mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
Shadow shaders
This commit is contained in:
parent
056cc64eb4
commit
7386a05a0d
@ -12,8 +12,13 @@ publish = false
|
||||
name = "cube"
|
||||
path = "src/cube.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "shadow"
|
||||
path = "src/shadow.rs"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
metal-auto-capture = ["wgpu/metal-auto-capture"]
|
||||
metal = ["wgpu/metal"]
|
||||
dx11 = ["wgpu/dx11"]
|
||||
dx12 = ["wgpu/dx12"]
|
||||
|
@ -1,10 +1,55 @@
|
||||
#version 450
|
||||
|
||||
const int MAX_LIGHTS = 10;
|
||||
|
||||
layout(location = 0) in vec3 v_Normal;
|
||||
layout(location = 1) in vec4 v_Position;
|
||||
|
||||
layout(location = 0) out vec4 o_Target;
|
||||
|
||||
layout(set = 0, binding = 2) uniform texture2D u_ShadowTexture;
|
||||
layout(set = 0, binding = 3) uniform sampler u_ShadowSampler;
|
||||
struct Light {
|
||||
mat4 proj;
|
||||
vec4 pos;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 0) uniform Globals {
|
||||
mat4 u_ViewProj;
|
||||
uvec4 u_NumLights;
|
||||
};
|
||||
layout(set = 0, binding = 1) uniform Lights {
|
||||
Light u_Lights[MAX_LIGHTS];
|
||||
};
|
||||
layout(set = 0, binding = 2) uniform texture2DArray t_Shadow;
|
||||
layout(set = 0, binding = 3) uniform samplerShadow s_Shadow;
|
||||
|
||||
layout(set = 1, binding = 0) uniform Entity {
|
||||
mat4 u_World;
|
||||
vec4 u_Color;
|
||||
};
|
||||
|
||||
|
||||
void main() {
|
||||
o_Target = vec4(1.0);
|
||||
vec3 normal = normalize(v_Normal);
|
||||
vec3 ambient = vec3(0.05, 0.05, 0.05);
|
||||
// accumulate color
|
||||
vec3 color = ambient;
|
||||
for (int i=0; i<int(u_NumLights.x) && i<MAX_LIGHTS; ++i) {
|
||||
Light light = u_Lights[i];
|
||||
// project into the light space
|
||||
vec4 light_local = light.proj * v_Position;
|
||||
// compute texture coordinates for shadow lookup
|
||||
light_local.y *= -1.0; // difference in Vulkan target versus texture coordinates...
|
||||
light_local.xyw = (light_local.xyz/light_local.w + 1.0) / 2.0;
|
||||
light_local.z = i;
|
||||
// do the lookup, using HW PCF and comparison
|
||||
float shadow = texture(sampler2DArrayShadow(t_Shadow, s_Shadow), light_local);
|
||||
// compute Lambertian diffuse term
|
||||
vec3 light_dir = normalize(light.pos.xyz - v_Position.xyz);
|
||||
float diffuse = max(0.0, dot(normal, light_dir));
|
||||
// add light contribution
|
||||
color += shadow * diffuse * light.color.xyz;
|
||||
}
|
||||
// multiply the light by material color
|
||||
o_Target = vec4(color, 1.0) * u_Color;
|
||||
}
|
||||
|
@ -3,23 +3,20 @@
|
||||
layout(location = 0) in ivec4 a_Pos;
|
||||
layout(location = 1) in ivec4 a_Normal;
|
||||
|
||||
struct Light {
|
||||
mat4 proj;
|
||||
vec4 color;
|
||||
};
|
||||
layout(location = 0) out vec3 v_Normal;
|
||||
layout(location = 1) out vec4 v_Position;
|
||||
|
||||
layout(set = 0, binding = 0) uniform Globals {
|
||||
mat4 u_ViewProj;
|
||||
uvec4 u_NumLights;
|
||||
};
|
||||
layout(set = 0, binding = 1) uniform Lights {
|
||||
Light u_Lights[];
|
||||
};
|
||||
layout(set = 1, binding = 0) uniform Entity {
|
||||
mat4 u_World;
|
||||
vec4 u_Color;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = u_ViewProj * u_World * vec4(a_Pos);
|
||||
v_Normal = mat3(u_World) * vec3(a_Normal.xyz);
|
||||
v_Position = u_World * vec4(a_Pos);
|
||||
gl_Position = u_ViewProj * v_Position;
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ impl Example {
|
||||
let mx_view = cgmath::Matrix4::look_at(
|
||||
cgmath::Point3::new(1.5f32, -5.0, 3.0),
|
||||
cgmath::Point3::new(0f32, 0.0, 0.0),
|
||||
cgmath::Vector3::unit_z(),
|
||||
-cgmath::Vector3::unit_z(),
|
||||
);
|
||||
mx_projection * mx_view
|
||||
}
|
||||
|
@ -123,5 +123,6 @@ pub fn run<E: Example>(title: &str) {
|
||||
|
||||
let frame = swap_chain.get_next_texture();
|
||||
example.render(&frame, &mut device);
|
||||
running &= !cfg!(feature = "metal-auto-capture");
|
||||
}
|
||||
}
|
||||
|
@ -172,11 +172,11 @@ impl Example {
|
||||
};
|
||||
|
||||
fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4<f32> {
|
||||
let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 10.0);
|
||||
let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 20.0);
|
||||
let mx_view = cgmath::Matrix4::look_at(
|
||||
cgmath::Point3::new(1.5f32, -5.0, 3.0),
|
||||
cgmath::Point3::new(3.0f32, -10.0, 6.0),
|
||||
cgmath::Point3::new(0f32, 0.0, 0.0),
|
||||
cgmath::Vector3::unit_z(),
|
||||
-cgmath::Vector3::unit_z(),
|
||||
);
|
||||
mx_projection * mx_view
|
||||
}
|
||||
@ -219,7 +219,7 @@ impl framework::Example for Example {
|
||||
bindings: &[
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStageFlags::VERTEX,
|
||||
visibility: wgpu::ShaderStageFlags::VERTEX | wgpu::ShaderStageFlags::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer,
|
||||
},
|
||||
],
|
||||
@ -447,8 +447,8 @@ impl framework::Example for Example {
|
||||
rasterization_state: wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Cw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias: 2,
|
||||
depth_bias_slope_scale: 1.0,
|
||||
depth_bias_clamp: wgpu::MAX_DEPTH_BIAS_CLAMP,
|
||||
},
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
|
Loading…
Reference in New Issue
Block a user