Shadow shaders

This commit is contained in:
Dzmitry Malyshau 2019-02-22 12:59:05 -05:00
parent 056cc64eb4
commit 7386a05a0d
6 changed files with 66 additions and 18 deletions

View File

@ -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"]

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
}

View File

@ -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");
}
}

View File

@ -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,