diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index e7630da63..7e4d73123 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -8,16 +8,7 @@ vec3 DecodeNormal(vec2 n); vec3 SpecularBRDF(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness); vec3 DiffuseBRDF(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness); vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); - -vec3 getMostRepresentativePoint(vec3 direction, vec3 R, float angularRadius) -{ - vec3 D = direction; - float d = cos(angularRadius); - float r = sin(angularRadius); - float DdotR = dot(D, R); - vec3 S = R - DdotR * D; - return (DdotR < d) ? normalize(d * D + normalize (S) * r) : R; -} +vec3 SunMRP(vec3 normal, vec3 eyedir); void main() { vec2 uv = gl_FragCoord.xy / screen; @@ -28,12 +19,8 @@ void main() { float roughness = texture(ntex, uv).z; vec3 eyedir = -normalize(xpos.xyz); - vec3 L = normalize((transpose(InverseViewMatrix) * vec4(sun_direction, 0.)).xyz); - float NdotL = clamp(dot(norm, L), 0., 1.); - - float angle = 3.14 * sun_angle / 180.; - vec3 R = reflect(-eyedir, norm); - vec3 Lightdir = getMostRepresentativePoint(L, R, angle); + vec3 Lightdir = SunMRP(norm, eyedir); + float NdotL = clamp(dot(norm, Lightdir), 0., 1.); vec3 Specular = SpecularBRDF(norm, eyedir, Lightdir, vec3(1.), roughness); vec3 Diffuse = DiffuseBRDF(norm, eyedir, Lightdir, vec3(1.), roughness); diff --git a/data/shaders/sunlightshadow.frag b/data/shaders/sunlightshadow.frag index 5d154bdbb..4dbc9cbee 100644 --- a/data/shaders/sunlightshadow.frag +++ b/data/shaders/sunlightshadow.frag @@ -15,16 +15,7 @@ vec3 DecodeNormal(vec2 n); vec3 SpecularBRDF(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness); vec3 DiffuseBRDF(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness); vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); - -vec3 getMostRepresentativePoint(vec3 direction, vec3 R, float angularRadius) -{ - vec3 D = direction; - float d = cos(angularRadius); - float r = sin(angularRadius); - float DdotR = dot(D, R); - vec3 S = R - DdotR * D; - return (DdotR < d) ? normalize(d * D + normalize (S) * r) : R; -} +vec3 SunMRP(vec3 normal, vec3 eyedir); float getShadowFactor(vec3 pos, int index) { @@ -46,12 +37,8 @@ void main() { float roughness =texture(ntex, uv).z; vec3 eyedir = -normalize(xpos.xyz); - vec3 L = normalize((transpose(InverseViewMatrix) * vec4(sun_direction, 0.)).xyz); - float NdotL = clamp(dot(norm, L), 0., 1.); - - float angle = 3.14 * sun_angle / 180.; - vec3 R = reflect(-eyedir, norm); - vec3 Lightdir = getMostRepresentativePoint(L, R, angle); + vec3 Lightdir = SunMRP(norm, eyedir); + float NdotL = clamp(dot(norm, Lightdir), 0., 1.); vec3 Specular = SpecularBRDF(norm, eyedir, Lightdir, vec3(1.), roughness); vec3 Diffuse = DiffuseBRDF(norm, eyedir, Lightdir, vec3(1.), roughness); diff --git a/data/shaders/utils/SunMRP.frag b/data/shaders/utils/SunMRP.frag new file mode 100644 index 000000000..fcb3ac071 --- /dev/null +++ b/data/shaders/utils/SunMRP.frag @@ -0,0 +1,14 @@ +// Sun Most Representative Point (used for MRP area lighting method) +// From "Frostbite going PBR" paper +vec3 SunMRP(vec3 normal, vec3 eyedir) +{ + vec3 local_sundir = normalize((transpose(InverseViewMatrix) * vec4(sun_direction, 0.)).xyz); + vec3 R = reflect(-eyedir, normal); + float angularRadius = 3.14 * sun_angle / 180.; + vec3 D = local_sundir; + float d = cos(angularRadius); + float r = sin(angularRadius); + float DdotR = dot(D, R); + vec3 S = R - DdotR * D; + return (DdotR < d) ? normalize(d * D + normalize (S) * r) : R; +} \ No newline at end of file diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index ae33246fe..dae5f176c 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1639,6 +1639,7 @@ namespace FullScreenShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/SpecularBRDF.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/DiffuseBRDF.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/SunMRP.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/sunlight.frag").c_str()); AssignSamplerNames(Program, 0, "ntex", 1, "dtex"); @@ -1666,6 +1667,7 @@ namespace FullScreenShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/SpecularBRDF.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/DiffuseBRDF.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/SunMRP.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/sunlightshadow.frag").c_str()); // Use 8 to circumvent a catalyst bug when binding sampler