111 lines
3.1 KiB
GLSL
111 lines
3.1 KiB
GLSL
#ifndef _LIGHT_MOBILE_GLSL_
|
|
#define _LIGHT_MOBILE_GLSL_
|
|
|
|
#include "compiled.inc"
|
|
#include "std/brdf.glsl"
|
|
#ifdef _ShadowMap
|
|
#include "std/shadows.glsl"
|
|
#endif
|
|
|
|
#ifdef _ShadowMap
|
|
#ifdef _SinglePoint
|
|
#ifdef _Spot
|
|
uniform sampler2DShadow shadowMapSpot[1];
|
|
uniform mat4 LWVPSpot0;
|
|
#else
|
|
uniform samplerCubeShadow shadowMapPoint[1];
|
|
uniform vec2 lightProj;
|
|
#endif
|
|
#endif
|
|
#ifdef _Clusters
|
|
uniform samplerCubeShadow shadowMapPoint[4];
|
|
uniform vec2 lightProj;
|
|
#ifdef _Spot
|
|
uniform sampler2DShadow shadowMapSpot[4];
|
|
uniform mat4 LWVPSpot0;
|
|
uniform mat4 LWVPSpot1;
|
|
uniform mat4 LWVPSpot2;
|
|
uniform mat4 LWVPSpot3;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
|
|
const vec3 albedo, const float rough, const float spec, const vec3 f0
|
|
#ifdef _ShadowMap
|
|
, int index, float bias, bool receiveShadow
|
|
#endif
|
|
#ifdef _Spot
|
|
, bool isSpot, float spotA, float spotB, vec3 spotDir
|
|
#endif
|
|
) {
|
|
vec3 ld = lp - p;
|
|
vec3 l = normalize(ld);
|
|
vec3 h = normalize(v + l);
|
|
float dotNH = dot(n, h);
|
|
float dotVH = dot(v, h);
|
|
float dotNL = dot(n, l);
|
|
|
|
vec3 direct = albedo * max(dotNL, 0.0) +
|
|
specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
|
|
|
|
direct *= lightCol;
|
|
direct *= attenuate(distance(p, lp));
|
|
|
|
#ifdef _Spot
|
|
if (isSpot) {
|
|
float spotEffect = dot(spotDir, l); // lightDir
|
|
// x - cutoff, y - cutoff - exponent
|
|
if (spotEffect < spotA) {
|
|
direct *= smoothstep(spotB, spotA, spotEffect);
|
|
}
|
|
#ifdef _ShadowMap
|
|
if (receiveShadow) {
|
|
#ifdef _SinglePoint
|
|
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
|
|
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
|
|
#endif
|
|
#ifdef _Clusters
|
|
if (index == 0) {
|
|
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
|
|
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
|
|
}
|
|
else if (index == 1) {
|
|
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
|
|
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
|
|
}
|
|
else if (index == 2) {
|
|
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
|
|
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
|
|
}
|
|
else if (index == 3) {
|
|
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
|
|
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
return direct;
|
|
}
|
|
#endif
|
|
|
|
#ifdef _ShadowMap
|
|
#ifndef _Spot
|
|
if (receiveShadow) {
|
|
#ifdef _SinglePoint
|
|
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
|
|
#endif
|
|
#ifdef _Clusters
|
|
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
|
|
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
|
|
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
|
|
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
|
|
#endif
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
return direct;
|
|
}
|
|
|
|
#endif
|