Skip to content

Commit 7b29217

Browse files
dakersankhesh
authored andcommitted
fix(CellArrayMapper): reduces func arguments to improving readability
1 parent 629a4d2 commit 7b29217

File tree

1 file changed

+112
-90
lines changed
  • Sources/Rendering/WebGPU/CellArrayMapper

1 file changed

+112
-90
lines changed

Sources/Rendering/WebGPU/CellArrayMapper/index.js

Lines changed: 112 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,30 @@ struct PBRData {
6363
specular: vec3<f32>,
6464
}
6565
66+
struct Material {
67+
ior: f32,
68+
roughness: f32,
69+
metallic: f32,
70+
base: vec3<f32>,
71+
};
72+
73+
struct DirectionalLight {
74+
direction: vec3<f32>,
75+
color: vec3<f32>,
76+
};
77+
78+
struct PointLight {
79+
position: vec3<f32>,
80+
color: vec3<f32>,
81+
};
82+
83+
struct SpotLight {
84+
position: vec3<f32>,
85+
direction: vec3<f32>,
86+
cones: vec2<f32>,
87+
color: vec3<f32>,
88+
};
89+
6690
const pi: f32 = 3.14159265359;
6791
6892
// Dot product with the max already in it
@@ -167,53 +191,51 @@ fn cookTorrance(D: f32, F: f32, G: f32, N: vec3<f32>, V: vec3<f32>, L: vec3<f32>
167191
}
168192
169193
// Different lighting calculations for different light sources
170-
fn calcDirectionalLight(N: vec3<f32>, V: vec3<f32>, ior: f32, roughness: f32, metallic: f32, direction: vec3<f32>, color: vec3<f32>, base: vec3<f32>) -> PBRData {
171-
var L: vec3<f32> = normalize(direction); // Light Vector
194+
fn calcDirectionalLight(N: vec3<f32>, V: vec3<f32>, mat: Material, light: DirectionalLight) -> PBRData {
195+
var L: vec3<f32> = normalize(light.direction); // Light Vector
172196
var H: vec3<f32> = normalize(L + V); // Halfway Vector
173197
174-
var alpha = roughness*roughness;
175-
var k: f32 = alpha*alpha / 2;
198+
var alpha = mat.roughness * mat.roughness;
199+
var k: f32 = alpha * alpha / 2.0;
176200
177201
var D: f32 = trGGX(N, H, alpha); // Distribution
178202
// var F: f32 = schlickFresnelIOR(V, N, ior, k); // Fresnel
179203
var G: f32 = smithSurfaceRoughness(N, V, L, k); // Geometry
180204
181205
var brdf: f32 = cookTorrance(D, 1.0, G, N, V, L); // Fresnel term is replaced with 1 because it is added later
182-
var incoming: vec3<f32> = color;
206+
var incoming: vec3<f32> = light.color;
183207
var angle: f32 = mdot(L, N);
184208
angle = pow(angle, 1.5);
185209
186-
var specular: vec3<f32> = brdf*incoming*angle;
210+
var specular: vec3<f32> = brdf * incoming * angle;
187211
// Oren-Nayar gives a clay-like effect when fully rough which some people may not want, so it might be better to give a separate
188212
// control property for the diffuse vs specular roughness
189-
var diffuse: vec3<f32> = incoming*fujiiOrenNayar(base, roughness, N, L, V);
213+
var diffuse: vec3<f32> = incoming * fujiiOrenNayar(mat.base, mat.roughness, N, L, V);
190214
// Stores the specular and diffuse separately to allow for finer post processing
191215
var out = PBRData(diffuse, specular);
192216
193217
return out; // Returns angle along with color of light so the final color can be multiplied by angle as well (creates black areas)
194218
}
195219
196-
// TODO: find some way to reduce the number of arguments going in here
197-
fn calcPointLight(N: vec3<f32>, V: vec3<f32>, fragPos: vec3<f32>, ior: f32, roughness: f32, metallic: f32, position: vec3<f32>, color: vec3<f32>, base: vec3<f32>) -> PBRData {
198-
var L: vec3<f32> = normalize(position - fragPos); // Light Vector
199-
var H: vec3<f32> = normalize(L + V); // Halfway Vector
200-
var dist = distance(position, fragPos);
220+
fn calcPointLight(N: vec3<f32>, V: vec3<f32>, fragPos: vec3<f32>, mat: Material, light: PointLight) -> PBRData {
221+
var L: vec3<f32> = normalize(light.position - fragPos);
222+
var H: vec3<f32> = normalize(L + V);
223+
var dist = distance(light.position, fragPos);
201224
202-
var alpha = roughness*roughness;
203-
var k: f32 = alpha*alpha / 2.0; // could also be pow(alpha + 1.0, 2) / 8
225+
var alpha = mat.roughness * mat.roughness;
226+
var k: f32 = alpha * alpha / 2.0;
204227
205228
var D: f32 = trGGX(N, H, alpha); // Distribution
206-
// var F: f32 = schlickFresnelIOR(V, N, ior, k); // Fresnel
229+
var F: f32 = schlickFresnelIOR(V, N, mat.ior, k); // Fresnel
207230
var G: f32 = smithSurfaceRoughness(N, V, L, k); // Geometry
208231
209232
var brdf: f32 = cookTorrance(D, 1.0, G, N, V, L);
210-
var incoming: vec3<f32> = color * (1.0 / (dist*dist));
233+
var incoming: vec3<f32> = light.color * (1.0 / (dist * dist));
211234
var angle: f32 = mdot(L, N);
212-
angle = pow(angle, 1.5); // Smoothing factor makes it less accurate, but reduces ugly "seams" bewteen light sources
213-
214-
var specular: vec3<f32> = brdf*incoming*angle;
215-
var diffuse: vec3<f32> = incoming*fujiiOrenNayar(base, roughness, N, L, V);
235+
angle = pow(angle, 1.5); // Smoothing factor makes it less accurate, but reduces ugly "seams" between light sources
216236
237+
var specular: vec3<f32> = brdf * incoming * angle;
238+
var diffuse: vec3<f32> = incoming * fujiiOrenNayar(mat.base, mat.roughness, N, L, V);
217239
// Stores the specular and diffuse separately to allow for finer post processing
218240
// Could also be done (propably more properly) with a struct
219241
var out = PBRData(diffuse, specular);
@@ -222,34 +244,33 @@ fn calcPointLight(N: vec3<f32>, V: vec3<f32>, fragPos: vec3<f32>, ior: f32, roug
222244
}
223245
224246
// For a reason unknown to me, spheres dont seem to behave propperly with head-on spot lights
225-
fn calcSpotLight(N: vec3<f32>, V: vec3<f32>, fragPos: vec3<f32>, ior: f32, roughness: f32, metallic: f32, position: vec3<f32>, direction: vec3<f32>, cones: vec2<f32>, color: vec3<f32>, base: vec3<f32>) -> PBRData {
226-
var L: vec3<f32> = normalize(position - fragPos);
247+
fn calcSpotLight(N: vec3<f32>, V: vec3<f32>, fragPos: vec3<f32>, mat: Material, light: SpotLight) -> PBRData {
248+
var L: vec3<f32> = normalize(light.position - fragPos);
227249
var H: vec3<f32> = normalize(L + V); // Halfway Vector
228-
var dist = distance(position, fragPos);
250+
var dist = distance(light.position, fragPos);
229251
230-
var alpha = roughness*roughness;
231-
var k: f32 = alpha*alpha / 2.0; // could also be pow(alpha + 1.0, 2) / 8
252+
var alpha = mat.roughness * mat.roughness;
253+
var k: f32 = alpha * alpha / 2.0; // could also be pow(alpha + 1.0, 2) / 8
232254
233255
var D: f32 = trGGX(N, H, alpha); // Distribution
234256
// var F: f32 = schlickFresnelIOR(V, N, ior, k); // Fresnel
235257
var G: f32 = smithSurfaceRoughness(N, V, L, k); // Geometry
236258
237259
var brdf: f32 = cookTorrance(D, 1.0, G, N, V, L);
238260
239-
// Cones.x is the inner phi and cones.y is the outer phi
240-
var theta: f32 = mdot(normalize(direction), L);
241-
var epsilon: f32 = cones.x - cones.y;
242-
var intensity: f32 = (theta - cones.y) / epsilon;
261+
var theta: f32 = mdot(normalize(light.direction), L);
262+
var epsilon: f32 = light.cones.x - light.cones.y;
263+
var intensity: f32 = (theta - light.cones.y) / epsilon;
243264
intensity = clamp(intensity, 0.0, 1.0);
244-
intensity /= dist*dist;
265+
intensity /= dist * dist;
245266
246-
var incoming: vec3<f32> = color * intensity;
267+
var incoming: vec3<f32> = light.color * intensity;
247268
248269
var angle: f32 = mdot(L, N);
249-
angle = pow(angle, 1.5); // Smoothing factor makes it less accurate, but reduces ugly "seams" bewteen light sources
270+
angle = pow(angle, 1.5); // Smoothing factor makes it less accurate, but reduces ugly "seams" between light sources
250271
251-
var specular: vec3<f32> = brdf*incoming*angle;
252-
var diffuse: vec3<f32> = incoming*fujiiOrenNayar(base, roughness, N, L, V);
272+
var specular: vec3<f32> = brdf * incoming * angle;
273+
var diffuse: vec3<f32> = incoming * fujiiOrenNayar(mat.base, mat.roughness, N, L, V);
253274
254275
// Stores the specular and diffuse separately to allow for finer post processing
255276
// Could also be done (propably more properly) with a struct
@@ -302,6 +323,7 @@ fn main(
302323
var ambientColor: vec4<f32> = mapperUBO.AmbientColor;
303324
var diffuseColor: vec4<f32> = mapperUBO.DiffuseColor;
304325
var opacity: f32 = mapperUBO.Opacity;
326+
var ior: f32 = mapperUBO.BaseIOR;
305327
306328
// This should be declared somewhere else
307329
var _diffuseMap: vec4<f32> = vec4<f32>(1.0);
@@ -631,89 +653,89 @@ function vtkWebGPUCellArrayMapper(publicAPI, model) {
631653
) {
632654
const lightingCode = [
633655
// Vectors needed for light calculations
634-
' var fragPos: vec3<f32> = vec3<f32>(input.vertexVC.xyz);',
635-
' var V: vec3<f32> = mix(normalize(-fragPos), vec3<f32>(0, 0, 1), f32(rendererUBO.cameraParallel)); // View Vector',
656+
' let fragPos = vec3<f32>(input.vertexVC.xyz);',
657+
' let V = mix(normalize(-fragPos), vec3<f32>(0, 0, 1), f32(rendererUBO.cameraParallel)); // View Vector',
636658
// Values needed for light calculations
637-
' var baseColor: vec3<f32> = _diffuseMap.rgb * diffuseColor.rgb;',
638-
' var roughness: f32 = max(0.000001, mapperUBO.Roughness * _roughnessMap.r);', // Need to have a different way of sampling greyscale values aside from .r
639-
' var metallic: f32 = mapperUBO.Metallic * _metallicMap.r;',
640-
' var alpha: f32 = roughness*roughness;',
641-
' var ior: f32 = mapperUBO.BaseIOR;',
642-
' var k: f32 = alpha*alpha / 2;',
659+
' let baseColor = _diffuseMap.rgb * diffuseColor.rgb;',
660+
' let roughness = max(0.000001, mapperUBO.Roughness * _roughnessMap.r);', // Need to have a different way of sampling greyscale values aside from .r
661+
' let metallic = mapperUBO.Metallic * _metallicMap.r;',
662+
' let alpha = roughness * roughness;',
663+
' let k = alpha * alpha / 2.0;',
643664
// Split diffuse and specular components
644-
' var diffuse: vec3<f32> = vec3<f32>(0.);',
645-
' var specular: vec3<f32> = vec3<f32>(0.);',
646-
' var emission: vec3<f32> = _emissionMap.rgb * mapperUBO.Emission;',
665+
' var diffuse = vec3<f32>(0.);',
666+
' var specular = vec3<f32>(0.);',
667+
' let emission = _emissionMap.rgb * mapperUBO.Emission;',
668+
'',
669+
' // Material struct',
670+
' let mat = Material(ior, roughness, metallic, baseColor);',
671+
'',
647672
// Summing diffuse and specular components of directional lights
648673
' {',
649-
' var i: i32 = 0;',
674+
' var i = 0;',
650675
' loop {',
651-
' if !(i < rendererUBO.LightCount) { break; }',
676+
' if (!(i < rendererUBO.LightCount)) { break; }',
652677
' switch (i32(rendererLightSSBO.values[i].LightData.x)) {',
653678
' // Point Light',
654679
' case 0 {',
655-
' var color: vec3<f32> = rendererLightSSBO.values[i].LightColor.rgb * rendererLightSSBO.values[i].LightColor.w;',
656-
' var pos: vec3<f32> = (rendererLightSSBO.values[i].LightPos).xyz;',
657-
' var calculated: PBRData = calcPointLight(normal, V, fragPos, ior, roughness, metallic, pos, color, baseColor);',
658-
' diffuse += max(vec3<f32>(0), calculated.diffuse);',
659-
' specular += max(vec3<f32>(0), calculated.specular);',
680+
' let color = rendererLightSSBO.values[i].LightColor.rgb * rendererLightSSBO.values[i].LightColor.w;',
681+
' let pos = (rendererLightSSBO.values[i].LightPos).xyz;',
682+
' let pointLight = PointLight(pos, color);',
683+
' let result = calcPointLight(normal, V, fragPos, mat, pointLight);',
684+
' diffuse += max(vec3<f32>(0), result.diffuse);',
685+
' specular += max(vec3<f32>(0), result.specular);',
660686
' }',
661687
' // Directional light',
662688
' case 1 {',
663-
' var dir: vec3<f32> = (rendererUBO.WCVCNormals * vec4<f32>(normalize(rendererLightSSBO.values[i].LightDir.xyz), 0.)).xyz;',
664-
' dir = normalize(dir);',
665-
' var color: vec3<f32> = rendererLightSSBO.values[i].LightColor.rgb * rendererLightSSBO.values[i].LightColor.w;',
666-
' var calculated: PBRData = calcDirectionalLight(normal, V, ior, roughness, metallic, dir, color, baseColor); // diffuseColor.rgb needs to be fixed with a more dynamic diffuse color',
667-
' diffuse += max(vec3<f32>(0), calculated.diffuse);',
668-
' specular += max(vec3<f32>(0), calculated.specular);',
689+
' let dir = normalize((rendererUBO.WCVCNormals * vec4<f32>(normalize(rendererLightSSBO.values[i].LightDir.xyz), 0.)).xyz);',
690+
' let color = rendererLightSSBO.values[i].LightColor.rgb * rendererLightSSBO.values[i].LightColor.w;',
691+
' let dirLight = DirectionalLight(dir, color);',
692+
' let result = calcDirectionalLight(normal, V, mat, dirLight); // diffuseColor.rgb needs to be fixed with a more dynamic diffuse color',
693+
' diffuse += max(vec3<f32>(0), result.diffuse);',
694+
' specular += max(vec3<f32>(0), result.specular);',
669695
' }',
670696
' // Spot Light',
671697
' case 2 {',
672-
' var color: vec3<f32> = rendererLightSSBO.values[i].LightColor.rgb * rendererLightSSBO.values[i].LightColor.w;',
673-
' var pos: vec3<f32> = (rendererLightSSBO.values[i].LightPos).xyz;',
674-
' var dir: vec3<f32> = (rendererUBO.WCVCNormals * vec4<f32>(normalize(rendererLightSSBO.values[i].LightDir.xyz), 0.)).xyz;',
675-
' dir = normalize(dir);',
676-
' var cones: vec2<f32> = vec2<f32>(rendererLightSSBO.values[i].LightData.y, rendererLightSSBO.values[i].LightData.z);',
677-
' var calculated: PBRData = calcSpotLight(normal, V, fragPos, ior, roughness, metallic, pos, dir, cones, color, baseColor);',
678-
' diffuse += max(vec3<f32>(0), calculated.diffuse);',
679-
' specular += max(vec3<f32>(0), calculated.specular);',
698+
' let color = rendererLightSSBO.values[i].LightColor.rgb * rendererLightSSBO.values[i].LightColor.w;',
699+
' let pos = (rendererLightSSBO.values[i].LightPos).xyz;',
700+
' let dir = normalize((rendererUBO.WCVCNormals * vec4<f32>(normalize(rendererLightSSBO.values[i].LightDir.xyz), 0.)).xyz);',
701+
' let cones = vec2<f32>(rendererLightSSBO.values[i].LightData.y, rendererLightSSBO.values[i].LightData.z);',
702+
' let spotLight = SpotLight(pos, dir, cones, color);',
703+
' let result = calcSpotLight(normal, V, fragPos, mat, spotLight);',
704+
' diffuse += max(vec3<f32>(0), result.diffuse);',
705+
' specular += max(vec3<f32>(0), result.specular);',
680706
' }',
681707
' default { continue; }',
682708
' }',
683709
' continuing { i++; }',
684710
' }',
685711
' }',
686712
// Final variables for combining specular and diffuse
687-
' var fresnel: f32 = schlickFresnelIOR(V, normal, ior, k); // Fresnel',
688-
' fresnel = min(1.0, fresnel);',
713+
' let fresnel = min(1.0, schlickFresnelIOR(V, normal, ior, k)); // Fresnel',
689714
' // This could be controlled with its own variable (that isnt base color) for better artistic control',
690-
' var fresnelMetallic: vec3<f32> = schlickFresnelRGB(V, normal, baseColor); // Fresnel for metal, takes color into account',
691-
' var kS: vec3<f32> = mix(vec3<f32>(fresnel), fresnelMetallic, metallic);',
692-
' kS = min(vec3<f32>(1.0), kS);',
693-
' var kD: vec3<f32> = (1.0 - kS) * (1.0 - metallic);',
694-
' var PBR: vec3<f32> = mapperUBO.DiffuseIntensity*kD*diffuse + kS*specular;',
695-
' PBR += emission;',
696-
' computedColor = vec4<f32>(PBR, mapperUBO.Opacity);',
715+
' let fresnelMetallic = schlickFresnelRGB(V, normal, baseColor); // Fresnel for metal, takes color into account',
716+
' let kS = min(vec3<f32>(1.0), mix(vec3<f32>(fresnel), fresnelMetallic, metallic));',
717+
' let kD = (1.0 - kS) * (1.0 - metallic);',
718+
' let PBR = mapperUBO.DiffuseIntensity * kD * diffuse + kS * specular;',
719+
' computedColor = vec4<f32>(PBR + emission, mapperUBO.Opacity);',
697720
];
698721
if (renderer.getEnvironmentTexture()?.getImageLoaded()) {
699722
lightingCode.push(
700723
' // To get diffuse IBL, the texture is sampled with normals in worldspace',
701-
' var diffuseIBLCoords: vec3<f32> = (transpose(rendererUBO.WCVCNormals) * vec4<f32>(normal, 1.)).xyz;',
702-
' var diffuseCoords: vec2<f32> = vecToRectCoord(diffuseIBLCoords);',
724+
' let diffuseIBLCoords = (transpose(rendererUBO.WCVCNormals) * vec4<f32>(normal, 1.)).xyz;',
725+
' let diffuseCoords = vecToRectCoord(diffuseIBLCoords);',
703726
' // To get specular IBL, the texture is sampled as the worldspace reflection between the normal and view vectors',
704727
' // Reflections are first calculated in viewspace, then converted to worldspace to sample the environment',
705-
' var VreflN: vec3<f32> = normalize(reflect(-V, normal));',
706-
' var reflectionIBLCoords = (transpose(rendererUBO.WCVCNormals) * vec4<f32>(VreflN, 1.)).xyz;',
707-
' var specularCoords: vec2<f32> = vecToRectCoord(reflectionIBLCoords);',
708-
' var diffuseIBL = textureSampleLevel(EnvironmentTexture, EnvironmentTextureSampler, diffuseCoords, rendererUBO.MaxEnvironmentMipLevel);',
728+
' let VreflN = normalize(reflect(-V, normal));',
729+
' let reflectionIBLCoords = (transpose(rendererUBO.WCVCNormals) * vec4<f32>(VreflN, 1.)).xyz;',
730+
' let specularCoords = vecToRectCoord(reflectionIBLCoords);',
731+
' let diffuseIBL = textureSampleLevel(EnvironmentTexture, EnvironmentTextureSampler, diffuseCoords, rendererUBO.MaxEnvironmentMipLevel);',
709732
// Level multiplier should be set by UBO
710-
' var level = roughness * rendererUBO.MaxEnvironmentMipLevel;',
711-
' var specularIBL = textureSampleLevel(EnvironmentTexture, EnvironmentTextureSampler, specularCoords, level);', // Manual mip smoothing since not all formats support smooth level sampling
712-
' var specularIBLContribution: vec3<f32> = specularIBL.rgb*rendererUBO.BackgroundSpecularStrength;',
713-
' computedColor += vec4<f32>(specularIBLContribution*kS, 0);',
714-
' var diffuseIBLContribution: vec3<f32> = diffuseIBL.rgb*rendererUBO.BackgroundDiffuseStrength;',
715-
' diffuseIBLContribution *= baseColor * _ambientOcclusionMap.rgb;', // Multipy by baseColor may be changed
716-
' computedColor += vec4<f32>(diffuseIBLContribution*kD, 0);'
733+
' let level = roughness * rendererUBO.MaxEnvironmentMipLevel;',
734+
' let specularIBL = textureSampleLevel(EnvironmentTexture, EnvironmentTextureSampler, specularCoords, level);', // Manual mip smoothing since not all formats support smooth level sampling
735+
' let specularIBLContribution = specularIBL.rgb * rendererUBO.BackgroundSpecularStrength;',
736+
' computedColor += vec4<f32>(specularIBLContribution * kS, 0);',
737+
' let diffuseIBLContribution = diffuseIBL.rgb * rendererUBO.BackgroundDiffuseStrength;',
738+
' computedColor += vec4<f32>(diffuseIBLContribution * baseColor * _ambientOcclusionMap.rgb * kD, 0);'
717739
);
718740
}
719741
code = vtkWebGPUShaderCache.substitute(
@@ -725,8 +747,8 @@ function vtkWebGPUCellArrayMapper(publicAPI, model) {
725747
// If theres no normals, just set the specular color to be flat
726748
} else {
727749
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Light::Impl', [
728-
' var diffuse: vec3<f32> = diffuseColor.rgb;',
729-
' var specular: vec3<f32> = mapperUBO.SpecularColor.rgb * mapperUBO.SpecularColor.a;',
750+
' let diffuse = diffuseColor.rgb;',
751+
' let specular = mapperUBO.SpecularColor.rgb * mapperUBO.SpecularColor.a;',
730752
' computedColor = vec4<f32>(diffuse * _diffuseMap.rgb, mapperUBO.Opacity);',
731753
]).result;
732754
fDesc.setCode(code);

0 commit comments

Comments
 (0)