lygia
/v1.1.6
/lighting
/specular
/ggx
)Dependencies:
lygia
/v1.1.6
/lighting
/common
/ggx
.glsl
lygia
/v1.1.6
/lighting
/common
/smithGGXCorrelated
.glsl
lygia
/v1.1.6
/math
/saturate
.glsl
lygia
/v1.1.6
/math
/saturateMediump
.glsl
lygia
/v1.1.6
/lighting
/fresnel
.glsl
#ifndef FNC_SPECULAR_GGX
#define FNC_SPECULAR_GGX
float specularGGX(const in vec3 _L, const in vec3 _N, const in vec3 _V, float _NoV, float _NoL, float _roughness, float _fresnel) {
float NoV = max(_NoV, 0.0);
float NoL = max(_NoL, 0.0);
vec3 H = normalize(_L + _V);
float LoH = saturate(dot(_L, H));
float NoH = saturate(dot(_N, H));
// float NoV, float NoL, float roughness
float linearRoughness = _roughness * _roughness;
float D = GGX(NoH, linearRoughness);
#if defined(PLATFORM_RPI)
float V = smithGGXCorrelated_Fast(_NoV, NoL,linearRoughness);
#else
float V = smithGGXCorrelated(_NoV, NoL,linearRoughness);
#endif
float F = fresnel(vec3(_fresnel), LoH).r;
return (D * V) * F;
}
float specularGGX(vec3 L, vec3 N, vec3 V, float roughness, float fresnel) {
float NoV = max(dot(N, V), 0.0);
float NoL = max(dot(N, L), 0.0);
return specularGGX(L, N, V, NoV, NoL, roughness, fresnel);
}
float specularGGX(vec3 L, vec3 N, vec3 V, float roughness) {
return specularGGX(L, N, V, roughness, 0.04);
}
#endif
Dependencies:
// #include "../common/ggx.hlsl"
#ifndef FNC_SPECULAR_GGX
#define FNC_SPECULAR_GGX
float commonGGX(float NoH, float linearRoughness) {
float oneMinusNoHSquared = 1.0 - NoH * NoH;
float a = NoH * linearRoughness;
float k = linearRoughness / (oneMinusNoHSquared + a * a);
float d = k * k * INV_PI;
return saturateMediump(d);
}
float specularGGX(float3 _L, float3 _N, float3 _V, float _NoV, float _NoL, float _roughness, float _fresnel) {
float NoV = max(_NoV, 0.0);
float NoL = max(_NoL, 0.0);
float3 H = normalize(_L + _V);
float LoH = saturate(dot(_L, H));
float NoH = saturate(dot(_N, H));
// float NoV, float NoL, float roughness
float linearRoughness = _roughness * _roughness;
float D = commonGGX(NoH, linearRoughness);
float V = smithGGXCorrelated(_NoV, NoL,linearRoughness);
float F = fresnel(float3(_fresnel, _fresnel, _fresnel), LoH).r;
return (D * V) * F;
}
float specularGGX(float3 L, float3 N, float3 V, float roughness, float fresnel) {
float NoV = max(dot(N, V), 0.0);
float NoL = max(dot(N, L), 0.0);
return specularGGX(L, N, V, NoV, NoL, roughness, fresnel);
}
float specularGGX(float3 L, float3 N, float3 V, float roughness) {
return specularGGX(L, N, V, roughness, 0.04);
}
#endif
LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.
Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).
It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.
Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository