66#![ register_attr( spirv) ]
77
88use core:: f32:: consts:: PI ;
9- use spirv_std:: { Input , Mat4 , MathExt , Output , Vec2 , Vec3 , Vec4 } ;
9+ use glam:: { const_vec3, Mat4 , Vec2 , Vec3 , Vec4 } ;
10+ use spirv_std:: { Input , MathExt , Output } ;
1011
1112const DEPOLARIZATION_FACTOR : f32 = 0.035 ;
1213const LUMINANCE : f32 = 1.0 ;
1314const MIE_COEFFICIENT : f32 = 0.005 ;
1415const MIE_DIRECTIONAL_G : f32 = 0.8 ;
15- const MIE_K_COEFFICIENT : Vec3 = Vec3 :: new ( 0.686 , 0.678 , 0.666 ) ;
16+ const MIE_K_COEFFICIENT : Vec3 = const_vec3 ! ( [ 0.686 , 0.678 , 0.666 ] ) ;
1617const MIE_V : f32 = 4.0 ;
1718const MIE_ZENITH_LENGTH : f32 = 1.25e3 ;
1819const NUM_MOLECULES : f32 = 2.542e25f32 ;
19- const PRIMARIES : Vec3 = Vec3 :: new ( 6.8e-7f32 , 5.5e-7f32 , 4.5e-7f32 ) ;
20+ const PRIMARIES : Vec3 = const_vec3 ! ( [ 6.8e-7f32 , 5.5e-7f32 , 4.5e-7f32 ] ) ;
2021const RAYLEIGH : f32 = 1.0 ;
2122const RAYLEIGH_ZENITH_LENGTH : f32 = 8.4e3 ;
2223const REFRACTIVE_INDEX : f32 = 1.0003 ;
2324const SUN_ANGULAR_DIAMETER_DEGREES : f32 = 0.0093333 ;
2425const SUN_INTENSITY_FACTOR : f32 = 1000.0 ;
2526const SUN_INTENSITY_FALLOFF_STEEPNESS : f32 = 1.5 ;
26- const TONEMAP_WEIGHTING : Vec3 = Vec3 :: splat ( 9.50 ) ;
27+ const TONEMAP_WEIGHTING : Vec3 = const_vec3 ! ( [ 9.50 ; 3 ] ) ;
2728const TURBIDITY : f32 = 2.0 ;
2829
30+ // TODO: add this to glam? Rust std has it on f32/f64
31+ fn pow ( v : Vec3 , power : f32 ) -> Vec3 {
32+ let v: [ f32 ; 3 ] = v. into ( ) ;
33+ Vec3 :: new ( v[ 0 ] . pow ( power) , v[ 1 ] . pow ( power) , v[ 2 ] . pow ( power) )
34+ }
35+
36+ // TODO: add this to glam? Rust std has it on f32/f64
37+ fn exp ( v : Vec3 ) -> Vec3 {
38+ let v: [ f32 ; 3 ] = v. into ( ) ;
39+ Vec3 :: new ( v[ 0 ] . exp ( ) , v[ 1 ] . exp ( ) , v[ 2 ] . exp ( ) )
40+ }
41+
2942/// Based on: https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/
3043fn acos_approx ( v : f32 ) -> f32 {
3144 let x = v. abs ( ) ;
@@ -51,12 +64,12 @@ fn total_rayleigh(lambda: Vec3) -> Vec3 {
5164 ( 8.0 * PI . pow ( 3.0 )
5265 * ( REFRACTIVE_INDEX . pow ( 2.0 ) - 1.0 ) . pow ( 2.0 )
5366 * ( 6.0 + 3.0 * DEPOLARIZATION_FACTOR ) )
54- / ( 3.0 * NUM_MOLECULES * lambda . pow ( 4.0 ) * ( 6.0 - 7.0 * DEPOLARIZATION_FACTOR ) )
67+ / ( 3.0 * NUM_MOLECULES * pow ( lambda , 4.0 ) * ( 6.0 - 7.0 * DEPOLARIZATION_FACTOR ) )
5568}
5669
5770fn total_mie ( lambda : Vec3 , k : Vec3 , t : f32 ) -> Vec3 {
5871 let c = 0.2 * t * 10e-18 ;
59- 0.434 * c * PI * ( ( 2.0 * PI ) / lambda) . pow ( MIE_V - 2.0 ) * k
72+ 0.434 * c * PI * pow ( ( 2.0 * PI ) / lambda, MIE_V - 2.0 ) * k
6073}
6174
6275fn rayleigh_phase ( cos_theta : f32 ) -> f32 {
@@ -78,19 +91,19 @@ fn sun_intensity(zenith_angle_cos: f32) -> f32 {
7891}
7992
8093fn uncharted2_tonemap ( w : Vec3 ) -> Vec3 {
81- const A : Vec3 = Vec3 :: splat ( 0.15 ) ; // Shoulder strength
82- const B : Vec3 = Vec3 :: splat ( 0.50 ) ; // Linear strength
83- const C : Vec3 = Vec3 :: splat ( 0.10 ) ; // Linear angle
84- const D : Vec3 = Vec3 :: splat ( 0.20 ) ; // Toe strength
85- const E : Vec3 = Vec3 :: splat ( 0.02 ) ; // Toe numerator
86- const F : Vec3 = Vec3 :: splat ( 0.30 ) ; // Toe denominator
94+ const A : Vec3 = const_vec3 ! ( [ 0.15 ; 3 ] ) ; // Shoulder strength
95+ const B : Vec3 = const_vec3 ! ( [ 0.50 ; 3 ] ) ; // Linear strength
96+ const C : Vec3 = const_vec3 ! ( [ 0.10 ; 3 ] ) ; // Linear angle
97+ const D : Vec3 = const_vec3 ! ( [ 0.20 ; 3 ] ) ; // Toe strength
98+ const E : Vec3 = const_vec3 ! ( [ 0.02 ; 3 ] ) ; // Toe numerator
99+ const F : Vec3 = const_vec3 ! ( [ 0.30 ; 3 ] ) ; // Toe denominator
87100
88101 ( ( w * ( A * w + C * B ) + D * E ) / ( w * ( A * w + B ) + D * F ) ) - E / F
89102}
90103
91104fn sky ( dir : Vec3 , sun_position : Vec3 ) -> Vec3 {
92105 let up = Vec3 :: new ( 0.0 , 1.0 , 0.0 ) ;
93- let sunfade = 1.0 - ( 1.0 - ( sun_position. 1 / 450000.0 ) . exp ( ) ) . saturate ( ) ;
106+ let sunfade = 1.0 - ( 1.0 - ( sun_position. y ( ) / 450000.0 ) . exp ( ) ) . saturate ( ) ;
94107 let rayleigh_coefficient = RAYLEIGH - ( 1.0 * ( 1.0 - sunfade) ) ;
95108 let beta_r = total_rayleigh ( PRIMARIES ) * rayleigh_coefficient;
96109
@@ -105,7 +118,7 @@ fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
105118 let s_m = MIE_ZENITH_LENGTH / denom;
106119
107120 // Combined extinction factor
108- let fex = ( -( beta_r * s_r + beta_m * s_m) ) . exp ( ) ;
121+ let fex = exp ( -( beta_r * s_r + beta_m * s_m) ) ;
109122
110123 // In-scattering
111124 let sun_direction = sun_position. normalize ( ) ;
@@ -114,11 +127,16 @@ fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
114127
115128 let beta_m_theta = beta_m * henyey_greenstein_phase ( cos_theta, MIE_DIRECTIONAL_G ) ;
116129 let sun_e = sun_intensity ( sun_direction. dot ( up) ) ;
117- let mut lin =
118- ( sun_e * ( ( beta_r_theta + beta_m_theta) / ( beta_r + beta_m) ) * ( Vec3 :: splat ( 1.0 ) - fex) )
119- . pow ( 1.5 ) ;
130+ let mut lin = pow (
131+ sun_e * ( ( beta_r_theta + beta_m_theta) / ( beta_r + beta_m) ) * ( Vec3 :: splat ( 1.0 ) - fex) ,
132+ 1.5 ,
133+ ) ;
134+
120135 lin *= Vec3 :: splat ( 1.0 ) . lerp (
121- ( sun_e * ( ( beta_r_theta + beta_m_theta) / ( beta_r + beta_m) ) * fex) . pow ( 0.5 ) ,
136+ pow (
137+ sun_e * ( ( beta_r_theta + beta_m_theta) / ( beta_r + beta_m) ) * fex,
138+ 0.5 ,
139+ ) ,
122140 ( ( 1.0 - up. dot ( sun_direction) ) . pow ( 5.0 ) ) . saturate ( ) ,
123141 ) ;
124142
@@ -140,50 +158,24 @@ fn sky(dir: Vec3, sun_position: Vec3) -> Vec3 {
140158 let curr = uncharted2_tonemap ( ( ( 2.0 / LUMINANCE . pow ( 4.0 ) ) . log2 ( ) ) * tex_color) ;
141159 let color = curr * white_scale;
142160
143- color. pow ( 1.0 / ( 1.2 + ( 1.2 * sunfade) ) )
144- }
145-
146- pub fn main_fs_test ( screen_pos : Vec2 ) -> Vec4 {
147- // hard-code information because we can't bind buffers at the moment
148- let eye_pos = Vec3 ( 0.0 , 0.0997 , 0.2 ) ;
149- let sun_pos = Vec3 :: new ( 0.0 , 75.0 , -1000.0 ) ;
150- let clip_to_world = Mat4 {
151- x_axis : Vec4 ( -0.5522849 , 0.0 , 0.0 , 0.0 ) ,
152- y_axis : Vec4 ( 0.0 , 0.4096309 , -0.061444636 , 0.0 ) ,
153- z_axis : Vec4 ( 0.0 , 99.99999 , 199.99998 , 999.99994 ) ,
154- w_axis : Vec4 ( 0.0 , -0.14834046 , -0.98893654 , 0.0 ) ,
155- } ;
156-
157- let cs_pos = Vec4 ( screen_pos. 0 , -screen_pos. 1 , 1.0 , 1.0 ) ;
158- let ws_pos = {
159- let p = clip_to_world. mul_vec4 ( cs_pos) ;
160- p. truncate ( ) / p. 3
161- } ;
162- let dir = ( ws_pos - eye_pos) . normalize ( ) ;
163-
164- // evaluate Preetham sky model
165- let color = sky ( dir, sun_pos) ;
166-
167- // let color = dir;
168-
169- color. extend ( 1.0 )
161+ pow ( color, 1.0 / ( 1.2 + ( 1.2 * sunfade) ) )
170162}
171163
172164pub fn fs ( screen_pos : Vec2 ) -> Vec4 {
173165 // hard-code information because we can't bind buffers at the moment
174- let eye_pos = Vec3 ( 0.0 , 0.0997 , 0.2 ) ;
166+ let eye_pos = Vec3 :: new ( 0.0 , 0.0997 , 0.2 ) ;
175167 let sun_pos = Vec3 :: new ( 0.0 , 75.0 , -1000.0 ) ;
176- let clip_to_world = Mat4 {
177- x_axis : Vec4 ( -0.5522849 , 0.0 , 0.0 , 0.0 ) ,
178- y_axis : Vec4 ( 0.0 , 0.4096309 , -0.061444636 , 0.0 ) ,
179- z_axis : Vec4 ( 0.0 , 99.99999 , 199.99998 , 999.99994 ) ,
180- w_axis : Vec4 ( 0.0 , -0.14834046 , -0.98893654 , 0.0 ) ,
181- } ;
168+ let clip_to_world = Mat4 :: from_cols (
169+ Vec4 :: new ( -0.5522849 , 0.0 , 0.0 , 0.0 ) ,
170+ Vec4 :: new ( 0.0 , 0.4096309 , -0.061444636 , 0.0 ) ,
171+ Vec4 :: new ( 0.0 , 99.99999 , 199.99998 , 999.99994 ) ,
172+ Vec4 :: new ( 0.0 , -0.14834046 , -0.98893654 , 0.0 ) ,
173+ ) ;
182174
183- let cs_pos = Vec4 ( screen_pos. 0 , -screen_pos. 1 , 1.0 , 1.0 ) ;
175+ let cs_pos = Vec4 :: new ( screen_pos. x ( ) , -screen_pos. y ( ) , 1.0 , 1.0 ) ;
184176 let ws_pos = {
185177 let p = clip_to_world. mul_vec4 ( cs_pos) ;
186- p. truncate ( ) / p. 3
178+ p. truncate ( ) / p. w ( )
187179 } ;
188180 let dir = ( ws_pos - eye_pos) . normalize ( ) ;
189181
@@ -197,7 +189,7 @@ pub fn fs(screen_pos: Vec2) -> Vec4 {
197189#[ spirv( fragment) ]
198190pub fn main_fs ( input : Input < Vec4 > , mut output : Output < Vec4 > ) {
199191 let v = input. load ( ) ;
200- let color = fs ( Vec2 :: new ( v. 0 , v. 1 ) ) ;
192+ let color = fs ( Vec2 :: new ( v. x ( ) , v. y ( ) ) ) ;
201193 output. store ( color)
202194}
203195
0 commit comments