Skip to content

Commit 4df9898

Browse files
gkjohnsonmrdoob
andauthored
Examples: Adjust volume instances demo to write to depth (#30464)
* Calculate screen coordinates * Get depth working * Remove unused variables * code style * Update depth assignment * variable name updates * Fix depth calculation * Update screenshot * Updated screenshot with a CI generated one. * Revert "Updated screenshot with a CI generated one." This reverts commit a4b7498. * Puppeteer: Added webgl_volume_instancing to exceptionList. --------- Co-authored-by: Mr.doob <[email protected]>
1 parent 4e629c8 commit 4df9898

File tree

3 files changed

+45
-13
lines changed

3 files changed

+45
-13
lines changed
145 KB
Loading

examples/webgl_volume_instancing.html

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,28 +61,28 @@
6161
uniform mat4 projectionMatrix;
6262
uniform vec3 cameraPos;
6363
64-
out vec3 vOrigin;
65-
out vec3 vDirection;
64+
out vec4 vScreenPosition;
65+
out mat4 vInstanceToViewMatrix;
6666
6767
void main() {
6868
vec4 mvPosition = modelViewMatrix * instanceMatrix * vec4( position, 1.0 );
6969
70-
vOrigin = vec3( inverse( instanceMatrix * modelMatrix ) * vec4( cameraPos, 1.0 ) ).xyz;
71-
vDirection = position - vOrigin;
72-
7370
gl_Position = projectionMatrix * mvPosition;
71+
vScreenPosition = vec4( gl_Position.xy, 0.0, gl_Position.w );
72+
vInstanceToViewMatrix = modelViewMatrix * instanceMatrix;
7473
}
7574
`;
7675

7776
const fragmentShader = /* glsl */`
7877
precision highp float;
7978
precision highp sampler3D;
8079
80+
uniform mat4 viewMatrix;
8181
uniform mat4 modelViewMatrix;
8282
uniform mat4 projectionMatrix;
8383
84-
in vec3 vOrigin;
85-
in vec3 vDirection;
84+
in vec4 vScreenPosition;
85+
in mat4 vInstanceToViewMatrix;
8686
8787
out vec4 color;
8888
@@ -126,20 +126,41 @@
126126
return normalize( vec3( x, y, z ) );
127127
}
128128
129-
void main(){
129+
void main() {
130130
131-
vec3 rayDir = normalize( vDirection );
132-
vec2 bounds = hitBox( vOrigin, rayDir );
131+
// perform w divide in the fragment shader to avoid interpolation artifacts
132+
vec2 screenUv = vScreenPosition.xy / vScreenPosition.w;
133+
mat4 invProjectionMatrix = inverse( projectionMatrix );
134+
mat4 invInstanceToViewMatrix = inverse( vInstanceToViewMatrix );
135+
136+
// get camera ray
137+
vec4 temp;
138+
vec3 camRayOrigin, camRayEnd;
139+
temp = invProjectionMatrix * vec4( screenUv, - 1.0, 1.0 );
140+
camRayOrigin = temp.xyz / temp.w;
141+
142+
temp = invProjectionMatrix * vec4( screenUv, 1.0, 1.0 );
143+
camRayEnd = temp.xyz / temp.w;
144+
145+
// get local ray
146+
vec3 instRayOrigin, instRayDirection, instRayEnd;
147+
instRayOrigin = ( invInstanceToViewMatrix * vec4( camRayOrigin, 1.0 ) ).xyz;
148+
instRayEnd = ( invInstanceToViewMatrix * vec4( camRayEnd, 1.0 ) ).xyz;
149+
instRayDirection = normalize( instRayEnd - instRayOrigin );
150+
151+
// calculate the start of the ray at the box edge
152+
vec2 bounds = hitBox( instRayOrigin, instRayDirection );
133153
134154
if ( bounds.x > bounds.y ) discard;
135155
136156
bounds.x = max( bounds.x, 0.0 );
137157
138-
vec3 p = vOrigin + bounds.x * rayDir;
139-
vec3 inc = 1.0 / abs( rayDir );
158+
vec3 p = instRayOrigin + bounds.x * instRayDirection;
159+
vec3 inc = 1.0 / abs( instRayDirection );
140160
float delta = min( inc.x, min( inc.y, inc.z ) );
141161
delta /= 50.0;
142162
163+
// march through the volume
143164
for ( float t = bounds.x; t < bounds.y; t += delta ) {
144165
145166
float d = sample1( p + 0.5 );
@@ -152,12 +173,22 @@
152173
153174
}
154175
155-
p += rayDir * delta;
176+
p += instRayDirection * delta;
156177
157178
}
158179
159180
if ( color.a == 0.0 ) discard;
160181
182+
// calculate the final point in the ndc coords
183+
vec4 ndc = projectionMatrix * vInstanceToViewMatrix * vec4( p, 1.0 );
184+
ndc /= ndc.w;
185+
186+
// map the ndc coordinate to depth
187+
// https://stackoverflow.com/questions/10264949/glsl-gl-fragcoord-z-calculation-and-setting-gl-fragdepth
188+
float far = gl_DepthRange.far;
189+
float near = gl_DepthRange.near;
190+
gl_FragDepth = ( ( ( far - near ) * ndc.z ) + near + far ) / 2.0;
191+
161192
}
162193
`;
163194

test/e2e/puppeteer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ const exceptionList = [
105105
'webgl_points_dynamic',
106106
'webgpu_multisampled_renderbuffers',
107107
'webgl_test_wide_gamut',
108+
'webgl_volume_instancing',
108109

109110
// TODO: implement determinism for setTimeout and setInterval
110111
// could it fix some examples from above?

0 commit comments

Comments
 (0)