forked from Mirrorlandia_minetest/minetest
Copy shadow mapping shader from nodes to objects
This commit is contained in:
parent
4e39cdef94
commit
10be033791
@ -1,6 +1,7 @@
|
|||||||
uniform sampler2D baseTexture;
|
uniform sampler2D baseTexture;
|
||||||
|
|
||||||
uniform vec4 emissiveColor;
|
uniform vec4 emissiveColor;
|
||||||
|
uniform vec3 dayLight;
|
||||||
uniform vec4 skyBgColor;
|
uniform vec4 skyBgColor;
|
||||||
uniform float fogDistance;
|
uniform float fogDistance;
|
||||||
uniform vec3 eyePosition;
|
uniform vec3 eyePosition;
|
||||||
@ -16,6 +17,8 @@ centroid varying vec2 varTexCoord;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
varying vec3 eyeVec;
|
varying vec3 eyeVec;
|
||||||
|
varying float nightRatio;
|
||||||
|
|
||||||
varying float vIDiff;
|
varying float vIDiff;
|
||||||
|
|
||||||
const float e = 2.718281828459;
|
const float e = 2.718281828459;
|
||||||
@ -31,53 +34,23 @@ const float fogShadingParameter = 1.0 / (1.0 - fogStart);
|
|||||||
uniform float f_textureresolution;
|
uniform float f_textureresolution;
|
||||||
uniform mat4 m_ShadowViewProj;
|
uniform mat4 m_ShadowViewProj;
|
||||||
uniform float f_shadowfar;
|
uniform float f_shadowfar;
|
||||||
uniform float f_timeofday;
|
|
||||||
varying float normalOffsetScale;
|
varying float normalOffsetScale;
|
||||||
varying float adj_shadow_strength;
|
varying float adj_shadow_strength;
|
||||||
varying float cosLight;
|
varying float cosLight;
|
||||||
varying float f_normal_length;
|
varying float f_normal_length;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLE_TONE_MAPPING
|
|
||||||
/* Hable's UC2 Tone mapping parameters
|
|
||||||
A = 0.22;
|
|
||||||
B = 0.30;
|
|
||||||
C = 0.10;
|
|
||||||
D = 0.20;
|
|
||||||
E = 0.01;
|
|
||||||
F = 0.30;
|
|
||||||
W = 11.2;
|
|
||||||
equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
|
|
||||||
*/
|
|
||||||
|
|
||||||
vec3 uncharted2Tonemap(vec3 x)
|
|
||||||
{
|
|
||||||
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 applyToneMapping(vec4 color)
|
|
||||||
{
|
|
||||||
color = vec4(pow(color.rgb, vec3(2.2)), color.a);
|
|
||||||
const float gamma = 1.6;
|
|
||||||
const float exposureBias = 5.5;
|
|
||||||
color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
|
|
||||||
// Precalculated white_scale from
|
|
||||||
//vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
|
||||||
vec3 whiteScale = vec3(1.036015346);
|
|
||||||
color.rgb *= whiteScale;
|
|
||||||
return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||||
const float bias0 = 0.9;
|
const float bias0 = 0.9;
|
||||||
const float zPersFactor = 0.5;
|
const float zPersFactor = 0.5;
|
||||||
const float bias1 = 1.0 - bias0;
|
const float bias1 = 1.0 - bias0 + 1e-6;
|
||||||
|
|
||||||
vec4 getPerspectiveFactor(in vec4 shadowPosition)
|
vec4 getPerspectiveFactor(in vec4 shadowPosition)
|
||||||
{
|
{
|
||||||
|
|
||||||
float pDistance = length(shadowPosition.xy);
|
float pDistance = length(shadowPosition.xy);
|
||||||
float pFactor = pDistance * bias0 + bias1;
|
float pFactor = pDistance * bias0 + bias1;
|
||||||
|
|
||||||
shadowPosition.xyz *= vec3(vec2(1.0 / pFactor), zPersFactor);
|
shadowPosition.xyz *= vec3(vec2(1.0 / pFactor), zPersFactor);
|
||||||
|
|
||||||
return shadowPosition;
|
return shadowPosition;
|
||||||
@ -92,11 +65,23 @@ float getLinearDepth()
|
|||||||
vec3 getLightSpacePosition()
|
vec3 getLightSpacePosition()
|
||||||
{
|
{
|
||||||
vec4 pLightSpace;
|
vec4 pLightSpace;
|
||||||
float normalBias = 0.0005 * getLinearDepth() * cosLight + normalOffsetScale;
|
// some drawtypes have zero normals, so we need to handle it :(
|
||||||
pLightSpace = m_ShadowViewProj * vec4(worldPosition + normalBias * normalize(vNormal), 1.0);
|
#if DRAW_TYPE == NDT_PLANTLIKE
|
||||||
|
pLightSpace = m_ShadowViewProj * vec4(worldPosition, 1.0);
|
||||||
|
#else
|
||||||
|
float offsetScale = (0.0057 * getLinearDepth() + normalOffsetScale);
|
||||||
|
pLightSpace = m_ShadowViewProj * vec4(worldPosition + offsetScale * normalize(vNormal), 1.0);
|
||||||
|
#endif
|
||||||
pLightSpace = getPerspectiveFactor(pLightSpace);
|
pLightSpace = getPerspectiveFactor(pLightSpace);
|
||||||
return pLightSpace.xyz * 0.5 + 0.5;
|
return pLightSpace.xyz * 0.5 + 0.5;
|
||||||
}
|
}
|
||||||
|
// custom smoothstep implementation because it's not defined in glsl1.2
|
||||||
|
// https://docs.gl/sl4/smoothstep
|
||||||
|
float mtsmoothstep(in float edge0, in float edge1, in float x)
|
||||||
|
{
|
||||||
|
float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
|
||||||
|
return t * t * (3.0 - 2.0 * t);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef COLORED_SHADOWS
|
#ifdef COLORED_SHADOWS
|
||||||
|
|
||||||
@ -124,10 +109,10 @@ vec4 getHardShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDist
|
|||||||
{
|
{
|
||||||
vec4 texDepth = texture2D(shadowsampler, smTexCoord.xy).rgba;
|
vec4 texDepth = texture2D(shadowsampler, smTexCoord.xy).rgba;
|
||||||
|
|
||||||
float visibility = step(0.0, (realDistance-2e-5) - texDepth.r);
|
float visibility = step(0.0, realDistance - texDepth.r);
|
||||||
vec4 result = vec4(visibility, vec3(0.0,0.0,0.0));//unpackColor(texDepth.g));
|
vec4 result = vec4(visibility, vec3(0.0,0.0,0.0));//unpackColor(texDepth.g));
|
||||||
if (visibility < 0.1) {
|
if (visibility < 0.1) {
|
||||||
visibility = step(0.0, (realDistance-2e-5) - texDepth.r);
|
visibility = step(0.0, realDistance - texDepth.b);
|
||||||
result = vec4(visibility, unpackColor(texDepth.a));
|
result = vec4(visibility, unpackColor(texDepth.a));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -138,13 +123,13 @@ vec4 getHardShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDist
|
|||||||
float getHardShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
|
float getHardShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
|
||||||
{
|
{
|
||||||
float texDepth = texture2D(shadowsampler, smTexCoord.xy).r;
|
float texDepth = texture2D(shadowsampler, smTexCoord.xy).r;
|
||||||
float visibility = step(0.0, (realDistance-2e-5) - texDepth);
|
float visibility = step(0.0, realDistance - texDepth);
|
||||||
|
|
||||||
return visibility;
|
return visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if SHADOW_FILTER == 2
|
#if SHADOW_FILTER == 2
|
||||||
#define PCFBOUND 3.5
|
#define PCFBOUND 3.5
|
||||||
#define PCFSAMPLES 64.0
|
#define PCFSAMPLES 64.0
|
||||||
@ -163,6 +148,73 @@ float getHardShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance
|
|||||||
#define PCFSAMPLES 1.0
|
#define PCFSAMPLES 1.0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef COLORED_SHADOWS
|
||||||
|
float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
|
||||||
|
{
|
||||||
|
vec4 texDepth = texture2D(shadowsampler, smTexCoord.xy);
|
||||||
|
float depth = max(realDistance - texDepth.r, realDistance - texDepth.b);
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
|
||||||
|
{
|
||||||
|
float texDepth = texture2D(shadowsampler, smTexCoord.xy).r;
|
||||||
|
float depth = realDistance - texDepth;
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float getBaseLength(vec2 smTexCoord)
|
||||||
|
{
|
||||||
|
float l = length(2.0 * smTexCoord.xy - 1.0); // length in texture coords
|
||||||
|
return bias1 / (1.0 / l - bias0); // return to undistorted coords
|
||||||
|
}
|
||||||
|
|
||||||
|
float getDeltaPerspectiveFactor(float l)
|
||||||
|
{
|
||||||
|
return 0.1 / (bias0 * l + bias1); // original distortion factor, divided by 10
|
||||||
|
}
|
||||||
|
|
||||||
|
float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDistance, float multiplier)
|
||||||
|
{
|
||||||
|
float baseLength = getBaseLength(smTexCoord);
|
||||||
|
float perspectiveFactor;
|
||||||
|
|
||||||
|
// Return fast if sharp shadows are requested
|
||||||
|
if (SOFTSHADOWRADIUS <= 1.0) {
|
||||||
|
perspectiveFactor = getDeltaPerspectiveFactor(baseLength);
|
||||||
|
return max(2 * length(smTexCoord.xy) * 2048 / f_textureresolution / pow(perspectiveFactor, 3), SOFTSHADOWRADIUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 clampedpos;
|
||||||
|
float texture_size = 1.0 / (2048 /*f_textureresolution*/ * 0.5);
|
||||||
|
float y, x;
|
||||||
|
float depth = 0.0;
|
||||||
|
float pointDepth;
|
||||||
|
float maxRadius = SOFTSHADOWRADIUS * 5.0 * multiplier;
|
||||||
|
|
||||||
|
float bound = clamp(PCFBOUND * (1 - baseLength), 0.0, PCFBOUND);
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
for (y = -bound; y <= bound; y += 1.0)
|
||||||
|
for (x = -bound; x <= bound; x += 1.0) {
|
||||||
|
clampedpos = vec2(x,y);
|
||||||
|
perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * maxRadius);
|
||||||
|
clampedpos = clampedpos * texture_size * perspectiveFactor * maxRadius * perspectiveFactor + smTexCoord.xy;
|
||||||
|
|
||||||
|
pointDepth = getHardShadowDepth(shadowsampler, clampedpos.xy, realDistance);
|
||||||
|
if (pointDepth > -0.01) {
|
||||||
|
depth += pointDepth;
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
depth = depth / n;
|
||||||
|
depth = pow(clamp(depth, 0.0, 1000.0), 1.6) / 0.001;
|
||||||
|
|
||||||
|
perspectiveFactor = getDeltaPerspectiveFactor(baseLength);
|
||||||
|
return max(length(smTexCoord.xy) * 2 * 2048 / f_textureresolution / pow(perspectiveFactor, 3), depth * maxRadius);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef POISSON_FILTER
|
#ifdef POISSON_FILTER
|
||||||
const vec2[64] poissonDisk = vec2[64](
|
const vec2[64] poissonDisk = vec2[64](
|
||||||
@ -238,17 +290,28 @@ vec4 getShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDistance
|
|||||||
{
|
{
|
||||||
vec2 clampedpos;
|
vec2 clampedpos;
|
||||||
vec4 visibility = vec4(0.0);
|
vec4 visibility = vec4(0.0);
|
||||||
|
float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance, 1.5); // scale to align with PCF
|
||||||
|
if (radius < 0.1) {
|
||||||
|
// we are in the middle of even brightness, no need for filtering
|
||||||
|
return getHardShadowColor(shadowsampler, smTexCoord.xy, realDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
float baseLength = getBaseLength(smTexCoord);
|
||||||
|
float perspectiveFactor;
|
||||||
|
|
||||||
float texture_size = 1.0 / (f_textureresolution * 0.5);
|
float texture_size = 1.0 / (f_textureresolution * 0.5);
|
||||||
int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-PCFSAMPLES)));
|
int samples = int(clamp(PCFSAMPLES * (1 - baseLength) * (1 - baseLength), PCFSAMPLES / 4, PCFSAMPLES));
|
||||||
int end_offset = int(PCFSAMPLES) + init_offset;
|
int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-samples)));
|
||||||
|
int end_offset = int(samples) + init_offset;
|
||||||
|
|
||||||
for (int x = init_offset; x < end_offset; x++) {
|
for (int x = init_offset; x < end_offset; x++) {
|
||||||
clampedpos = poissonDisk[x] * texture_size * SOFTSHADOWRADIUS + smTexCoord.xy;
|
clampedpos = poissonDisk[x];
|
||||||
|
perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * radius);
|
||||||
|
clampedpos = clampedpos * texture_size * perspectiveFactor * radius * perspectiveFactor + smTexCoord.xy;
|
||||||
visibility += getHardShadowColor(shadowsampler, clampedpos.xy, realDistance);
|
visibility += getHardShadowColor(shadowsampler, clampedpos.xy, realDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return visibility / PCFSAMPLES;
|
return visibility / samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -257,17 +320,28 @@ float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
|
|||||||
{
|
{
|
||||||
vec2 clampedpos;
|
vec2 clampedpos;
|
||||||
float visibility = 0.0;
|
float visibility = 0.0;
|
||||||
|
float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance, 1.5); // scale to align with PCF
|
||||||
|
if (radius < 0.1) {
|
||||||
|
// we are in the middle of even brightness, no need for filtering
|
||||||
|
return getHardShadow(shadowsampler, smTexCoord.xy, realDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
float baseLength = getBaseLength(smTexCoord);
|
||||||
|
float perspectiveFactor;
|
||||||
|
|
||||||
float texture_size = 1.0 / (f_textureresolution * 0.5);
|
float texture_size = 1.0 / (f_textureresolution * 0.5);
|
||||||
int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-PCFSAMPLES)));
|
int samples = int(clamp(PCFSAMPLES * (1 - baseLength) * (1 - baseLength), PCFSAMPLES / 4, PCFSAMPLES));
|
||||||
int end_offset = int(PCFSAMPLES) + init_offset;
|
int init_offset = int(floor(mod(((smTexCoord.x * 34.0) + 1.0) * smTexCoord.y, 64.0-samples)));
|
||||||
|
int end_offset = int(samples) + init_offset;
|
||||||
|
|
||||||
for (int x = init_offset; x < end_offset; x++) {
|
for (int x = init_offset; x < end_offset; x++) {
|
||||||
clampedpos = poissonDisk[x] * texture_size * SOFTSHADOWRADIUS + smTexCoord.xy;
|
clampedpos = poissonDisk[x];
|
||||||
|
perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * radius);
|
||||||
|
clampedpos = clampedpos * texture_size * perspectiveFactor * radius * perspectiveFactor + smTexCoord.xy;
|
||||||
visibility += getHardShadow(shadowsampler, clampedpos.xy, realDistance);
|
visibility += getHardShadow(shadowsampler, clampedpos.xy, realDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return visibility / PCFSAMPLES;
|
return visibility / samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -281,19 +355,31 @@ vec4 getShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDistance
|
|||||||
{
|
{
|
||||||
vec2 clampedpos;
|
vec2 clampedpos;
|
||||||
vec4 visibility = vec4(0.0);
|
vec4 visibility = vec4(0.0);
|
||||||
float sradius=0.0;
|
float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance, 1.0);
|
||||||
if( PCFBOUND>0)
|
if (radius < 0.1) {
|
||||||
sradius = SOFTSHADOWRADIUS / PCFBOUND;
|
// we are in the middle of even brightness, no need for filtering
|
||||||
float texture_size = 1.0 / (f_textureresolution * 0.5);
|
return getHardShadowColor(shadowsampler, smTexCoord.xy, realDistance);
|
||||||
float y, x;
|
|
||||||
// basic PCF filter
|
|
||||||
for (y = -PCFBOUND; y <= PCFBOUND; y += 1.0)
|
|
||||||
for (x = -PCFBOUND; x <= PCFBOUND; x += 1.0) {
|
|
||||||
clampedpos = vec2(x,y) * texture_size* sradius + smTexCoord.xy;
|
|
||||||
visibility += getHardShadowColor(shadowsampler, clampedpos.xy, realDistance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return visibility / PCFSAMPLES;
|
float baseLength = getBaseLength(smTexCoord);
|
||||||
|
float perspectiveFactor;
|
||||||
|
|
||||||
|
float texture_size = 1.0 / (f_textureresolution * 0.5);
|
||||||
|
float y, x;
|
||||||
|
float bound = clamp(PCFBOUND * (1 - baseLength), PCFBOUND / 2, PCFBOUND);
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
// basic PCF filter
|
||||||
|
for (y = -bound; y <= bound; y += 1.0)
|
||||||
|
for (x = -bound; x <= bound; x += 1.0) {
|
||||||
|
clampedpos = vec2(x,y); // screen offset
|
||||||
|
perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * radius / bound);
|
||||||
|
clampedpos = clampedpos * texture_size * perspectiveFactor * radius * perspectiveFactor / bound + smTexCoord.xy; // both dx,dy and radius are adjusted
|
||||||
|
visibility += getHardShadowColor(shadowsampler, clampedpos.xy, realDistance);
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return visibility / n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -301,20 +387,31 @@ float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
|
|||||||
{
|
{
|
||||||
vec2 clampedpos;
|
vec2 clampedpos;
|
||||||
float visibility = 0.0;
|
float visibility = 0.0;
|
||||||
float sradius=0.0;
|
float radius = getPenumbraRadius(shadowsampler, smTexCoord, realDistance, 1.0);
|
||||||
if( PCFBOUND>0)
|
if (radius < 0.1) {
|
||||||
sradius = SOFTSHADOWRADIUS / PCFBOUND;
|
// we are in the middle of even brightness, no need for filtering
|
||||||
|
return getHardShadow(shadowsampler, smTexCoord.xy, realDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
float baseLength = getBaseLength(smTexCoord);
|
||||||
|
float perspectiveFactor;
|
||||||
|
|
||||||
float texture_size = 1.0 / (f_textureresolution * 0.5);
|
float texture_size = 1.0 / (f_textureresolution * 0.5);
|
||||||
float y, x;
|
float y, x;
|
||||||
|
float bound = clamp(PCFBOUND * (1 - baseLength), PCFBOUND / 2, PCFBOUND);
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
// basic PCF filter
|
// basic PCF filter
|
||||||
for (y = -PCFBOUND; y <= PCFBOUND; y += 1.0)
|
for (y = -bound; y <= bound; y += 1.0)
|
||||||
for (x = -PCFBOUND; x <= PCFBOUND; x += 1.0) {
|
for (x = -bound; x <= bound; x += 1.0) {
|
||||||
clampedpos = vec2(x,y) * texture_size * sradius + smTexCoord.xy;
|
clampedpos = vec2(x,y); // screen offset
|
||||||
|
perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * radius / bound);
|
||||||
|
clampedpos = clampedpos * texture_size * perspectiveFactor * radius * perspectiveFactor / bound + smTexCoord.xy; // both dx,dy and radius are adjusted
|
||||||
visibility += getHardShadow(shadowsampler, clampedpos.xy, realDistance);
|
visibility += getHardShadow(shadowsampler, clampedpos.xy, realDistance);
|
||||||
|
n += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return visibility / PCFSAMPLES;
|
return visibility / n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -322,6 +419,37 @@ float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_TONE_MAPPING
|
||||||
|
/* Hable's UC2 Tone mapping parameters
|
||||||
|
A = 0.22;
|
||||||
|
B = 0.30;
|
||||||
|
C = 0.10;
|
||||||
|
D = 0.20;
|
||||||
|
E = 0.01;
|
||||||
|
F = 0.30;
|
||||||
|
W = 11.2;
|
||||||
|
equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
|
||||||
|
*/
|
||||||
|
|
||||||
|
vec3 uncharted2Tonemap(vec3 x)
|
||||||
|
{
|
||||||
|
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 applyToneMapping(vec4 color)
|
||||||
|
{
|
||||||
|
color = vec4(pow(color.rgb, vec3(2.2)), color.a);
|
||||||
|
const float gamma = 1.6;
|
||||||
|
const float exposureBias = 5.5;
|
||||||
|
color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
|
||||||
|
// Precalculated white_scale from
|
||||||
|
//vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
||||||
|
vec3 whiteScale = vec3(1.036015346);
|
||||||
|
color.rgb *= whiteScale;
|
||||||
|
return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
vec3 color;
|
vec3 color;
|
||||||
@ -350,6 +478,11 @@ void main(void)
|
|||||||
vec3 shadow_color = vec3(0.0, 0.0, 0.0);
|
vec3 shadow_color = vec3(0.0, 0.0, 0.0);
|
||||||
vec3 posLightSpace = getLightSpacePosition();
|
vec3 posLightSpace = getLightSpacePosition();
|
||||||
|
|
||||||
|
float distance_rate = (1 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 20.0));
|
||||||
|
float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z ),0.0);
|
||||||
|
|
||||||
|
if (distance_rate > 1e-7) {
|
||||||
|
|
||||||
#ifdef COLORED_SHADOWS
|
#ifdef COLORED_SHADOWS
|
||||||
vec4 visibility;
|
vec4 visibility;
|
||||||
if (cosLight > 0.0)
|
if (cosLight > 0.0)
|
||||||
@ -359,20 +492,37 @@ void main(void)
|
|||||||
shadow_int = visibility.r;
|
shadow_int = visibility.r;
|
||||||
shadow_color = visibility.gba;
|
shadow_color = visibility.gba;
|
||||||
#else
|
#else
|
||||||
|
if (cosLight > 0.0)
|
||||||
shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
|
shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
|
||||||
|
else
|
||||||
|
shadow_int = 1.0;
|
||||||
#endif
|
#endif
|
||||||
|
shadow_int *= distance_rate;
|
||||||
|
shadow_int = clamp(shadow_int, 0.0, 1.0);
|
||||||
|
|
||||||
if (f_normal_length != 0 && cosLight <= 0.001) {
|
|
||||||
shadow_int = clamp(shadow_int + 0.5 * abs(cosLight), 0.0, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shadow_int = 1.0 - (shadow_int * adj_shadow_strength);
|
// turns out that nightRatio falls off much faster than
|
||||||
|
// actual brightness of artificial light in relation to natual light.
|
||||||
|
// Power ratio was measured on torches in MTG (brightness = 14).
|
||||||
|
float adjusted_night_ratio = pow(nightRatio, 0.6);
|
||||||
|
|
||||||
col.rgb = mix(shadow_color, col.rgb, shadow_int) * shadow_int;
|
if (f_normal_length != 0 && cosLight < 0.035) {
|
||||||
|
shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, 0.035)/0.035);
|
||||||
|
}
|
||||||
|
|
||||||
|
shadow_int *= f_adj_shadow_strength;
|
||||||
|
|
||||||
|
// calculate fragment color from components:
|
||||||
|
col.rgb =
|
||||||
|
adjusted_night_ratio * col.rgb + // artificial light
|
||||||
|
(1.0 - adjusted_night_ratio) * ( // natural light
|
||||||
|
col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color
|
||||||
|
dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight
|
||||||
|
// col.r = 0.5 * clamp(getPenumbraRadius(ShadowMapSampler, posLightSpace.xy, posLightSpace.z, 1.0) / SOFTSHADOWRADIUS, 0.0, 1.0) + 0.5 * col.r;
|
||||||
|
// col.r = adjusted_night_ratio; // debug night ratio adjustment
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if ENABLE_TONE_MAPPING
|
#if ENABLE_TONE_MAPPING
|
||||||
col = applyToneMapping(col);
|
col = applyToneMapping(col);
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,6 +28,8 @@ centroid varying vec2 varTexCoord;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
varying vec3 eyeVec;
|
varying vec3 eyeVec;
|
||||||
|
varying float nightRatio;
|
||||||
|
|
||||||
varying float vIDiff;
|
varying float vIDiff;
|
||||||
|
|
||||||
const float e = 2.718281828459;
|
const float e = 2.718281828459;
|
||||||
@ -60,7 +62,7 @@ void main(void)
|
|||||||
gl_Position = mWorldViewProj * inVertexPosition;
|
gl_Position = mWorldViewProj * inVertexPosition;
|
||||||
|
|
||||||
vPosition = gl_Position.xyz;
|
vPosition = gl_Position.xyz;
|
||||||
vNormal = inVertexNormal;
|
vNormal = (mWorld * vec4(inVertexNormal, 0.0)).xyz;
|
||||||
worldPosition = (mWorld * inVertexPosition).xyz;
|
worldPosition = (mWorld * inVertexPosition).xyz;
|
||||||
eyeVec = -(mWorldView * inVertexPosition).xyz;
|
eyeVec = -(mWorldView * inVertexPosition).xyz;
|
||||||
|
|
||||||
@ -73,6 +75,7 @@ void main(void)
|
|||||||
? 1.0
|
? 1.0
|
||||||
: directional_ambient(normalize(inVertexNormal));
|
: directional_ambient(normalize(inVertexNormal));
|
||||||
#endif
|
#endif
|
||||||
|
nightRatio = 0.0;
|
||||||
|
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
varColor = inVertexColor.bgra;
|
varColor = inVertexColor.bgra;
|
||||||
@ -81,11 +84,12 @@ void main(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||||
|
vec3 nNormal = normalize(vNormal);
|
||||||
cosLight = max(0.0, dot(vNormal, -v_LightDirection));
|
cosLight = dot(nNormal, -v_LightDirection);
|
||||||
float texelSize = 0.51;
|
float texelSize = 767.0 / f_textureresolution;
|
||||||
float slopeScale = clamp(1.0 - cosLight, 0.0, 1.0);
|
float slopeScale = clamp(1.0 - abs(cosLight), 0.0, 1.0);
|
||||||
normalOffsetScale = texelSize * slopeScale;
|
normalOffsetScale = texelSize * slopeScale;
|
||||||
|
|
||||||
if (f_timeofday < 0.2) {
|
if (f_timeofday < 0.2) {
|
||||||
adj_shadow_strength = f_shadow_strength * 0.5 *
|
adj_shadow_strength = f_shadow_strength * 0.5 *
|
||||||
(1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
|
(1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
|
||||||
@ -98,6 +102,5 @@ void main(void)
|
|||||||
(1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
|
(1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
|
||||||
}
|
}
|
||||||
f_normal_length = length(vNormal);
|
f_normal_length = length(vNormal);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user