Postprocessing with normal and depth information

Hello,

We are currently experimenting with Cesium's rendering capabilities and we are having a few problems.
We successfully integrated the postprocessing-hook branch to our project, but in order to make the most out of it, we need to gather additional information from the initial shader pass : normals, depth, etc. What would be the best way to transfer this information to the postprocessing shaders ?

Regards,

Jérémy Gaillard

Hi Jérémy,

Sounds interesting. What kind of project are you working on?

If you want depth for just the globe/terrain, check out czm_globeDepthTexture:

https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Renderer/AutomaticUniforms.js#L180

If you want the depth for the entire scene, you’ll have to change Cesium’s renderer (it will be similar to czm_globeDepthTexture). The initial work we did on shadows may be useful. You’ll want to take a similar approach with normals (I would use multiple render targets when available).

This will be a fair amount of work and you’ll have to handle Cesium’s use of multiple frustums. Eventually, depth and normal buffers will be part of Cesium, but if you want to go for it now, here’s a few resources:

Patrick

Thanks for the pointers.

If you want the depth for the entire scene, you'll have to change Cesium's renderer (it will be similar to czm_globeDepthTexture). The initial work we did on shadows may be useful. You'll want to take a similar approach with normals (I would use multiple render targets when available).

For ou purpose (first a "cell shader":https://en.wikipedia.org/wiki/Cel_shading and then ssao maybe) we need the depth and normals of the entire scene, not just the globe.

I was considering adding a loop for a least a second render pass just around the loop over frustrums in Scene.executeCommands and overriding the framebuffer of the draw commands to compute the necessary framebuffer. I would also need to override the appearances for the normal+depth render pass, but I don't see yet how to do that last bit cleanly.

Does that make sense for you ?

I see that the approach you took for shadow casting is different, but in our cases we don't need a second point of view on the scene.

(I would use multiple render targets when available)

That is another approach I was considering. If we could use 3 render targets, then no need to loop, we could use the normal+depth additional textures in the custom post-process as it stands and do what needs be done.

As a first step, for the cell-shading) only our 'special' appearance would need to know about the additional render targets. It would also be less intrusive and faster to implement I guess. All shader would write to gl_FragData[0] without even knowing that there are more RT to render to, until we want all primitives to write their depth an normals there.

Any thought on that ?

V.

Hi,

For SSAO, check out this (very old) branch:

https://github.com/AnalyticalGraphicsInc/cesium/blob/925037dfd6eba83437c10a23a82186f618e467d2/Source/Shaders/PostFX/AmbientOcclusion.glsl

I see that the approach you took for shadow casting is different, but in our cases we don’t need a second point of view on the scene.

This is the general-purpose approach we will take for shadow maps, environment maps, and laying out g-buffers when MRT is not supported. You are welcome to bend the renderer however you need in the meantime, but I just want to give you a heads up that merging in future versions of Cesium may be challenging as we update the renderer for shadows and WebGL 2.

Patrick

Necropost-
Trying to use czm_globeDepthTexture in a custom primitive, getting:

TypeError: Cannot read property '_target' of undefined
TypeError: Cannot read property '_target' of undefined
    at UniformSampler.set
    at ShaderProgram._setUniforms
    at continueDraw
    at Context.draw
    at DrawCommand.execute
    at executeCommand
    at executeTranslucentCommandsSortedMRT
    at OIT.executeCommands
    at scene._executeOITFunction
    at executeCommands

glsl:
    gl_FragColor.rgb= texture2D(czm_globeDepthTexture, vec2(0.,0.)).xxx;

Do you have support for depth textures? Check Context.depthTexture in Cesium or check for WEBGL_depth_texture at webglreport.com.

Also, to avoid haveing to also require floating point textures, the depth is packed into an RGBA texture. To get the floating point depth:

float depth = czm_unpackDepth(texture2D(czm_globeDepthTexture, textureCoordinates));

Report says I have support for depth textures, I'd hope as I've a GTX980.
Also the issue is not from being in the translucent pass, opaque pass is same result.

I just realized that the globed depth texture is disabled by default. It’ll be enabled by default in the future when we need it, for example GroundPrimitive texture coordinates. You can enable it with the scene.copyGlobeDepth = true.

Works C: