Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGL Depth Texture Extension #8577

Merged
merged 16 commits into from Apr 9, 2016
Merged

WebGL Depth Texture Extension #8577

merged 16 commits into from Apr 9, 2016

Conversation

@mattdesl
Copy link
Contributor

@mattdesl mattdesl commented Apr 8, 2016

This adds a depthTexture parameter for RenderTargets which allows them to render to a depth texture instead of using a depth renderbuffer.

var target = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight );
target.texture.format = THREE.RGBFormat;
target.texture.minFilter = THREE.NearestFilter;
target.texture.magFilter = THREE.NearestFilter;
target.texture.generateMipmaps = false;
target.stencilBuffer = false;
target.depthTexture = new THREE.DepthTexture();

The WEBGL_depth_texture extension is supported in Chrome/FF and some other environments, and is part of core in WebGL2.

Notes:

  • New texture format added: THREE.DepthFormat
  • Depth textures use unsigned short - and WebGL2 contexts must pass a signed internalFormat parameter to gl.texImage2D
  • WebGL2 supports THREE.FloatType for the depth texture
  • I decided to use a new class, THREE.DepthTexture. Although a regular THREE.Texture could have been used for this implementation, the user might not know to change the type to unsigned short.
  • If depthTexture is present, then depthBuffer will be ignored
  • depthTexture is not supported with cube render targets

This doesn't implement depth textures for shadow mapping. Once that comes in, it should provide a nice performance boost compared to the packing/unpacking we have now.

@mattdesl
Copy link
Contributor Author

@mattdesl mattdesl commented Apr 8, 2016

Here is a quick demo that just renders the depth to the screen. I've been using this extension in my WebGL2 application for fog and SSAO post-processing effects.

http://ci.threejs.org/api/pullrequests/8577/examples/webgl_depth_texture.html

screen shot 2016-04-08 at 10 07 17 am

It looks like this doesn't work on Safari yet. Will investigate.

Loading

@mattdesl
Copy link
Contributor Author

@mattdesl mattdesl commented Apr 8, 2016

Ok, works in OSX and iOS Safari now, too.

Loading


void main() {
vec3 diffuse = texture2D(tDiffuse, vUv).rgb;
float depth = readDepth(tDepth, vUv);
Copy link
Contributor

@bhouston bhouston Apr 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the custom readDepth function and instead use this:

#include <packing>
...
float depth = invClipZToViewZ( texture2D( depthSampler, coord ).x, cameraNear, cameraFar );
float linearClipZ = viewZToLinearClipZ( depth, cameraNear, cameraFar );

gl_FragColor.rgb = vec3( linearClipZ );

This will reconstruct the true z depth value in eye space using standardized functions.

Loading

Copy link
Owner

@mrdoob mrdoob Apr 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Loading

Copy link
Contributor Author

@mattdesl mattdesl Apr 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get a black screen with no errors when switching to this code. Ideas?

Loading

@bhouston
Copy link
Contributor

@bhouston bhouston commented Apr 8, 2016

This is so awesome. I was just working in this area with this PR:

#8573

I am not sure if depth textures can speed up shadowmaps much, and they are only by default 16bit in WebGL 1 rather than 32bit of precision. So my feeling is we should stick with RGBA packed for shadowmaps.

I do suggest trying to use the functions in packed for decoding the depth buffers values, there is one for orthogonal cameras (linearClipZToViewZ) and one for perspective cameras (invClipZToViewZ.)

I'm moving on to SAO/SSAO stuff now, and this extension is amazingly useful for speed purposes.

Loading

@@ -29,6 +29,7 @@ THREE.WebGLRenderTarget = function ( width, height, options ) {

this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
this.depthTexture = undefined;
Copy link
Owner

@mrdoob mrdoob Apr 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would set it to null instead.

Loading

@kintel
Copy link
Contributor

@kintel kintel commented Apr 9, 2016

@mattdesl Did you look at #5402 ? I'm interested in moving forward with either approach - just got a bit stalled as I'm not currently needing this feature..

Loading

@mrdoob
Copy link
Owner

@mrdoob mrdoob commented Apr 9, 2016

Merging this by now. Hopefully @bhouston can take a look at why invClipZToViewZ isn't woking.

Loading

@mrdoob mrdoob merged commit e77697f into mrdoob:dev Apr 9, 2016
@mrdoob
Copy link
Owner

@mrdoob mrdoob commented Apr 9, 2016

Many thanks!

Loading

@MasterJames
Copy link
Contributor

@MasterJames MasterJames commented Apr 10, 2016

Example renders all black on android chrome v 49.0.2623 galaxy tab 3 while Firefox works fine.

Loading

@bhouston
Copy link
Contributor

@bhouston bhouston commented Apr 10, 2016

Loading

@MasterJames
Copy link
Contributor

@MasterJames MasterJames commented Apr 10, 2016

I seem to have to rerun adb kill-server and adb start-server for chrome://inspect to detect my device with is actually a Gallaxy Note 3.

THREE.WebGLRenderer 76dev
three.js:28971 THREE.WebGLRenderer: OES_texture_float_linear extension not supported.
three.js:31660 WebGL: INVALID_VALUE: texImage2D: invalid internalformat
three.js:25244 WebGL: INVALID_FRAMEBUFFER_OPERATION: clear: the internalformat of the attached image is not depth-renderable
31three.js:28805 WebGL: INVALID_FRAMEBUFFER_OPERATION: drawArrays: the internalformat of the attached image is not depth-renderable
three.js:25244 WebGL: INVALID_FRAMEBUFFER_OPERATION: clear: the internalformat of the attached image is not depth-renderable
31three.js:28805 WebGL: INVALID_FRAMEBUFFER_OPERATION: drawArrays: the internalformat of the attached image is not depth-renderable
three.js:25244 WebGL: INVALID_FRAMEBUFFER_OPERATION: clear: the internalformat of the attached image is not depth-renderable
31three.js:28805 WebGL: INVALID_FRAMEBUFFER_OPERATION: drawArrays: the internalformat of the attached image is not depth-renderable
2webgl_depth_texture.html:1 [.CommandBufferContext]RENDER WARNING: texture bound to texture unit 1 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
three.js:25244 WebGL: INVALID_FRAMEBUFFER_OPERATION: clear: the internalformat of the attached image is not depth-renderable
31three.js:28805 WebGL: INVALID_FRAMEBUFFER_OPERATION: drawArrays: the internalformat of the attached image is not depth-renderable
2webgl_depth_texture.html:1 [.CommandBufferContext]RENDER WARNING: texture bound to texture unit 1 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
three.js:25244 WebGL: INVALID_FRAMEBUFFER_OPERATION: clear: the internalformat of the attached image is not depth-renderable
31three.js:28805 WebGL: INVALID_FRAMEBUFFER_OPERATION: drawArrays: the internalformat of the attached image is not depth-renderable
three.js:25244 WebGL: INVALID_FRAMEBUFFER_OPERATION: clear: the internalformat of the attached image is not depth-renderable
31three.js:28805 WebGL: INVALID_FRAMEBUFFER_OPERATION: drawArrays: the internalformat of the attached image is not depth-renderable
webgl_depth_texture.html:1 [.CommandBufferContext]RENDER WARNING: texture bound to texture unit 1 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
three.js:25244 WebGL: INVALID_FRAMEBUFFER_OPERATION: clear: the internalformat of the attached image is not depth-renderable
31three.js:28805 WebGL: INVALID_FRAMEBUFFER_OPERATION: drawArrays: the internalformat of the attached image is not depth-renderable
webgl_depth_texture.html:1 [.CommandBufferContext]RENDER WARNING: texture bound to texture unit 1 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
three.js:25244 WebGL: INVALID_FRAMEBUFFER_OPERATION: clear: the internalformat of the attached image is not depth-renderable
24three.js:28805 WebGL: INVALID_FRAMEBUFFER_OPERATION: drawArrays: the internalformat of the attached image is not depth-renderable
three.js:28805 WebGL: too many errors, no more errors will be reported to the console for this context.

Loading

@MasterJames
Copy link
Contributor

@MasterJames MasterJames commented Apr 10, 2016

I've only recently for the spotlights been digging into GL error detection, shows the typical #s.
renderer.getContext().getError()
1281
renderer.getContext().getError()
1286

I've noted trying to popup alerts() leads to the GUI missing mouse up events if related to events triggered from that (like exceeding map size limits), maybe the dat.GUI stuff should only be responding to mouseUp events to avoid that?

I guess maybe this phone is no longer representational of the average phones ability? :(

Is there another way to check the extensions?

Loading

@kintel
Copy link
Contributor

@kintel kintel commented Apr 11, 2016

It looks like this breaks stencil buffers; rendering to depth textures requires stencil buffers to have a compatible format, if that's enabled (using a DEPTH_STENCIL_ATTACHMENT).
See my code from #5402 which sets this up correctly: https://github.com/mrdoob/three.js/pull/5402/files#diff-c0e88b98497597a015ecf238e91ac3a0R3300

Using stencil buffers might not be the most common operation for a rendering framework, but for my use-case (CSG rendering), that was a key requirement when I first implemented depth texture support.

Loading

@bhouston
Copy link
Contributor

@bhouston bhouston commented Apr 11, 2016

I've just created two issues so we can track the errors reported by @kintel and @MasterJames in this thread. And @MasterJames I suspect that you are seeing a real error and one that we need to fix.

Loading

@MasterJames
Copy link
Contributor

@MasterJames MasterJames commented Apr 11, 2016

Yes it's solid black on my mobile device with chrome but Firefox works.

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

5 participants