HugoMcPhee Posted September 29, 2014 Share Posted September 29, 2014 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 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 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted September 29, 2014 Share Posted September 29, 2014 I suggest using custom render targets. First you have to create a RenderTargetTextureThen add it to scene.customRenderTargets. This way the scene will be first rendered into your textureThen create a material that output gl_FragCoord.z into gl_FragColorFinally 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? Quote Link to comment Share on other sites More sharing options...
HugoMcPhee Posted September 29, 2014 Author Share Posted September 29, 2014 Thankyou! that worked perfectly here's my result 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;} Temechon 1 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted September 29, 2014 Share Posted September 29, 2014 here is the code just for you:http://www.babylonjs.com/?CUSTOMRENDERTARGETvar 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;}; Quote Link to comment Share on other sites More sharing options...
HugoMcPhee Posted September 29, 2014 Author Share Posted September 29, 2014 Wow thanks heaps for making that example! GameMonetize 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.