@@ -12,7 +12,7 @@ use spirv_std::{
12
12
#[ cfg( target_arch = "spirv" ) ]
13
13
use spirv_std:: num_traits:: Float ;
14
14
15
- use crate :: { pbr, IsVector } ;
15
+ use crate :: { pbr, stage :: Camera , IsVector } ;
16
16
17
17
fn radical_inverse_vdc ( mut bits : u32 ) -> f32 {
18
18
bits = ( bits << 16u32 ) | ( bits >> 16u32 ) ;
@@ -149,40 +149,46 @@ pub fn integrate_brdf_doesnt_work(mut n_dot_v: f32, roughness: f32) -> Vec2 {
149
149
Vec2 :: new ( a, b)
150
150
}
151
151
152
- /// Expects a slab to contain a [`crate::stage::Camera`] followed by a `f32`
152
+ /// Used by [`vertex_prefilter_environment_cubemap`] to read the camera and
153
+ /// roughness values from the slab.
154
+ #[ derive( Default , SlabItem ) ]
155
+ pub struct VertexPrefilterEnvironmentCubemapIds {
156
+ pub camera : Id < Camera > ,
157
+ pub roughness : Id < f32 > ,
158
+ }
159
+
160
+ /// Uses the `instance_index` as the [`Id`] of a [`PrefilterEnvironmentIds`].
153
161
/// roughness value.
154
- // TODO: merge this with the standard pass-thru cubemap vertex shader.
155
162
#[ spirv( vertex) ]
156
163
pub fn vertex_prefilter_environment_cubemap (
164
+ #[ spirv( instance_index) ] instance_index : u32 ,
157
165
#[ spirv( vertex_index) ] vertex_id : u32 ,
158
166
#[ spirv( storage_buffer, descriptor_set = 0 , binding = 0 ) ] slab : & [ u32 ] ,
159
167
out_pos : & mut Vec3 ,
168
+ out_roughness : & mut f32 ,
160
169
#[ spirv( position) ] gl_pos : & mut Vec4 ,
161
170
) {
162
171
let in_pos = crate :: math:: CUBE [ vertex_id as usize ] ;
163
- let camera = slab. read :: < crate :: stage:: Camera > ( 0u32 . into ( ) ) ;
172
+ let VertexPrefilterEnvironmentCubemapIds { camera, roughness } =
173
+ slab. read ( Id :: new ( instance_index) ) ;
174
+ let camera = slab. read ( camera) ;
175
+ * out_roughness = slab. read ( roughness) ;
164
176
* out_pos = in_pos;
165
177
* gl_pos = camera. projection * camera. view * in_pos. extend ( 1.0 ) ;
166
178
}
167
179
168
180
/// Lambertian prefilter.
169
- ///
170
- /// Expects a slab to contain a [`crate::stage::Camera`] followed by a `f32`
171
- /// roughness value.
172
181
#[ spirv( fragment) ]
173
182
pub fn fragment_prefilter_environment_cubemap (
174
- #[ spirv( storage_buffer, descriptor_set = 0 , binding = 0 ) ] slab : & [ u32 ] ,
175
183
#[ spirv( descriptor_set = 0 , binding = 1 ) ] environment_cubemap : & Cubemap ,
176
184
#[ spirv( descriptor_set = 0 , binding = 2 ) ] sampler : & Sampler ,
177
185
in_pos : Vec3 ,
186
+ in_roughness : f32 ,
178
187
frag_color : & mut Vec4 ,
179
188
) {
180
- let roughness = slab. read ( Id :: < f32 > :: from ( crate :: stage:: Camera :: slab_size ( ) ) ) ;
181
189
let mut n = in_pos. alt_norm_or_zero ( ) ;
182
190
// `wgpu` and vulkan's y coords are flipped from opengl
183
191
n. y *= -1.0 ;
184
- // These moves are redundant but the names have connections to the PBR
185
- // equations.
186
192
let r = n;
187
193
let v = r;
188
194
@@ -191,12 +197,12 @@ pub fn fragment_prefilter_environment_cubemap(
191
197
192
198
for i in 0 ..SAMPLE_COUNT {
193
199
let xi = hammersley ( i, SAMPLE_COUNT ) ;
194
- let h = importance_sample_ggx ( xi, n, roughness ) ;
200
+ let h = importance_sample_ggx ( xi, n, in_roughness ) ;
195
201
let l = ( 2.0 * v. dot ( h) * h - v) . alt_norm_or_zero ( ) ;
196
202
197
203
let n_dot_l = n. dot ( l) . max ( 0.0 ) ;
198
204
if n_dot_l > 0.0 {
199
- let mip_level = if roughness == 0.0 {
205
+ let mip_level = if in_roughness == 0.0 {
200
206
0.0
201
207
} else {
202
208
calc_lod ( n_dot_l)
0 commit comments