Skip to content

Commit

Permalink
Update TerrainGeometryShader.wgsl
Browse files Browse the repository at this point in the history
TBD: Texture blending stages work differently in DirectX?
  • Loading branch information
rdw-software committed Feb 7, 2024
1 parent 9aa1583 commit 9992322
Showing 1 changed file with 28 additions and 23 deletions.
51 changes: 28 additions & 23 deletions Core/NativeClient/WebGPU/Shaders/TerrainGeometryShader.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -135,42 +135,47 @@ fn vs_main(in: VertexInput) -> VertexOutput {
return out;
}

// Magenta background pixels should be discarded (but pre-processing on the CPU is expensive)
fn isTransparentBackgroundPixel(diffuseTextureColor : vec4f) -> bool {
return (diffuseTextureColor.r >= 254/255 && diffuseTextureColor.g <= 3/255 && diffuseTextureColor.b >= 254/255);
fn isTransparentBackgroundPixel(diffuseTextureColor : vec4<f32>) -> bool {
return (diffuseTextureColor.r >= 254.0/255.0 && diffuseTextureColor.g <= 3.0/255.0 && diffuseTextureColor.b >= 254.0/255.0);
}

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
let textureCoords = in.diffuseTextureCoords;
var diffuseTextureColor = textureSample(diffuseTexture, diffuseTextureSampler, textureCoords);

if (isTransparentBackgroundPixel(diffuseTextureColor)) {
discard;
}

diffuseTextureColor.r *= in.color.r;
diffuseTextureColor.g *= in.color.g;
diffuseTextureColor.b *= in.color.b;
// diffuseTextureColor.a *= in.color.a;

let normal = normalize(in.surfaceNormal);
let sunlightColor = uPerSceneData.directionalLightColor.rgb;
let ambientColor = uPerSceneData.ambientLight.rgb;

if (isTransparentBackgroundPixel(diffuseTextureColor)) {
diffuseTextureColor.a = 0.0;
}
let sunlightRayOrigin = -normalize(uPerSceneData.directionalLightDirection.xyz);
let sunlightColorContribution = max(dot(sunlightRayOrigin, normal), 0.0);
let directionalLightColor = sunlightColorContribution * sunlightColor;
let combinedLightContribution = clampToUnitRange(directionalLightColor + ambientColor);

let lightmapTexCoords = in.lightmapTextureCoords;
var lightmapTextureColor = textureSample(lightmapTexture, lightmapTextureSampler, lightmapTexCoords);

// Simulated fixed-function pipeline (DirectX7/9) - no specular highlights needed AFAICT?
let sunlightRayOrigin = -normalize(uPerSceneData.directionalLightDirection.xyz);
let sunlightColorContribution = max(dot(sunlightRayOrigin, normal), 0.0);
let directionalLightColor = sunlightColorContribution * sunlightColor;
let combinedLightContribution = clampToUnitRange(directionalLightColor + ambientColor) * lightmapTextureColor.a;
diffuseTextureColor.r = (diffuseTextureColor.r * lightmapTextureColor.a) + lightmapTextureColor.r;
diffuseTextureColor.g = (diffuseTextureColor.g * lightmapTextureColor.a) + lightmapTextureColor.g;
diffuseTextureColor.b = (diffuseTextureColor.b * lightmapTextureColor.a) + lightmapTextureColor.b;

var finalColor = diffuseTextureColor.rgb * combinedLightContribution;

// Screen blending increases the vibrancy of colors (see https://en.wikipedia.org/wiki/Blend_modes#Screen)
let contrastCorrectionColor = clampToUnitRange(ambientColor + sunlightColor - (sunlightColor * ambientColor));
let fragmentColor = clampToUnitRange(in.color * contrastCorrectionColor * combinedLightContribution * diffuseTextureColor.rgb + lightmapTextureColor.rgb);
finalColor = clampToUnitRange(finalColor * contrastCorrectionColor + lightmapTextureColor.rgb);

// Should be a no-op if fog is disabled, since the fogFactor would be zero
let foggedColor = mix(fragmentColor.rgb, uPerSceneData.fogColor.rgb, in.fogFactor);
let foggedColor = mix(finalColor, uPerSceneData.fogColor.rgb, in.fogFactor);

// Gamma-correction:
// WebGPU assumes that the colors output by the fragment shader are given in linear space
// When setting the surface format to BGRA8UnormSrgb it performs a linear to sRGB conversion
let gammaCorrectedColor = pow(foggedColor.rgb, vec3f(2.2));
return vec4f(gammaCorrectedColor, diffuseTextureColor.a + DEBUG_ALPHA_OFFSET);
}
let gammaCorrectedColor = pow(foggedColor, vec3<f32>(2.2));

return vec4<f32>(gammaCorrectedColor, diffuseTextureColor.a);
}

0 comments on commit 9992322

Please sign in to comment.