wip ffl shader port
shader_ffl.wgsl
230 lines 5.9 kB view raw
1struct TransformUniform { 2 mtx: mat4x4<f32>, 3 color_r: vec4<f32>, 4 color_g: vec4<f32>, 5 color_b: vec4<f32>, 6 modulation_mode: u32, 7}; 8 9@group(1) @binding(0) // 1. 10var<uniform> mvp: TransformUniform; 11 12 13 14struct VertexOutput { 15 @builtin(position) clip_position: vec4<f32>, 16 @location(0) tex_coords: vec2<f32>, 17 @location(1) thirdthing: vec4<f32>, 18} 19 20@vertex 21fn vs_main( 22 @location(0) position: vec4<f32>, 23 @location(1) tex_coords: vec2<f32> 24) -> VertexOutput { 25 var out: VertexOutput; 26 out.tex_coords = tex_coords; 27 28 out.clip_position = mvp.mtx * vec4<f32>(position.xyz, 1.0); 29 30 return out; 31} 32 33@group(0) @binding(0) 34var t_diffuse: texture_2d<f32>; 35@group(0) @binding(1) 36var s_diffuse: sampler; 37 38 39fn modulate(color: vec4f, mode: u32) -> vec4f { 40 if mode == 0 { 41 return modulate_single_color(color); 42 } else if mode == 1 { 43 return modulate_direct_texture(color); 44 } else if mode == 2 { 45 return modulate_rgba(color); 46 } else if mode == 3 { 47 return modulate_alpha(color); 48 } else if mode == 4 { 49 return modulate_lum_alpha(color); 50 } else if mode == 5 { 51 return modulate_lum(color); 52 } else { 53 // OOB access, return RebeccaPurple 54 return vec4f(0.4, 0.2, 0.6, 1.0); 55 } 56} 57 58 59// new bindings (TODO bind these from wgpu) 60struct ULight { 61 ambient: vec3f, 62 diffuse: vec3f, 63 dir: vec3f, 64 enable: bool, 65 specular: vec3f, 66}; 67 68@group(2) @binding(0) 69var<uniform> u_light: ULight; 70 71struct UAmbient { 72 ambient: vec3f, 73 diffuse: vec3f, 74 specular: vec3f, 75 dir: i32, 76 specular_power: f32, 77}; 78 79@group(2) @binding(1) 80var<uniform> u_ambient: UAmbient; 81 82// ill figure this out laater? 83struct V { 84 color: vec4f, 85 position: vec3f, 86 normal: vec3f, 87 tangent: vec3f, 88 texCoord: vec3f, 89}; 90 91@group(2) @binding(2) 92var<uniform> v: V; 93 94struct UConst { 95 first: vec4f, 96 second: vec4f, 97 third: vec4f, 98}; 99 100@group(2) @binding(3) 101var<uniform> u_const: UConst; 102 103struct URim { 104 color: vec3f, 105 power: f32, 106} 107 108@group(2) @binding(4) 109var<uniform> u_rim: URim; 110// end new bindings 111 112@fragment 113fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { 114 var color: vec4<f32> = textureSample(t_diffuse, s_diffuse, in.tex_coords); 115 116 let specular_power = u_material.specular.power; 117 let rim_width = v.color.a; 118 119 color = modulate(color, mvp.modulation_mode); 120 121 //#ifdef FFL_LIGHT_MODE_ENABLE 122 let ambient: vec3f = calc_ambient_color(u_light.ambient.xyz, u_material.ambient.xyz); 123 let norm: vec3f = normalize(v.normal); 124 let eye: vec3f = normalize(-v.position.xyz); 125 let f_dot: f32 = calc_dot(u_light.dir, norm); 126 let diffuse: vec3f = calc_diffuse_color(u_light.diffuse.xyz, u_material.diffuse.xyz, f_dot); 127 let specular_blinn: vec3f = calc_blinn_specular(u_light.dir, norm, eye, u_material.specular.power); 128 129 var reflection: f32 = 0.0; 130 var strength: f32 = v.color.g; 131 if (u_material.specular.mode == 0) { 132 strength = 1.0; 133 reflection = specular_blinn; 134 } else { 135 let specular_aniso = calc_anisotropic_specular(u_light.dir, v.tangent, eye, u_material.specular.power); 136 reflection = calc_specular_spend(v.color.r, specular_blinn, specular_aniso); 137 } 138 139 let specular: vec3f = calc_specular_color(u_light.specular.xyz, u_material.specular.xyz, reflection, strength); 140 let rim_color: vec3f = calc_rim_color(u_rim.color.rgb, norm.z, rim_width, u_rim.power); 141 142 color.rgb = (ambient + diffuse) * color.rgb + specular + rimColor; 143 //#endif 144 145 return color; 146} 147 148// Two trivial cases 149fn modulate_single_color(color: vec4f) -> vec4f { 150 return mvp.color_r; 151} 152 153fn modulate_direct_texture(color: vec4f) -> vec4f { 154 return color; 155} 156 157// Texture passes us alpha information, we fill in the rest of the color. 158// [a,0,0,0] -> [r,g,b,a] 159fn modulate_alpha(color: vec4f) -> vec4f { 160 let repl = mvp.color_r; 161 162 return vec4(repl.rgb, color.r); 163} 164 165// Texture passes luminance + alpha, we colorize it. 166// [l,a,0,0] -> [r,g,b,a] 167fn modulate_lum_alpha(color: vec4f) -> vec4f { 168 let repl_lum = mvp.color_r; 169 170 return vec4f(color.r * repl_lum.rgb, color.g * repl_lum.a); 171} 172 173// Texture passes luminance, we colorize it (alpha always 1). 174// [l,0,0,0] -> [r,g,b,1] 175fn modulate_lum(color: vec4f) -> vec4f { 176 let repl_lum = mvp.color_r; 177 178 return vec4f(color.r * repl_lum.rgb, 1.0); 179} 180 181fn modulate_rgba(color: vec4f) -> vec4f { 182 let repl_r = mvp.color_r; 183 let repl_g = mvp.color_g; 184 let repl_b = mvp.color_b; 185 186 return vec4f(color.r * repl_r.rgb + color.g * repl_g.rgb + color.b * repl_b.rgb, color.a * repl_r.a); 187 188} 189// fragment shader stuffs BEGIN 190 191fn calc_anisotripic_specular( 192 light: vec3f, 193 tangent: vec3f, 194 eye: vec3f, 195 power: f32, 196) -> f32 { 197 let dotLT = dot(light, tangent); 198 let dotVT = dot(eye, tangent); 199 let dotLN = sqrt(1.0 - dotLT * dotLT); 200 let dotVR = dotLN * sqrt(1.0 - dotVT * dotVT) - dotLT * dotVT; 201 202 return pow(max(0.0, dotVR), power); 203} 204 205fn calc_blinn_specular(light: vec3f, normal: vec3f, eye: vec3f, power: f32) -> f32 { 206 return pow(max(dot(reflect(-light, normal), eye), 0.0), power); 207} 208 209fn calc_specular_blend(blend: f32, blinn: f32, aniso: f32) -> f32 { 210 return mix(aniso, blinn, blend); 211} 212 213// did you really need a function to multiply 3 values?? 214fn calc_diffuse_color(light: vec3f, material: vec3f, ln: f32) -> vec3f { 215 return light * material * ln; 216} 217 218fn calc_specular_color(light: vec3f, material: vec3f, reflection: f32, strength: f32 ) -> vec3f { 219 return light * material * reflection * strength; 220} 221 222fn calc_rim_color(color: vec3f, normal_z: f32, width: f32, power: f32) -> vec3f { 223 return color * pow(width * (1.0 - abs(normal_z)), power); 224} 225 226fn calc_dot(light: vec3f, normal: vec3f) -> f32 { 227 return max(dot(light, normal), 0.1); 228} 229 230// fragment shader stuffs END