Skip to content

Commit

Permalink
example-runner-ash: use NumPad +/- to control sky-shader's "sun int…
Browse files Browse the repository at this point in the history
…ensity" through a specialization constant.
  • Loading branch information
eddyb committed Jul 20, 2023
1 parent 64a3332 commit a3a32a9
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
31 changes: 31 additions & 0 deletions examples/runners/ash/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
WindowEvent::Resized(_) => {
Expand Down Expand Up @@ -657,6 +670,9 @@ pub struct RenderCtx {
pub rendering_paused: bool,
pub recompiling_shaders: bool,
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 {
Expand Down Expand Up @@ -702,6 +718,8 @@ impl RenderCtx {
rendering_paused: false,
recompiling_shaders: false,
start: std::time::Instant::now(),

sky_fs_spec_id_0x5007_sun_intensity_extra_spec_const_factor: 100,
}
}

Expand All @@ -723,6 +741,18 @@ impl RenderCtx {
}

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();
let pipeline_layout = self.create_pipeline_layout();
let viewport = vk::PipelineViewportStateCreateInfo::builder()
Expand Down Expand Up @@ -754,6 +784,7 @@ impl RenderCtx {
module: *frag_module,
p_name: (*frag_name).as_ptr(),
stage: vk::ShaderStageFlags::FRAGMENT,
p_specialization_info: &*specialization_info,
..Default::default()
},
]))
Expand Down
2 changes: 1 addition & 1 deletion examples/runners/cpu/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ fn main() {
* vec2(WIDTH as f32, HEIGHT as f32);

// 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)
})
Expand Down
22 changes: 17 additions & 5 deletions examples/shaders/sky-shader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 sunfade = 1.0 - (1.0 - saturate(sun_position.y / 450000.0).exp());
let rayleigh_coefficient = RAYLEIGH - (1.0 * (1.0 - sunfade));
Expand All @@ -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_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(
sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * (Vec3::splat(1.0) - fex),
1.5,
Expand Down Expand Up @@ -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()
}

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))
/ constants.height as f32;
uv.y = -uv.y;
Expand All @@ -141,7 +150,7 @@ pub fn fs(constants: &ShaderConstants, frag_coord: Vec2) -> Vec4 {
let dir = get_ray_dir(uv, eye_pos, sun_pos);

// evaluate Preetham sky model
let color = sky(dir, sun_pos);
let color = sky(dir, sun_pos, sun_intensity_extra_spec_const_factor);

// Tonemapping
let color = color.max(Vec3::splat(0.0)).min(Vec3::splat(1024.0));
Expand All @@ -154,9 +163,12 @@ pub fn main_fs(
#[spirv(frag_coord)] in_frag_coord: Vec4,
#[spirv(push_constant)] constants: &ShaderConstants,
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);
*output = fs(constants, frag_coord);
*output = fs(constants, frag_coord, sun_intensity_extra_spec_const_factor);
}

#[spirv(vertex)]
Expand Down

0 comments on commit a3a32a9

Please sign in to comment.