| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- // Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- // Contains functions for light calculations
- #ifndef ANKI_SHADERS_LIGHT_FUNCTIONS_GLSL
- #define ANKI_SHADERS_LIGHT_FUNCTIONS_GLSL
- #pragma anki include "shaders/Common.glsl"
- const float ATTENUATION_BOOST = 0.05;
- const float OMNI_LIGHT_FRUSTUM_NEAR_PLANE = 0.1 / 4.0;
- //==============================================================================
- /// Calculate the cluster split
- uint calcClusterSplit(float zVspace)
- {
- zVspace = -zVspace;
- float fk = sqrt(
- (zVspace - u_nearFarClustererDivisor.x) / u_nearFarClustererDivisor.z);
- uint k = uint(fk);
- return k;
- }
- //==============================================================================
- float computeAttenuationFactor(float lightRadius, vec3 frag2Light)
- {
- float fragLightDist = length(frag2Light);
- float att = (fragLightDist * lightRadius) + (1.0 + ATTENUATION_BOOST);
- att = max(0.0, att);
- att *= att;
- return att;
- }
- //==============================================================================
- // Performs BRDF specular lighting
- vec3 computeSpecularColorBrdf(
- vec3 v, // view dir
- vec3 l, // light dir
- vec3 n, // normal
- vec3 specCol,
- vec3 lightSpecCol,
- float a2, // rougness^2
- float nol) // N dot L
- {
- vec3 h = normalize(l + v);
- // Fresnel (Schlick)
- float loh = max(EPSILON, dot(l, h));
- vec3 f = specCol + (1.0 - specCol) * pow((1.0 + EPSILON - loh), 5.0);
- //float f = specColor + (1.0 - specColor)
- // * pow(2.0, (-5.55473 * loh - 6.98316) * loh);
- // NDF: GGX Trowbridge-Reitz
- float noh = max(EPSILON, dot(n, h));
- float d = a2 / (PI * pow(noh * noh * (a2 - 1.0) + 1.0, 2.0));
- // Visibility term: Geometric shadowing devided by BRDF denominator
- float nov = max(EPSILON, dot(n, v));
- float vv = nov + sqrt((nov - nov * a2) * nov + a2);
- float vl = nol + sqrt((nol - nol * a2) * nol + a2);
- float vis = 1.0 / (vv * vl);
- return f * (vis * d) * lightSpecCol;
- }
- //==============================================================================
- vec3 computeDiffuseColor(vec3 diffCol, vec3 lightDiffCol)
- {
- return diffCol * lightDiffCol;
- }
- //==============================================================================
- float computeSpotFactor(
- vec3 l,
- float outerCos,
- float innerCos,
- vec3 spotDir)
- {
- float costheta = -dot(l, spotDir);
- float spotFactor = smoothstep(outerCos, innerCos, costheta);
- return spotFactor;
- }
- //==============================================================================
- float computeShadowFactorSpot(mat4 lightProjectionMat, vec3 fragPos,
- float layer)
- {
- vec4 texCoords4 = lightProjectionMat * vec4(fragPos, 1.0);
- vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
- #if POISSON == 1
- const vec2 poissonDisk[4] = vec2[](
- vec2(-0.94201624, -0.39906216),
- vec2(0.94558609, -0.76890725),
- vec2(-0.094184101, -0.92938870),
- vec2(0.34495938, 0.29387760));
- float shadowFactor = 0.0;
- vec2 cordpart0 = vec2(layer, texCoords3.z);
- for(int i = 0; i < 4; i++)
- {
- vec2 cordpart1 = texCoords3.xy + poissonDisk[i] / (300.0);
- vec4 tcoord = vec4(cordpart1, cordpart0);
- shadowFactor += texture(u_spotMapArr, tcoord);
- }
- return shadowFactor / 4.0;
- #else
- vec4 tcoord = vec4(texCoords3.x, texCoords3.y, layer, texCoords3.z);
- float shadowFactor = texture(u_spotMapArr, tcoord);
- return shadowFactor;
- #endif
- }
- //==============================================================================
- float computeShadowFactorOmni(vec3 frag2Light, float layer, float radius)
- {
- vec3 dir = (u_viewMat * vec4(-frag2Light, 1.0)).xyz;
- vec3 dirabs = abs(dir);
- float dist = -max(dirabs.x, max(dirabs.y, dirabs.z));
- dir = normalize(dir);
- const float near = OMNI_LIGHT_FRUSTUM_NEAR_PLANE;
- const float far = radius;
- // Original code:
- // float g = near - far;
- // float z = (far + near) / g * dist + (2.0 * far * near) / g;
- // float w = -dist;
- // z /= w;
- // z = z * 0.5 + 0.5;
- // Optimized:
- float z = (far * (dist + near)) / (dist * (far - near));
- float shadowFactor = texture(u_omniMapArr, vec4(dir, layer), z).r;
- return shadowFactor;
- }
- #endif
|