aboutsummaryrefslogtreecommitdiff
path: root/apps/openmb/resources/shaders/textured_lit.frag
diff options
context:
space:
mode:
Diffstat (limited to 'apps/openmb/resources/shaders/textured_lit.frag')
-rw-r--r--apps/openmb/resources/shaders/textured_lit.frag121
1 files changed, 121 insertions, 0 deletions
diff --git a/apps/openmb/resources/shaders/textured_lit.frag b/apps/openmb/resources/shaders/textured_lit.frag
new file mode 100644
index 0000000..58c71f7
--- /dev/null
+++ b/apps/openmb/resources/shaders/textured_lit.frag
@@ -0,0 +1,121 @@
+#version 330 core
+
+in vec2 vUV;
+in vec3 vNormal;
+in vec3 vFragPos;
+in vec4 vFragPosLightSpace;
+out vec4 FragColor;
+
+uniform sampler2D albedo;
+uniform sampler2D normalMap;
+uniform int normalEnabled;
+uniform float normalStrength;
+uniform vec3 tint;
+uniform int radialEnabled;
+uniform float radialInner;
+uniform float radialOuter;
+
+struct DirectionalLight
+{
+ vec3 direction;
+ vec3 color;
+ float intensity;
+};
+
+uniform DirectionalLight dirLight;
+uniform vec3 ambientColor = vec3(0.15, 0.15, 0.15);
+uniform sampler2D shadowMap;
+uniform float shadowBiasMin;
+uniform float shadowBiasScale;
+uniform int pcfRadius;
+uniform sampler2D ssao;
+uniform float aoStrength;
+uniform float screenWidth;
+uniform float screenHeight;
+
+// Fog
+uniform vec3 cameraPos;
+uniform vec3 fogColor;
+uniform float fogDensity; // e.g. 0.02
+uniform float fogAmount; // 0..1 blend factor
+float ShadowCalculation(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir)
+{
+
+ vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
+
+ projCoords = projCoords * 0.5 + 0.5;
+
+ if (projCoords.z > 1.0)
+ return 0.0;
+
+
+ float currentDepth = projCoords.z;
+
+ float bias = max(shadowBiasScale * (1.0 - max(dot(normal, lightDir), 0.0)), shadowBiasMin);
+
+
+ ivec2 texSize = textureSize(shadowMap, 0);
+ vec2 texelSize = 1.0 / vec2(texSize);
+ float vis = 0.0;
+ int samples = 0;
+ for (int x = -pcfRadius; x <= pcfRadius; ++x)
+ {
+ for (int y = -pcfRadius; y <= pcfRadius; ++y)
+ {
+ vec2 offset = vec2(x, y) * texelSize;
+ float depthSample = texture(shadowMap, projCoords.xy + offset).r;
+ // texture returns stored light-space depth. If our fragment's depth (minus bias)
+ // is less than or equal to the sampled depth, it's visible to the light.
+ vis += (currentDepth - bias <= depthSample) ? 1.0 : 0.0;
+ samples++;
+ }
+ }
+ float visibility = vis / float(samples);
+ float shadow = 1.0 - visibility;
+ return shadow;
+}
+
+void main()
+{
+ vec4 tex = texture(albedo, vUV);
+ vec3 color = tex.rgb * tint;
+ float alpha = tex.a;
+ vec3 finalNormal = vec3(0.0, 0.0, 1.0);
+ if (normalEnabled == 1)
+ {
+ vec3 n = texture(normalMap, vUV).rgb;
+ n = n * 2.0 - 1.0;
+ finalNormal = normalize(vec3(n.x * normalStrength, n.y * normalStrength, 1.0));
+ }
+ if (radialEnabled == 1)
+ {
+ float dist = distance(vUV, vec2(0.5, 0.5));
+ float mask = 1.0 - smoothstep(radialInner, radialOuter, dist);
+ alpha *= mask;
+ }
+
+
+ vec3 N = normalize(finalNormal);
+ vec3 L = normalize(dirLight.direction);
+ float diff = max(dot(N, L), 0.0);
+ vec3 diffuse = dirLight.color * dirLight.intensity * diff;
+
+ float shadow = ShadowCalculation(vFragPosLightSpace, N, L);
+ float shadowFactor = 1.0 - shadow * 0.9;
+ float ao = 1.0;
+ if (aoStrength > 0.0)
+ {
+ vec2 ssaoUV = gl_FragCoord.xy / vec2(screenWidth, screenHeight);
+ ao = texture(ssao, ssaoUV).r;
+ }
+ float aoFactor = mix(1.0, ao, aoStrength);
+ vec3 result = color * (ambientColor * aoFactor + diffuse * shadowFactor);
+
+ // Compute fog based on distance from camera
+ float dist = length(vFragPos - cameraPos);
+ float fogFactor = 1.0 - exp(-fogDensity * dist);
+ fogFactor = clamp(fogFactor * fogAmount, 0.0, 1.0);
+ vec3 finalColor = mix(result, fogColor, fogFactor);
+
+ FragColor = vec4(finalColor, alpha);
+}