Skip to content

Commit

Permalink
Introduce additional terrain shaders (#4902)
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackYps committed May 21, 2023
1 parent 910a580 commit b5b2d78
Show file tree
Hide file tree
Showing 2 changed files with 492 additions and 259 deletions.
74 changes: 55 additions & 19 deletions effects/mesh.fx
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,16 @@ sampler2D falloffSampler = sampler_state
AddressV = CLAMP;
};

sampler WaterRampSampler = sampler_state
{
Texture = (waterRamp);
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
};

///////////////////////////////////////
///
/// Structures
Expand Down Expand Up @@ -9155,7 +9165,7 @@ float GeometrySmith(float3 n, float3 v, float3 l, float roughness)
return gs1 * gs2;
}

float4 PBR_PS(
float3 PBR_PS(
NORMALMAPPED_VERTEX vertex,
float3 albedo,
float metallic,
Expand Down Expand Up @@ -9196,6 +9206,11 @@ float4 PBR_PS(
//////////////////////////////
// Compute sun light
//

// specular reflections of dielectrics mostly disappear underwater
if (vertex.depth.x < 0) {
facingSpecular = facingSpecular * 0.05;
}
float3 F0 = lerp(float3(facingSpecular, facingSpecular, facingSpecular), albedo, metallic);
float3 l = sunDirection;
float3 h = normalize(v + l);
Expand Down Expand Up @@ -9248,7 +9263,27 @@ float4 PBR_PS(
float3 specular = env_reflection * (kS * envBRDFlookuptexture.r + envBRDFlookuptexture.g);
color += (kD * diffuse + specular) * ao;

return float4(color, 0);
return color;
}

float3 ApplyWaterColor(NORMALMAPPED_VERTEX vertex, float3 color, float3 emission) {
float4 waterColor = tex1D(WaterRampSampler, -vertex.depth.x / (surfaceElevation - abyssElevation));
float3 v = normalize(vertex.viewDirection);
float3 up = float3(0,1,0);
// To simplify, we assume that the light enters vertically into the water,
// this is the length that the light travels underwater back to the camera
float oneOverCosV = 1 / max(dot(up, v), 0.0001);
// light gets absorbed exponentially
float waterAbsorption = saturate(exp(-waterColor.w * (1 + oneOverCosV)));
// when the mesh emits light, then the path from the surface to the mesh doesn't apply
float emissionAbsorption = saturate(exp(-waterColor.w * oneOverCosV));
// darken the color first to simulate the light absorption on the way in and out
color *= waterAbsorption;
// lerp in the watercolor to simulate the scattered light from the dirty water
color = lerp(waterColor.rgb, color, waterAbsorption);
// similarly tune down the emission light
color += emission * emissionAbsorption;
return color;
}

float4 PBR_UEF(NORMALMAPPED_VERTEX vertex, float teamColorFactor, uniform bool hiDefShadows) : COLOR0
Expand Down Expand Up @@ -9276,15 +9311,15 @@ float4 PBR_UEF(NORMALMAPPED_VERTEX vertex, float teamColorFactor, uniform bool h
roughness += planeCockpitMask - specular.b * 3;
roughness = saturate(1 - roughness);

float4 color = PBR_PS(vertex, albedo.rgb, metallic, roughness, normal, hiDefShadows, .04, ao);

float3 color = PBR_PS(vertex, albedo.rgb, metallic, roughness, normal, hiDefShadows, .04, ao);
float emission = specular.b * 0.8;
color += emission * albedo;
color = ApplyWaterColor(vertex, color, emission * albedo);

// The glowminimum is required to make the unit behave properly with the water shader.
// If the alpha channel is 0 somewhere, those parts will show as water refractions even
// if they are above the water line. See https://github.com/FAForever/fa/issues/4696
float alphaGlow = mirrored ? 0.5 : emission + glowMinimum;
return float4(color.rgb, alphaGlow);
return float4(color, alphaGlow);
}

float4 PBR_UEF_PS(NORMALMAPPED_VERTEX vertex,
Expand Down Expand Up @@ -9352,10 +9387,10 @@ float4 PBR_Aeon(NORMALMAPPED_VERTEX vertex, float teamColorFactor, uniform bool
float specularAmount = lerp(0.08, 0, darkAreas);
specularAmount = lerp(specularAmount, 0.04, fullTeamColor);

float3 color = PBR_PS(vertex, albedo, metallic, roughness, normal, hiDefShadows, specularAmount).rgb;

float3 color = PBR_PS(vertex, albedo, metallic, roughness, normal, hiDefShadows, specularAmount);
float3 emission = specular.b + specular.a * vertex.color.rgb * 0.5;
color += emission;
color = ApplyWaterColor(vertex, color, emission);

float alpha = mirrored ? 0.5 : specular.b + glowMinimum + specular.a * 0.13;

return float4(color, alpha);
Expand Down Expand Up @@ -9389,7 +9424,7 @@ float4 PBR_AeonBuildPuddlePS(NORMALMAPPED_VERTEX vertex, uniform bool hiDefShado
float metallic = 1;
float roughness = specular.g;

float3 color = PBR_PS(vertex, albedo, metallic, roughness, normal, hiDefShadows).rgb;
float3 color = PBR_PS(vertex, albedo, metallic, roughness, normal, hiDefShadows);

float alpha = mirrored ? 0.5 : specular.b + glowMinimum;

Expand Down Expand Up @@ -9422,7 +9457,7 @@ float4 PBR_AeonBuildOverlayPS( NORMALMAPPED_VERTEX vertex) : COLOR0

float metallic = 1;
float roughness = 0.15;
float3 color = PBR_PS(vertex, diffuse, metallic, roughness, normal, true).rgb;
float3 color = PBR_PS(vertex, diffuse, metallic, roughness, normal, true);

// Fade out 95% complete
float percentComplete = vertex.material.y;
Expand Down Expand Up @@ -9464,7 +9499,7 @@ float4 PBR_AeonCZARPS( NORMALMAPPED_VERTEX vertex, uniform bool hiDefShadows) :
float specularAmount = lerp(0.08, 0, darkAreas);
specularAmount = lerp(specularAmount, 0.04, saturate(specular.a * 3));

float3 color = PBR_PS(vertex, albedo.rgb, metallic, roughness, normal, hiDefShadows, specularAmount).rgb;
float3 color = PBR_PS(vertex, albedo.rgb, metallic, roughness, normal, hiDefShadows, specularAmount);

float emission = specular.b + (pow(specular.a, 2) * 0.13);
color += emission * albedo.rgb;
Expand Down Expand Up @@ -9498,13 +9533,13 @@ float4 PBR_Cybran(NORMALMAPPED_VERTEX vertex, float teamColorFactor, uniform boo
albedo.rgb = min(lerp(albedo.rgb, albedo.rgb * 2.3, pow(metallic, 2.5)), float3(1, 1, 1));
albedo.rgb = lerp(albedo.rgb, vertex.color.rgb, teamColorFactor * specular.a);

float4 color = PBR_PS(vertex, albedo.rgb, metallic, roughness, normal, hiDefShadows);

float3 color = PBR_PS(vertex, albedo.rgb, metallic, roughness, normal, hiDefShadows);
float emission = pow(max(specular.b - 0.04, 0.0), 0.5);
color += emission * albedo;
color = ApplyWaterColor(vertex, color, emission * albedo);

float alpha = mirrored ? 0.5 : emission + glowMinimum;

return float4(color.rgb, alpha);
return float4(color, alpha);
}

float4 PBR_CybranPS(NORMALMAPPED_VERTEX vertex, uniform bool hiDefShadows) : COLOR0
Expand Down Expand Up @@ -9543,17 +9578,18 @@ float4 PBR_Seraphim(

float metallic = 1;
float roughness = saturate((1 - pow(specular.g, 0.5) + 0.3) * 0.7);
float3 color = PBR_PS(vertex, albedo.rgb, metallic, roughness, normal, hiDefShadows).rgb;

float3 color = PBR_PS(vertex, albedo.rgb, metallic, roughness, normal, hiDefShadows);
color = lerp(color, teamColor * 0.5, albedo.a - 0.2);

float3 emission = saturate(specular.b - 0.1) + teamColor * albedo.a + whiteness * 1.5;
color += emission * albedo;

// Substitute all the computations on pure glowing parts with the
// pure brightness texture to get rid of reflections and shadows
float mask = saturate(saturate(specular.b * 2) - albedo.a);
color = lerp(color, specular.b * 2, mask);

color = ApplyWaterColor(vertex, color, emission * albedo);

// Bloom is only rendered where alpha > 0
float teamColorGlow = (vertex.color.r + vertex.color.g + vertex.color.b) / 3;
teamColorGlow = albedo.a * (1 - teamColorGlow) * 0.06;
Expand Down
Loading

0 comments on commit b5b2d78

Please sign in to comment.