pteropus/src/app/dem_renderer/dem_renderer.wgsl

82 lines
2.8 KiB
WebGPU Shading Language

struct VertexOutput {
@location(0) world_space_position: vec4<f32>,
@builtin(position) position: vec4<f32>,
}
struct Uniforms {
camera_to_world_matrix: mat4x4<f32>,
world_to_ndc_matrix: mat4x4<f32>,
camera_position: vec4<f32>,
dem_min_corner: vec2<f32>,
dem_cell_size: vec2<f32>,
dem_z_range: vec2<f32>
}
@group(0) @binding(0)
var<uniform> uniforms: Uniforms;
@group(0) @binding(1)
var dem_texture: texture_2d<u32>;
@group(0) @binding(2)
var dembvh_texture: texture_2d<u32>;
//#include ray_intersection.wgsl
@vertex
fn vs_main(
@location(0) position: vec4<f32>,
) -> 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<f32> {
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<u32>(0);
root_node.level = textureNumLevels(dembvh_texture) - 1;
var hit_index = vec2<u32>(0);
var hit_location: vec3<f32>;
var hit_normal: vec3<f32>;
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<f32>(normalize(vec3<f32>(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<f32>;
var dummy1: vec3<f32>;
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<f32>(vec3<f32>(l)*shadow_value, 1.0);
} else {
discard;
}
}