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); var hit_location: vec3; var hit_normal: vec3; if intersect_ray_with_node(dembvh_texture, uniforms.dem_min_corner, uniforms.dem_cell_size, uniforms.dem_z_range, ray, root_node, &hit_index, &hit_location, &hit_normal) { // 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(hit_normal, sun_direction); var shadow_ray :Ray; shadow_ray.origin = hit_location + hit_normal * 0.1; shadow_ray.direction = sun_direction; var dummy0: vec3; var dummy1: vec3; let shadow_value = select(1.0, 0.0, intersect_ray_with_node(dembvh_texture, uniforms.dem_min_corner, uniforms.dem_cell_size, uniforms.dem_z_range, shadow_ray, root_node, &hit_index, &dummy0, &dummy1)); return vec4(vec3(l)*shadow_value, 1.0); } else { discard; } }