Jump to content

Getting a Depth Texture


HugoMcPhee
 Share

Recommended Posts

Hi I've been trying to get a greyscale texture of the depth buffer to be able to use it to create a "depth of field" post process, however I can't figure out the best way to go about it.

The result i'm after is like this z-buffer2.jpg

 

To my understanding it seems a material has to be made with a custom vertex and fragment shader that converts (and linearises) values from gl_FragCoord.z into values in gl_FragColor, and this has to be done outside of creating a post process because post processes can't use vertex shaders. I'm wondering if there is a simple way to achieve this in babylon.js or if anyone has got it working so far?

Any help or hints in the right direction would be greatly appreciated

Link to comment
Share on other sites

I suggest using custom render targets.

 

First you have to create a RenderTargetTexture

Then add it to scene.customRenderTargets. This way the scene will be first rendered into your texture

Then create a material that output gl_FragCoord.z into gl_FragColor

Finally you can use RenderTargetTexture.onBeforeRender callback to affect your material to meshes and use RenderTargetTexture.onAfterRender callback to restore materials back

 

Does it make sense?

Link to comment
Share on other sites

Thankyou! that worked perfectly here's my result

166yalu.jpg

 

The javascript code: 

var originalMaterials = [];newScene.meshes.forEach(function(m) {        //if (predicate(m)) {            originalMaterials.push(m.material);        //}    });var depthMaterial = new BABYLON.ShaderMaterial("depthShader", newScene, "./depth",{    attributes: ["position", "uv"],    uniforms: ["worldViewProjection"]});var depthTextureRTT = new BABYLON.RenderTargetTexture("depthRTT", 512, newScene);newScene.customRenderTargets.push(depthTextureRTT)depthTextureRTT.onBeforeRender = function() {    newScene.meshes.forEach(function(m) {            // This is where the new screenshot is from            m.material = depthMaterial;    });};depthTextureRTT.onAfterRender = function() {    newScene.meshes.forEach(function(m,i) {            // I commented out this part to get the screenshot            m.material = originalMaterials[i];    });}; 

The fragment shader "depth.fragment.fx" (with help taken from this page http://www.ozone3d.net/tutorials/glsl_fog/p04.php?lang=1 ):

#ifdef GL_ESprecision mediump float;precision mediump int;#endif        // Refs        uniform sampler2D textureSampler; void main() {    float z = 1.0 - (gl_FragCoord.z / gl_FragCoord.w) / 40.0;    gl_FragColor = vec4(z, z, z, 1.0);}

and the vertex shader "depth.vertex.fx":

#ifdef GL_ES        precision mediump float;#endif    // Attributes    attribute vec3 position;    attribute vec2 uv;    uniform mat4 worldViewProjection;void main(void) {    vec4 outPosition = worldViewProjection * vec4(position, 1.0);	gl_Position = outPosition;}
Link to comment
Share on other sites

here is the code just for you:

http://www.babylonjs.com/?CUSTOMRENDERTARGET

var CreateCustomRenderTargetTestScene = function (engine) {    var scene = new BABYLON.Scene(engine);    var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene);    var material = new BABYLON.StandardMaterial("kosh", scene);    var sphere1 = BABYLON.Mesh.CreateSphere("Sphere1", 32, 3, scene);    var sphere2 = BABYLON.Mesh.CreateSphere("Sphere2", 32, 3, scene);    var sphere3 = BABYLON.Mesh.CreateSphere("Sphere3", 32, 3, scene);    var sphere4 = BABYLON.Mesh.CreateSphere("Sphere4", 32, 3, scene);    var light = new BABYLON.PointLight("Omni0", new BABYLON.Vector3(-17.6, 18.8, -49.9), scene);    camera.setPosition(new BABYLON.Vector3(-15, 3, 0));    camera.minZ = 1.0;    camera.maxZ = 100.0;    engine.displayLoadingUI();    sphere1.position.x -= 5;    sphere2.position.z -= 5;    sphere3.position.z += 5;    sphere4.position.x += 5;    material.diffuseColor = BABYLON.Color3.Purple();    sphere1.material = material;    sphere2.material = material;    sphere3.material = material;    sphere4.material = material;    // Skybox    var skybox = BABYLON.Mesh.CreateBox("skyBox", 100.0, scene);    var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);    skyboxMaterial.backFaceCulling = false;    skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("Scenes/Customs/skybox/TropicalSunnyDay", scene);    skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;    skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);    skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);    skybox.material = skyboxMaterial;    // depth material    BABYLON.Effect.ShadersStore["depthVertexShader"] =         "#ifdef GL_ES\n" +        "precision mediump float;\n" +        "#endif\n" +        "attribute vec3 position;\n" +        "uniform mat4 worldViewProjection;\n" +        "void main(void) {\n" +        "gl_Position = worldViewProjection * vec4(position, 1.0);\n" +        "}";    BABYLON.Effect.ShadersStore["depthPixelShader"] =        "#ifdef GL_ES\n" +        "precision mediump float;\n" +        "#endif\n" +        "void main(void) {\n" +        "float depth =  1.0 - (2.0 / (100.0 + 1.0 - gl_FragCoord.z * (100.0 - 1.0)));\n" +        "gl_FragColor = vec4(depth, depth, depth, 1.0);\n" +        "}\n" +        "";    var depthMaterial = new BABYLON.ShaderMaterial("depth", scene, "depth",        {            attributes: ["position"],            uniforms: ["worldViewProjection"]        });    depthMaterial.backFaceCulling = false;    // Plane    var plane = BABYLON.Mesh.CreatePlane("map", 10, scene);    plane.billboardMode = BABYLON.AbstractMesh.BILLBOARDMODE_ALL;    // Render target    var renderTarget = new BABYLON.RenderTargetTexture("depth", 1024, scene);    renderTarget.renderList.push(sphere1, sphere2, sphere3, sphere4, skybox);    scene.customRenderTargets.push(renderTarget);    renderTarget.onBeforeRender = function () {        for (var index = 0; index < renderTarget.renderList.length; index++) {            renderTarget.renderList[index]._savedMaterial = renderTarget.renderList[index].material;            renderTarget.renderList[index].material = depthMaterial;        }    }    renderTarget.onAfterRender = function () {        // Restoring previoux material        for (var index = 0; index < renderTarget.renderList.length; index++) {            renderTarget.renderList[index].material = renderTarget.renderList[index]._savedMaterial;        }    }    // Plane material    var mat = new BABYLON.StandardMaterial("plan mat", scene);    mat.diffuseColor = BABYLON.Color3.Black();    mat.specularColor = BABYLON.Color3.Black();    mat.emissiveTexture = renderTarget;    plane.material = mat;    // Animations    var isReady = false;    scene.registerBeforeRender(function () {        camera.alpha += 0.01 * scene.getAnimationRatio();        if (!isReady && scene.isReady()) {            isReady = true;            engine.hideLoadingUI();        }    });    return scene;};
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...