Skip to content

Commit 4c6cf0d

Browse files
committed
example-runner-ash: use NumPad +/- to control sky-shader's "sun intensity" through a specialization constant.
1 parent af2a9ee commit 4c6cf0d

File tree

3 files changed

+49
-6
lines changed

3 files changed

+49
-6
lines changed

examples/runners/ash/src/main.rs

+31
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,19 @@ pub fn main() {
187187
});
188188
}
189189
}
190+
Some(key @ (VirtualKeyCode::NumpadAdd | VirtualKeyCode::NumpadSubtract)) => {
191+
let factor =
192+
&mut ctx.sky_fs_spec_id_0x5007_sun_intensity_extra_spec_const_factor;
193+
*factor = if key == VirtualKeyCode::NumpadAdd {
194+
factor.saturating_add(1)
195+
} else {
196+
factor.saturating_sub(1)
197+
};
198+
199+
// HACK(eddyb) to see any changes, re-specializing the
200+
// shader module is needed (e.g. during pipeline rebuild).
201+
ctx.rebuild_pipelines(vk::PipelineCache::null());
202+
}
190203
_ => *control_flow = ControlFlow::Wait,
191204
},
192205
WindowEvent::Resized(_) => {
@@ -657,6 +670,9 @@ pub struct RenderCtx {
657670
pub rendering_paused: bool,
658671
pub recompiling_shaders: bool,
659672
pub start: std::time::Instant,
673+
674+
// NOTE(eddyb) this acts like an integration test for specialization constants.
675+
pub sky_fs_spec_id_0x5007_sun_intensity_extra_spec_const_factor: u32,
660676
}
661677

662678
impl RenderCtx {
@@ -702,6 +718,8 @@ impl RenderCtx {
702718
rendering_paused: false,
703719
recompiling_shaders: false,
704720
start: std::time::Instant::now(),
721+
722+
sky_fs_spec_id_0x5007_sun_intensity_extra_spec_const_factor: 100,
705723
}
706724
}
707725

@@ -723,6 +741,18 @@ impl RenderCtx {
723741
}
724742

725743
pub fn rebuild_pipelines(&mut self, pipeline_cache: vk::PipelineCache) {
744+
// NOTE(eddyb) this acts like an integration test for specialization constants.
745+
let spec_const_entries = [vk::SpecializationMapEntry::builder()
746+
.constant_id(0x5007)
747+
.offset(0)
748+
.size(4)
749+
.build()];
750+
let spec_const_data =
751+
u32::to_le_bytes(self.sky_fs_spec_id_0x5007_sun_intensity_extra_spec_const_factor);
752+
let specialization_info = vk::SpecializationInfo::builder()
753+
.map_entries(&spec_const_entries)
754+
.data(&spec_const_data);
755+
726756
self.cleanup_pipelines();
727757
let pipeline_layout = self.create_pipeline_layout();
728758
let viewport = vk::PipelineViewportStateCreateInfo::builder()
@@ -754,6 +784,7 @@ impl RenderCtx {
754784
module: *frag_module,
755785
p_name: (*frag_name).as_ptr(),
756786
stage: vk::ShaderStageFlags::FRAGMENT,
787+
p_specialization_info: &*specialization_info,
757788
..Default::default()
758789
},
759790
]))

examples/runners/cpu/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ fn main() {
141141
* vec2(WIDTH as f32, HEIGHT as f32);
142142

143143
// evaluate the fragment shader for the specific pixel
144-
let color = shader_module::fs(&push_constants, frag_coord);
144+
let color = shader_module::fs(&push_constants, frag_coord, 1);
145145

146146
color_u32_from_vec4(color)
147147
})

examples/shaders/sky-shader/src/lib.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ fn sun_intensity(zenith_angle_cos: f32) -> f32 {
7171
)
7272
}
7373

74-
fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
74+
fn sky(dir: Vec3, sun_position: Vec3, sun_intensity_extra_spec_const_factor: u32) -> Vec3 {
7575
let up = vec3(0.0, 1.0, 0.0);
7676
let sunfade = 1.0 - (1.0 - saturate(sun_position.y / 450000.0).exp());
7777
let rayleigh_coefficient = RAYLEIGH - (1.0 * (1.0 - sunfade));
@@ -96,7 +96,12 @@ fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
9696
let beta_r_theta = beta_r * rayleigh_phase(cos_theta * 0.5 + 0.5);
9797

9898
let beta_m_theta = beta_m * henyey_greenstein_phase(cos_theta, MIE_DIRECTIONAL_G);
99-
let sun_e = sun_intensity(sun_direction.dot(up));
99+
let sun_e = sun_intensity(sun_direction.dot(up))
100+
101+
// HACK(eddyb) this acts like an integration test for specialization constants,
102+
// but the correct value is only obtained when this is a noop (multiplies by `1`).
103+
* (sun_intensity_extra_spec_const_factor as f32 / 100.0);
104+
100105
let mut lin = pow(
101106
sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * (Vec3::splat(1.0) - fex),
102107
1.5,
@@ -130,7 +135,11 @@ fn get_ray_dir(uv: Vec2, pos: Vec3, look_at_pos: Vec3) -> Vec3 {
130135
(forward + uv.x * right + uv.y * up).normalize()
131136
}
132137

133-
pub fn fs(constants: &ShaderConstants, frag_coord: Vec2) -> Vec4 {
138+
pub fn fs(
139+
constants: &ShaderConstants,
140+
frag_coord: Vec2,
141+
sun_intensity_extra_spec_const_factor: u32,
142+
) -> Vec4 {
134143
let mut uv = (frag_coord - 0.5 * vec2(constants.width as f32, constants.height as f32))
135144
/ constants.height as f32;
136145
uv.y = -uv.y;
@@ -141,7 +150,7 @@ pub fn fs(constants: &ShaderConstants, frag_coord: Vec2) -> Vec4 {
141150
let dir = get_ray_dir(uv, eye_pos, sun_pos);
142151

143152
// evaluate Preetham sky model
144-
let color = sky(dir, sun_pos);
153+
let color = sky(dir, sun_pos, sun_intensity_extra_spec_const_factor);
145154

146155
// Tonemapping
147156
let color = color.max(Vec3::splat(0.0)).min(Vec3::splat(1024.0));
@@ -154,9 +163,12 @@ pub fn main_fs(
154163
#[spirv(frag_coord)] in_frag_coord: Vec4,
155164
#[spirv(push_constant)] constants: &ShaderConstants,
156165
output: &mut Vec4,
166+
167+
// NOTE(eddyb) this acts like an integration test for specialization constants.
168+
#[spirv(spec_constant(id = 0x5007, default = 100))] sun_intensity_extra_spec_const_factor: u32,
157169
) {
158170
let frag_coord = vec2(in_frag_coord.x, in_frag_coord.y);
159-
*output = fs(constants, frag_coord);
171+
*output = fs(constants, frag_coord, sun_intensity_extra_spec_const_factor);
160172
}
161173

162174
#[spirv(vertex)]

0 commit comments

Comments
 (0)