You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.4 KiB
73 lines
2.4 KiB
using System;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition.LTC
|
|
{
|
|
/// <summary>
|
|
/// GGX implementation of the BRDF interface
|
|
/// </summary>
|
|
class BRDF_GGX : IBRDF
|
|
{
|
|
public double Eval(ref Vector3 _tsView, ref Vector3 _tsLight, float _alpha, out double _pdf)
|
|
{
|
|
if (_tsView.z <= 0)
|
|
{
|
|
_pdf = 0;
|
|
return 0;
|
|
}
|
|
|
|
// masking
|
|
double lambdaV = Lambda(_tsView.z, _alpha);
|
|
|
|
// shadowing
|
|
double G2 = 0;
|
|
if (_tsLight.z > 0.0f)
|
|
{
|
|
double lambdaL = Lambda(_tsLight.z, _alpha);
|
|
G2 = 1.0 / (1.0 + lambdaV + lambdaL);
|
|
}
|
|
|
|
// D
|
|
Vector3 H = _tsView + _tsLight;
|
|
float lengthH = H.magnitude;
|
|
if (lengthH > 1e-8f)
|
|
H = H / lengthH;
|
|
else
|
|
H = new Vector3(0, 0, 1);
|
|
|
|
double slopex = H.x / H.z;
|
|
double slopey = H.y / H.z;
|
|
double D = 1.0 / (1.0 + (slopex * slopex + slopey * slopey) / _alpha / _alpha);
|
|
D = D * D;
|
|
D = D / (Math.PI * _alpha * _alpha * H.z * H.z * H.z * H.z);
|
|
|
|
// Full specular mico-facet model is F * D * G / (4 * NdotL * NdotV) but since we're fitting with the NdotL included, it gets nicely canceled out!
|
|
double res = D * G2 / 4.0 / _tsView.z;
|
|
|
|
// pdf = D(H) * (N.H) / (4 * (L.H))
|
|
_pdf = Math.Abs(D * H.z / 4.0 / Vector3.Dot(_tsView, H));
|
|
|
|
return res;
|
|
}
|
|
|
|
public void GetSamplingDirection(ref Vector3 _tsView, float _alpha, float _U1, float _U2, ref Vector3 _direction)
|
|
{
|
|
float phi = 2.0f * Mathf.PI * _U1;
|
|
float r = _alpha * Mathf.Sqrt(_U2 / (1.0f - _U2));
|
|
Vector3 H = new Vector3(r * Mathf.Cos(phi), r * Mathf.Sin(phi), 1.0f).normalized;
|
|
_direction = -_tsView + 2.0f * H * Vector3.Dot(H, _tsView);
|
|
}
|
|
|
|
double Lambda(float _cosTheta, float _alpha)
|
|
{
|
|
double a = 1.0f / _alpha / Math.Tan(Math.Acos(_cosTheta));
|
|
double lambda = _cosTheta < 1.0 ? 0.5 * (-1.0 + Math.Sqrt(1.0 + 1.0 / (a * a))) : 0.0;
|
|
return lambda;
|
|
}
|
|
|
|
public LTCLightingModel GetLightingModel()
|
|
{
|
|
return LTCLightingModel.GGX;
|
|
}
|
|
}
|
|
}
|