mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-05 13:30:34 +00:00
98 lines
3.7 KiB
HLSL
98 lines
3.7 KiB
HLSL
//-----------------------------------------------------------------------------
|
||
// Copyright (c) 2018 GarageGames, LLC
|
||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
// of this software and associated documentation files (the "Software"), to
|
||
// deal in the Software without restriction, including without limitation the
|
||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||
// sell copies of the Software, and to permit persons to whom the Software is
|
||
// furnished to do so, subject to the following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included in
|
||
// all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||
// IN THE SOFTWARE.
|
||
//-----------------------------------------------------------------------------
|
||
|
||
#ifndef BRDF_HLSL
|
||
#define BRDF_HLSL
|
||
|
||
#include "./torque.hlsl"
|
||
|
||
// BRDF from Frostbite presentation:
|
||
// Moving Frostbite to Physically Based Rendering
|
||
// S´ebastien Lagarde - Electronic Arts Frostbite
|
||
// Charles de Rousiers - Electronic Arts Frostbite
|
||
// SIGGRAPH 2014
|
||
|
||
float3 F_Schlick(in float3 f0, in float f90, in float u)
|
||
{
|
||
return f0 + (f90 - f0) * pow(1.f - u, 5.f);
|
||
}
|
||
|
||
float3 F_Fresnel(float3 SpecularColor, float VoH)
|
||
{
|
||
float3 SpecularColorSqrt = sqrt(min(SpecularColor, float3(0.99, 0.99, 0.99)));
|
||
float3 n = (1 + SpecularColorSqrt) / (1 - SpecularColorSqrt);
|
||
float3 g = sqrt(n*n + VoH*VoH - 1);
|
||
return 0.5 * sqr((g - VoH) / (g + VoH)) * (1 + sqr(((g + VoH)*VoH - 1) / ((g - VoH)*VoH + 1)));
|
||
}
|
||
|
||
float3 FresnelSchlickRoughness(float cosTheta, float3 F0, float roughness)
|
||
{
|
||
float3 ret = float3(0.0, 0.0, 0.0);
|
||
float powTheta = pow(1.0 - cosTheta, 5.0);
|
||
float invRough = float(1.0 - roughness);
|
||
|
||
ret.x = F0.x + (max(invRough, F0.x) - F0.x) * powTheta;
|
||
ret.y = F0.y + (max(invRough, F0.y) - F0.y) * powTheta;
|
||
ret.z = F0.z + (max(invRough, F0.z) - F0.z) * powTheta;
|
||
|
||
return ret;
|
||
}
|
||
|
||
float Fr_DisneyDiffuse(float NdotV, float NdotL, float LdotH, float linearRoughness)
|
||
{
|
||
float energyBias = lerp(0, 0.5, linearRoughness);
|
||
float energyFactor = lerp(1.0, 1.0 / 1.51, linearRoughness);
|
||
float fd90 = energyBias + 2.0 * LdotH*LdotH * linearRoughness;
|
||
float3 f0 = float3(1.0f, 1.0f, 1.0f);
|
||
float lightScatter = F_Schlick(f0, fd90, NdotL).r;
|
||
float viewScatter = F_Schlick(f0, fd90, NdotV).r;
|
||
|
||
return lightScatter * viewScatter * energyFactor;
|
||
}
|
||
|
||
float V_SmithGGXCorrelated(float NdotL, float NdotV, float alphaG2)
|
||
{
|
||
// Original formulation of G_SmithGGX Correlated
|
||
// lambda_v = (-1 + sqrt(alphaG2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;
|
||
// lambda_l = (-1 + sqrt(alphaG2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;
|
||
// G_SmithGGXCorrelated = 1 / (1 + lambda_v + lambda_l);
|
||
// V_SmithGGXCorrelated = G_SmithGGXCorrelated / (4.0f * NdotL * NdotV);
|
||
|
||
|
||
// This is the optimized version
|
||
//float alphaG2 = alphaG * alphaG;
|
||
|
||
// Caution: the "NdotL *" and "NdotV *" are explicitely inversed , this is not a mistake.
|
||
float Lambda_GGXV = NdotL * sqrt((-NdotV * alphaG2 + NdotV) * NdotV + alphaG2);
|
||
float Lambda_GGXL = NdotV * sqrt((-NdotL * alphaG2 + NdotL) * NdotL + alphaG2);
|
||
|
||
return 0.5f / (Lambda_GGXV + Lambda_GGXL);
|
||
}
|
||
|
||
float D_GGX(float NdotH, float m2)
|
||
{
|
||
// Divide by PI is apply later
|
||
//float m2 = m * m;
|
||
float f = (NdotH * m2 - NdotH) * NdotH + 1;
|
||
return m2 / (f * f);
|
||
}
|
||
|
||
#endif
|