1
1
//! Convolution shaders.
2
2
//!
3
3
//! These shaders convolve various functions to produce cached maps.
4
+ use crabslab:: { Id , Slab , SlabItem } ;
4
5
use glam:: { UVec2 , Vec2 , Vec3 , Vec4 , Vec4Swizzles } ;
5
6
use spirv_std:: {
6
7
image:: { Cubemap , Image2d } ,
@@ -11,7 +12,7 @@ use spirv_std::{
11
12
#[ cfg( target_arch = "spirv" ) ]
12
13
use spirv_std:: num_traits:: Float ;
13
14
14
- use crate :: { pbr, stage :: GpuConstants , IsVector } ;
15
+ use crate :: { pbr, IsVector } ;
15
16
16
17
fn radical_inverse_vdc ( mut bits : u32 ) -> f32 {
17
18
bits = ( bits << 16u32 ) | ( bits >> 16u32 ) ;
@@ -148,26 +149,35 @@ pub fn integrate_brdf_doesnt_work(mut n_dot_v: f32, roughness: f32) -> Vec2 {
148
149
Vec2 :: new ( a, b)
149
150
}
150
151
152
+ /// Expects a slab to contain a [`crate::stage::Camera`] followed by a `f32`
153
+ /// roughness value.
154
+ // TODO: merge this with the standard pass-thru cubemap vertex shader.
151
155
#[ spirv( vertex) ]
152
156
pub fn vertex_prefilter_environment_cubemap (
153
- #[ spirv( uniform , descriptor_set = 0 , binding = 0 ) ] constants : & GpuConstants ,
154
- in_pos : Vec3 ,
157
+ #[ spirv( vertex_index ) ] vertex_id : u32 ,
158
+ # [ spirv ( storage_buffer , descriptor_set = 0 , binding = 0 ) ] slab : & [ u32 ] ,
155
159
out_pos : & mut Vec3 ,
156
160
#[ spirv( position) ] gl_pos : & mut Vec4 ,
157
161
) {
162
+ let in_pos = crate :: math:: CUBE [ vertex_id as usize ] ;
163
+ let camera = slab. read :: < crate :: stage:: Camera > ( 0u32 . into ( ) ) ;
158
164
* out_pos = in_pos;
159
- * gl_pos = constants . camera_projection * constants . camera_view * in_pos. extend ( 1.0 ) ;
165
+ * gl_pos = camera . projection * camera . view * in_pos. extend ( 1.0 ) ;
160
166
}
161
167
162
168
/// Lambertian prefilter.
169
+ ///
170
+ /// Expects a slab to contain a [`crate::stage::Camera`] followed by a `f32`
171
+ /// roughness value.
163
172
#[ spirv( fragment) ]
164
173
pub fn fragment_prefilter_environment_cubemap (
165
- #[ spirv( uniform , descriptor_set = 0 , binding = 1 ) ] roughness : & f32 ,
166
- #[ spirv( descriptor_set = 0 , binding = 2 ) ] environment_cubemap : & Cubemap ,
167
- #[ spirv( descriptor_set = 0 , binding = 3 ) ] sampler : & Sampler ,
174
+ #[ spirv( storage_buffer , descriptor_set = 0 , binding = 0 ) ] slab : & [ u32 ] ,
175
+ #[ spirv( descriptor_set = 0 , binding = 1 ) ] environment_cubemap : & Cubemap ,
176
+ #[ spirv( descriptor_set = 0 , binding = 2 ) ] sampler : & Sampler ,
168
177
in_pos : Vec3 ,
169
178
frag_color : & mut Vec4 ,
170
179
) {
180
+ let roughness = slab. read ( Id :: < f32 > :: from ( crate :: stage:: Camera :: slab_size ( ) ) ) ;
171
181
let mut n = in_pos. alt_norm_or_zero ( ) ;
172
182
// `wgpu` and vulkan's y coords are flipped from opengl
173
183
n. y *= -1.0 ;
@@ -181,12 +191,12 @@ pub fn fragment_prefilter_environment_cubemap(
181
191
182
192
for i in 0 ..SAMPLE_COUNT {
183
193
let xi = hammersley ( i, SAMPLE_COUNT ) ;
184
- let h = importance_sample_ggx ( xi, n, * roughness) ;
194
+ let h = importance_sample_ggx ( xi, n, roughness) ;
185
195
let l = ( 2.0 * v. dot ( h) * h - v) . alt_norm_or_zero ( ) ;
186
196
187
197
let n_dot_l = n. dot ( l) . max ( 0.0 ) ;
188
198
if n_dot_l > 0.0 {
189
- let mip_level = if * roughness == 0.0 {
199
+ let mip_level = if roughness == 0.0 {
190
200
0.0
191
201
} else {
192
202
calc_lod ( n_dot_l)
@@ -273,15 +283,44 @@ pub fn fragment_bloom(
273
283
* frag_color = result. extend ( 1.0 ) ;
274
284
}
275
285
286
+ #[ repr( C ) ]
287
+ #[ derive( Clone , Copy ) ]
288
+ struct Vert {
289
+ pos : [ f32 ; 3 ] ,
290
+ uv : [ f32 ; 2 ] ,
291
+ }
292
+
293
+ /// A screen-space quad.
294
+ const BRDF_VERTS : [ Vert ; 6 ] = {
295
+ let bl = Vert {
296
+ pos : [ -1.0 , -1.0 , 0.0 ] ,
297
+ uv : [ 0.0 , 1.0 ] ,
298
+ } ;
299
+ let br = Vert {
300
+ pos : [ 1.0 , -1.0 , 0.0 ] ,
301
+ uv : [ 1.0 , 1.0 ] ,
302
+ } ;
303
+ let tl = Vert {
304
+ pos : [ -1.0 , 1.0 , 0.0 ] ,
305
+ uv : [ 0.0 , 0.0 ] ,
306
+ } ;
307
+ let tr = Vert {
308
+ pos : [ 1.0 , 1.0 , 0.0 ] ,
309
+ uv : [ 1.0 , 0.0 ] ,
310
+ } ;
311
+
312
+ [ bl, br, tr, bl, tr, tl]
313
+ } ;
314
+
276
315
#[ spirv( vertex) ]
277
316
pub fn vertex_brdf_lut_convolution (
278
- in_pos : glam:: Vec3 ,
279
- in_uv : glam:: Vec2 ,
317
+ #[ spirv( vertex_index) ] vertex_id : u32 ,
280
318
out_uv : & mut glam:: Vec2 ,
281
319
#[ spirv( position) ] gl_pos : & mut glam:: Vec4 ,
282
320
) {
283
- * out_uv = in_uv;
284
- * gl_pos = in_pos. extend ( 1.0 ) ;
321
+ let Vert { pos, uv } = BRDF_VERTS [ vertex_id as usize ] ;
322
+ * out_uv = Vec2 :: from ( uv) ;
323
+ * gl_pos = Vec3 :: from ( pos) . extend ( 1.0 ) ;
285
324
}
286
325
287
326
#[ spirv( fragment) ]
0 commit comments