Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 29 additions & 44 deletions examples/jsm/shaders/VolumeShader.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,23 @@ const VolumeRenderShader1 = {

vertexShader: /* glsl */`

varying vec4 v_nearpos;
varying vec4 v_farpos;
varying vec3 v_position;
varying vec3 v_cameraInObj;
varying vec3 v_viewDirInObj;

void main() {
// Prepare transforms to map to "camera view". See also:
// https://threejs.org/docs/#api/renderers/webgl/WebGLProgram
mat4 viewtransformf = modelViewMatrix;
mat4 viewtransformi = inverse(modelViewMatrix);

// Project local vertex coordinate to camera position. Then do a step
// backward (in cam coords) to the near clipping plane, and project back. Do
// the same for the far clipping plane. This gives us all the information we
// need to calculate the ray and truncate it to the viewing cone.
vec4 position4 = vec4(position, 1.0);
vec4 pos_in_cam = viewtransformf * position4;

// Intersection of ray and near clipping plane (z = -1 in clip coords)
pos_in_cam.z = -pos_in_cam.w;
v_nearpos = viewtransformi * pos_in_cam;
v_position = position;

// Intersection of ray and far clipping plane (z = +1 in clip coords)
pos_in_cam.z = pos_in_cam.w;
v_farpos = viewtransformi * pos_in_cam;
// Express the camera position and view direction in the object's local
// space so the fragment shader can build the per-fragment view ray.
// For perspective cameras, rays converge at v_cameraInObj.
// For orthographic cameras, rays travel along v_viewDirInObj.
v_cameraInObj = (inverse(modelMatrix) * vec4(cameraPosition, 1.0)).xyz;
v_viewDirInObj = (inverse(modelViewMatrix) * vec4(0.0, 0.0, -1.0, 0.0)).xyz;

// Set varyings and output pos
v_position = position;
gl_Position = projectionMatrix * viewMatrix * modelMatrix * position4;
gl_Position = projectionMatrix * modelViewMatrix * position4;
}`,

fragmentShader: /* glsl */`
Expand All @@ -75,8 +64,8 @@ const VolumeRenderShader1 = {
uniform sampler2D u_cmdata;

varying vec3 v_position;
varying vec4 v_nearpos;
varying vec4 v_farpos;
varying vec3 v_cameraInObj;
varying vec3 v_viewDirInObj;

// The maximum distance through our rendering volume is sqrt(3).
const int MAX_STEPS = 887; // 887 for 512^3, 1774 for 1024^3
Expand All @@ -96,33 +85,29 @@ const VolumeRenderShader1 = {


void main() {
// Normalize clipping plane info
vec3 farpos = v_farpos.xyz / v_farpos.w;
vec3 nearpos = v_nearpos.xyz / v_nearpos.w;

// Calculate unit vector pointing in the view direction through this fragment.
vec3 view_ray = normalize(nearpos.xyz - farpos.xyz);

// Compute the (negative) distance to the front surface or near clipping plane.
// v_position is the back face of the cuboid, so the initial distance calculated in the dot
// product below is the distance from near clip plane to the back of the cuboid
float distance = dot(nearpos - v_position, view_ray);
distance = max(distance, min((-0.5 - v_position.x) / view_ray.x,
(u_size.x - 0.5 - v_position.x) / view_ray.x));
distance = max(distance, min((-0.5 - v_position.y) / view_ray.y,
(u_size.y - 0.5 - v_position.y) / view_ray.y));
distance = max(distance, min((-0.5 - v_position.z) / view_ray.z,
(u_size.z - 0.5 - v_position.z) / view_ray.z));

// Now we have the starting position on the front surface
vec3 front = v_position + view_ray * distance;
// Per-fragment ray direction in object space, pointing from the back
// face toward the camera. For perspective cameras the rays converge
// at the camera position; for orthographic cameras they are parallel
// to the view direction.
vec3 view_ray = isOrthographic
? normalize(-v_viewDirInObj)
: normalize(v_cameraInObj - v_position);

// Slab-based ray/AABB intersection: v_position lies on the back face
// of the cuboid, so stepping along view_ray traverses the volume and
// exits through the front face at t = distance.
vec3 t1 = (vec3(-0.5) - v_position) / view_ray;
vec3 t2 = (u_size - vec3(0.5) - v_position) / view_ray;
vec3 tmax = max(t1, t2);
float distance = min(min(tmax.x, tmax.y), tmax.z);

// Decide how many steps to take
int nsteps = int(-distance / relative_step_size + 0.5);
int nsteps = int(distance / relative_step_size + 0.5);
if ( nsteps < 1 )
discard;

// Get starting location and step vector in texture coordinates
vec3 front = v_position + view_ray * distance;
vec3 step = ((v_position - front) / u_size) / float(nsteps);
vec3 start_loc = front / u_size;

Expand Down
2 changes: 1 addition & 1 deletion examples/webgl_texture3d.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

// Create camera (The volume renderer does not work very well with perspective yet)
// Create camera
const h = 512; // frustum height
const aspect = window.innerWidth / window.innerHeight;
camera = new THREE.OrthographicCamera( - h * aspect / 2, h * aspect / 2, h / 2, - h / 2, 1, 1000 );
Expand Down
4 changes: 2 additions & 2 deletions examples/webgpu_lines_fat.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
linewidth: 5, // in world units with size attenuation, pixels otherwise
vertexColors: true,
dashed: false,
alphaToCoverage: true,
alphaToCoverage: false,

} );

Expand Down Expand Up @@ -209,7 +209,7 @@
'line type': 0,
'world units': false,
'width': 5,
'alphaToCoverage': true,
'alphaToCoverage': false,
'dashed': false,
'dash offset': 0,
'dash scale': 1,
Expand Down
2 changes: 0 additions & 2 deletions examples/webgpu_lines_fat_wireframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@

// main scene

renderer.setClearColor( 0x000000, 0 );

renderer.setViewport( 0, 0, window.innerWidth, window.innerHeight );

renderer.autoClear = true;
Expand Down
Loading