mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-25 08:14:12 +00:00
example-runner-ash: use NumPad +/- to control sky-shader
's "sun intensity" through a specialization constant.
This commit is contained in:
parent
af2a9ee445
commit
4c6cf0d737
@ -187,6 +187,19 @@ pub fn main() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some(key @ (VirtualKeyCode::NumpadAdd | VirtualKeyCode::NumpadSubtract)) => {
|
||||||
|
let factor =
|
||||||
|
&mut ctx.sky_fs_spec_id_0x5007_sun_intensity_extra_spec_const_factor;
|
||||||
|
*factor = if key == VirtualKeyCode::NumpadAdd {
|
||||||
|
factor.saturating_add(1)
|
||||||
|
} else {
|
||||||
|
factor.saturating_sub(1)
|
||||||
|
};
|
||||||
|
|
||||||
|
// HACK(eddyb) to see any changes, re-specializing the
|
||||||
|
// shader module is needed (e.g. during pipeline rebuild).
|
||||||
|
ctx.rebuild_pipelines(vk::PipelineCache::null());
|
||||||
|
}
|
||||||
_ => *control_flow = ControlFlow::Wait,
|
_ => *control_flow = ControlFlow::Wait,
|
||||||
},
|
},
|
||||||
WindowEvent::Resized(_) => {
|
WindowEvent::Resized(_) => {
|
||||||
@ -657,6 +670,9 @@ pub struct RenderCtx {
|
|||||||
pub rendering_paused: bool,
|
pub rendering_paused: bool,
|
||||||
pub recompiling_shaders: bool,
|
pub recompiling_shaders: bool,
|
||||||
pub start: std::time::Instant,
|
pub start: std::time::Instant,
|
||||||
|
|
||||||
|
// NOTE(eddyb) this acts like an integration test for specialization constants.
|
||||||
|
pub sky_fs_spec_id_0x5007_sun_intensity_extra_spec_const_factor: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderCtx {
|
impl RenderCtx {
|
||||||
@ -702,6 +718,8 @@ impl RenderCtx {
|
|||||||
rendering_paused: false,
|
rendering_paused: false,
|
||||||
recompiling_shaders: false,
|
recompiling_shaders: false,
|
||||||
start: std::time::Instant::now(),
|
start: std::time::Instant::now(),
|
||||||
|
|
||||||
|
sky_fs_spec_id_0x5007_sun_intensity_extra_spec_const_factor: 100,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -723,6 +741,18 @@ impl RenderCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn rebuild_pipelines(&mut self, pipeline_cache: vk::PipelineCache) {
|
pub fn rebuild_pipelines(&mut self, pipeline_cache: vk::PipelineCache) {
|
||||||
|
// NOTE(eddyb) this acts like an integration test for specialization constants.
|
||||||
|
let spec_const_entries = [vk::SpecializationMapEntry::builder()
|
||||||
|
.constant_id(0x5007)
|
||||||
|
.offset(0)
|
||||||
|
.size(4)
|
||||||
|
.build()];
|
||||||
|
let spec_const_data =
|
||||||
|
u32::to_le_bytes(self.sky_fs_spec_id_0x5007_sun_intensity_extra_spec_const_factor);
|
||||||
|
let specialization_info = vk::SpecializationInfo::builder()
|
||||||
|
.map_entries(&spec_const_entries)
|
||||||
|
.data(&spec_const_data);
|
||||||
|
|
||||||
self.cleanup_pipelines();
|
self.cleanup_pipelines();
|
||||||
let pipeline_layout = self.create_pipeline_layout();
|
let pipeline_layout = self.create_pipeline_layout();
|
||||||
let viewport = vk::PipelineViewportStateCreateInfo::builder()
|
let viewport = vk::PipelineViewportStateCreateInfo::builder()
|
||||||
@ -754,6 +784,7 @@ impl RenderCtx {
|
|||||||
module: *frag_module,
|
module: *frag_module,
|
||||||
p_name: (*frag_name).as_ptr(),
|
p_name: (*frag_name).as_ptr(),
|
||||||
stage: vk::ShaderStageFlags::FRAGMENT,
|
stage: vk::ShaderStageFlags::FRAGMENT,
|
||||||
|
p_specialization_info: &*specialization_info,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
]))
|
]))
|
||||||
|
@ -141,7 +141,7 @@ fn main() {
|
|||||||
* vec2(WIDTH as f32, HEIGHT as f32);
|
* vec2(WIDTH as f32, HEIGHT as f32);
|
||||||
|
|
||||||
// evaluate the fragment shader for the specific pixel
|
// evaluate the fragment shader for the specific pixel
|
||||||
let color = shader_module::fs(&push_constants, frag_coord);
|
let color = shader_module::fs(&push_constants, frag_coord, 1);
|
||||||
|
|
||||||
color_u32_from_vec4(color)
|
color_u32_from_vec4(color)
|
||||||
})
|
})
|
||||||
|
@ -71,7 +71,7 @@ fn sun_intensity(zenith_angle_cos: f32) -> f32 {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
|
fn sky(dir: Vec3, sun_position: Vec3, sun_intensity_extra_spec_const_factor: u32) -> Vec3 {
|
||||||
let up = vec3(0.0, 1.0, 0.0);
|
let up = vec3(0.0, 1.0, 0.0);
|
||||||
let sunfade = 1.0 - (1.0 - saturate(sun_position.y / 450000.0).exp());
|
let sunfade = 1.0 - (1.0 - saturate(sun_position.y / 450000.0).exp());
|
||||||
let rayleigh_coefficient = RAYLEIGH - (1.0 * (1.0 - sunfade));
|
let rayleigh_coefficient = RAYLEIGH - (1.0 * (1.0 - sunfade));
|
||||||
@ -96,7 +96,12 @@ fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
|
|||||||
let beta_r_theta = beta_r * rayleigh_phase(cos_theta * 0.5 + 0.5);
|
let beta_r_theta = beta_r * rayleigh_phase(cos_theta * 0.5 + 0.5);
|
||||||
|
|
||||||
let beta_m_theta = beta_m * henyey_greenstein_phase(cos_theta, MIE_DIRECTIONAL_G);
|
let beta_m_theta = beta_m * henyey_greenstein_phase(cos_theta, MIE_DIRECTIONAL_G);
|
||||||
let sun_e = sun_intensity(sun_direction.dot(up));
|
let sun_e = sun_intensity(sun_direction.dot(up))
|
||||||
|
|
||||||
|
// HACK(eddyb) this acts like an integration test for specialization constants,
|
||||||
|
// but the correct value is only obtained when this is a noop (multiplies by `1`).
|
||||||
|
* (sun_intensity_extra_spec_const_factor as f32 / 100.0);
|
||||||
|
|
||||||
let mut lin = pow(
|
let mut lin = pow(
|
||||||
sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * (Vec3::splat(1.0) - fex),
|
sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * (Vec3::splat(1.0) - fex),
|
||||||
1.5,
|
1.5,
|
||||||
@ -130,7 +135,11 @@ fn get_ray_dir(uv: Vec2, pos: Vec3, look_at_pos: Vec3) -> Vec3 {
|
|||||||
(forward + uv.x * right + uv.y * up).normalize()
|
(forward + uv.x * right + uv.y * up).normalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fs(constants: &ShaderConstants, frag_coord: Vec2) -> Vec4 {
|
pub fn fs(
|
||||||
|
constants: &ShaderConstants,
|
||||||
|
frag_coord: Vec2,
|
||||||
|
sun_intensity_extra_spec_const_factor: u32,
|
||||||
|
) -> Vec4 {
|
||||||
let mut uv = (frag_coord - 0.5 * vec2(constants.width as f32, constants.height as f32))
|
let mut uv = (frag_coord - 0.5 * vec2(constants.width as f32, constants.height as f32))
|
||||||
/ constants.height as f32;
|
/ constants.height as f32;
|
||||||
uv.y = -uv.y;
|
uv.y = -uv.y;
|
||||||
@ -141,7 +150,7 @@ pub fn fs(constants: &ShaderConstants, frag_coord: Vec2) -> Vec4 {
|
|||||||
let dir = get_ray_dir(uv, eye_pos, sun_pos);
|
let dir = get_ray_dir(uv, eye_pos, sun_pos);
|
||||||
|
|
||||||
// evaluate Preetham sky model
|
// evaluate Preetham sky model
|
||||||
let color = sky(dir, sun_pos);
|
let color = sky(dir, sun_pos, sun_intensity_extra_spec_const_factor);
|
||||||
|
|
||||||
// Tonemapping
|
// Tonemapping
|
||||||
let color = color.max(Vec3::splat(0.0)).min(Vec3::splat(1024.0));
|
let color = color.max(Vec3::splat(0.0)).min(Vec3::splat(1024.0));
|
||||||
@ -154,9 +163,12 @@ pub fn main_fs(
|
|||||||
#[spirv(frag_coord)] in_frag_coord: Vec4,
|
#[spirv(frag_coord)] in_frag_coord: Vec4,
|
||||||
#[spirv(push_constant)] constants: &ShaderConstants,
|
#[spirv(push_constant)] constants: &ShaderConstants,
|
||||||
output: &mut Vec4,
|
output: &mut Vec4,
|
||||||
|
|
||||||
|
// NOTE(eddyb) this acts like an integration test for specialization constants.
|
||||||
|
#[spirv(spec_constant(id = 0x5007, default = 100))] sun_intensity_extra_spec_const_factor: u32,
|
||||||
) {
|
) {
|
||||||
let frag_coord = vec2(in_frag_coord.x, in_frag_coord.y);
|
let frag_coord = vec2(in_frag_coord.x, in_frag_coord.y);
|
||||||
*output = fs(constants, frag_coord);
|
*output = fs(constants, frag_coord, sun_intensity_extra_spec_const_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[spirv(vertex)]
|
#[spirv(vertex)]
|
||||||
|
Loading…
Reference in New Issue
Block a user