init
This commit is contained in:
83
assets/shaders/mesh.frag
Normal file
83
assets/shaders/mesh.frag
Normal file
@@ -0,0 +1,83 @@
|
||||
#version 450 core
|
||||
#include "common.glsl"
|
||||
// High-resolution 3D scenery (trees, bushes, rocks). Foliage uses wrap
|
||||
// lighting on its rounded custom normals plus sun translucency.
|
||||
|
||||
in VS {
|
||||
vec3 worldPos;
|
||||
vec3 normal;
|
||||
vec2 uv;
|
||||
vec3 color;
|
||||
float height;
|
||||
} v;
|
||||
|
||||
layout(binding = 0) uniform sampler2D uTex;
|
||||
uniform vec4 uBaseColor;
|
||||
uniform int uAlphaMask;
|
||||
uniform float uCutoff;
|
||||
uniform int uFoliage;
|
||||
uniform int uOccluderFade; // 1 in the main view: dither away scenery hiding the player
|
||||
uniform vec3 uEmissive; // linear HDR; multiplied by the emissive texture (unit 1)
|
||||
layout(binding = 1) uniform sampler2D uEmissiveTex;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec4 tex = texture(uTex, v.uv);
|
||||
if (uAlphaMask == 1) {
|
||||
// Sharpen alpha by its screen-space rate of change: keeps leaf coverage
|
||||
// stable through the mip chain instead of thinning out with distance.
|
||||
float a = (tex.a - uCutoff) / max(fwidth(tex.a), 1e-4) + 0.5;
|
||||
if (a < 0.5) discard;
|
||||
}
|
||||
if (uOccluderFade == 1 && uBlob.w > 0.0) {
|
||||
vec4 pc = uViewProj * vec4(uBlob.xyz + vec3(0.0, 0.6, 0.0), 1.0);
|
||||
vec2 ps = pc.xy / pc.w * 0.5 + 0.5;
|
||||
vec2 d = (gl_FragCoord.xy * uScreen.zw - ps) * vec2(uScreen.x * uScreen.w, 1.0);
|
||||
float fragDepth = (uViewProj * vec4(v.worldPos, 1.0)).w;
|
||||
float fade = (1.0 - smoothstep(0.07, 0.15, length(d))) * step(fragDepth, pc.w - 1.0);
|
||||
if (ign(gl_FragCoord.xy) < fade * 0.85) discard;
|
||||
}
|
||||
|
||||
vec3 wp = v.worldPos;
|
||||
vec3 n = normalize(v.normal);
|
||||
if (uFoliage == 0 && !gl_FrontFacing) n = -n;
|
||||
vec3 L = uSunDir.xyz;
|
||||
vec3 V = normalize(uCamPos.xyz - wp);
|
||||
vec3 albedo = tex.rgb * uBaseColor.rgb * v.color;
|
||||
float gao = groundAO(wp, v.height);
|
||||
|
||||
float ndl = dot(n, L);
|
||||
float diffuse = uFoliage == 1 ? clamp((ndl + 0.45) / 1.45, 0.0, 1.0) : max(ndl, 0.0);
|
||||
// Offset along the normal and toward the sun to avoid acne on thin cards.
|
||||
float vis = sunShadow(wp + n * 0.06 + L * 0.08) * canopyCookie(wp);
|
||||
if (uFoliage == 1) vis = mix(0.3, 1.0, vis); // light scatters through leaves: soft self-shadowing
|
||||
vec3 sunRad = uSunColor.rgb * uSunDir.w;
|
||||
|
||||
vec3 toCam = cross(uBillboardRight.xyz, vec3(0.0, 1.0, 0.0));
|
||||
vec3 amb = hemiAmbient(n) + uSkyHorizon.rgb * uSkyHorizon.w * max(dot(n, toCam), 0.0);
|
||||
vec3 light = sunRad * diffuse * vis * mix(1.0, gao, 0.7) + amb * gao + pointLights(wp, n);
|
||||
|
||||
if (uFoliage == 1) {
|
||||
// Backlit leaves glow; sunlit rims pick up a warm sheen.
|
||||
float back = pow(max(dot(-V, L), 0.0), 4.0);
|
||||
light += sunRad * back * vis * 0.35 * vec3(1.0, 1.05, 0.7);
|
||||
float rim = pow(1.0 - max(dot(n, V), 0.0), 3.0) * max(ndl, 0.0);
|
||||
light += sunRad * rim * vis * 0.25;
|
||||
} else {
|
||||
// Subtle sheen on rocks and bark.
|
||||
vec3 H = normalize(L + V);
|
||||
light += sunRad * pow(max(dot(n, H), 0.0), 24.0) * 0.06 * vis;
|
||||
}
|
||||
|
||||
vec3 sheen = vec3(0.0);
|
||||
if (uWeather.y > 0.0) albedo = wetSurface(albedo, n, V, vis, sheen);
|
||||
vec3 col = albedo * light + sheen * gao;
|
||||
col += texture(uEmissiveTex, v.uv).rgb * uEmissive;
|
||||
if (uBlob.w > 0.0) { // player's contact shadow
|
||||
float d = length(wp.xz - uBlob.xz) / uBlob.w;
|
||||
float near = 1.0 - smoothstep(0.0, 0.6, abs(wp.y - uBlob.y));
|
||||
col *= 1.0 - 0.4 * (1.0 - smoothstep(0.3, 1.0, d)) * near;
|
||||
}
|
||||
fragColor = vec4(col, 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user