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

Conversation

@mattdesl
Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor Author

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.

@mattdesl

This comment has been minimized.

Copy link
Contributor Author

commented Apr 8, 2016

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

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

This comment has been minimized.

Copy link
@bhouston

bhouston Apr 8, 2016

Contributor

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.

This comment has been minimized.

Copy link
@mrdoob

This comment has been minimized.

Copy link
@mattdesl

mattdesl Apr 9, 2016

Author Contributor

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

@bhouston

This comment has been minimized.

Copy link
Contributor

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.

@@ -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;

This comment has been minimized.

Copy link
@mrdoob

mrdoob Apr 9, 2016

Owner

I would set it to null instead.

@kintel

This comment has been minimized.

Copy link
Contributor

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..

@mrdoob

This comment has been minimized.

Copy link
Owner

commented Apr 9, 2016

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

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

@mrdoob

This comment has been minimized.

Copy link
Owner

commented Apr 9, 2016

Many thanks!

@MasterJames

This comment has been minimized.

Copy link
Contributor

commented Apr 10, 2016

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

@bhouston

This comment has been minimized.

Copy link
Contributor

commented Apr 10, 2016

@MasterJames

This comment has been minimized.

Copy link
Contributor

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.
@MasterJames

This comment has been minimized.

Copy link
Contributor

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?

@kintel

This comment has been minimized.

Copy link
Contributor

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.

@bhouston

This comment has been minimized.

Copy link
Contributor

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.

@MasterJames

This comment has been minimized.

Copy link
Contributor

commented Apr 11, 2016

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.