wip ffl shader port
shader_ffl.wgsl
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