struct VertexOutput { @location(0) world_space_position: vec4, @builtin(position) position: vec4, } struct Uniforms { camera_to_world_matrix: mat4x4, world_to_ndc_matrix: mat4x4, camera_position: vec4, dem_min_corner: vec2, dem_cell_size: vec2, dem_z_range: vec2 } @group(0) @binding(0) var uniforms: Uniforms; @group(0) @binding(1) var dem_texture: texture_2d; @group(0) @binding(2) var dembvh_texture: texture_2d; //#include ray_intersection.wgsl @vertex fn vs_main( @location(0) position: vec4, ) -> VertexOutput { var result: VertexOutput; result.position = uniforms.world_to_ndc_matrix * position; result.world_space_position = position; return result; } @fragment fn fs_solid(vertex: VertexOutput) -> @location(0) vec4 { var ray: Ray; ray.origin = vertex.world_space_position.xyz; ray.direction = normalize(vertex.world_space_position.xyz - uniforms.camera_position.xyz); var root_node: BoundingNode; root_node.index = vec2(0); root_node.level = textureNumLevels(dembvh_texture) - 1; var hit_index = vec2(0); if intersect_ray_with_node(dembvh_texture, uniforms.dem_min_corner, uniforms.dem_cell_size, uniforms.dem_z_range, ray, root_node, &hit_index) { //Calculate x-values of cell corners let v00 = textureLoad(dem_texture, hit_index, 0).r; let v01 = textureLoad(dem_texture, hit_index + vec2(0,1), 0).r; let v10 = textureLoad(dem_texture, hit_index + vec2(1,0), 0).r; let v11 = textureLoad(dem_texture, hit_index + vec2(1,1), 0).r; let z00 = 12.0 * f32(v00) / 65535.0; let z01 = 12.0 * f32(v01) / 65535.0; let z10 = 12.0 * f32(v10) / 65535.0; let z11 = 12.0 * f32(v11) / 65535.0; // Calculate xyz of cell corners let xy00 = uniforms.dem_min_corner.xy + uniforms.dem_cell_size * vec2(hit_index); let p00 = vec3(xy00, z00); let p01 = vec3(xy00 + vec2(0, 1), z01); let p10 = vec3(xy00 + vec2(1, 0), z10); let p11 = vec3(xy00 + vec2(1, 1), z11); // Intersect ray with the plane of each triangle and then take the // point that's inside it's triangle. // p is the point and p0, p1 and p2 are the triangle corners. let p_t0 = intersect_ray_with_triangle_plane(ray, p00, p01, p11); let p_t1 = intersect_ray_with_triangle_plane(ray, p00, p10, p11); let point_is_in_first_triangle = point_is_in_triangle(p_t0, p00, p01, p11); let p = select(p_t1, p_t0, point_is_in_first_triangle); let p0 = p00; let p1 = select(p10, p01, point_is_in_first_triangle); let p2 = p11; // Estimate normal as cross product of triangle for now var normal = normalize(cross(p1-p0, p2-p0)); normal *= sign(normal.z); //Ensure normal points up // Calculate light let sun_direction = (uniforms.camera_to_world_matrix * vec4(normalize(vec3(1.0, 1.0, 1.0)), 0.0)).xyz; let l = dot(normal, sun_direction); return vec4(l, l, l, 1.0); //return vec4(normal.xy, 0.0, 1.0); } else { discard; } }