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.
117 lines
2.6 KiB
117 lines
2.6 KiB
#ifndef UNITY_PATH_TRACING_MATERIAL_INCLUDED
|
|
#define UNITY_PATH_TRACING_MATERIAL_INCLUDED
|
|
|
|
#define BSDF_WEIGHT_EPSILON 0.00001
|
|
|
|
struct MaterialData
|
|
{
|
|
// BSDFs (4 max)
|
|
BSDFData bsdfData;
|
|
float4 bsdfWeight;
|
|
|
|
// Subsurface scattering
|
|
bool isSubsurface;
|
|
float subsurfaceWeightFactor;
|
|
|
|
// View vector, and altered shading normal
|
|
// (to be consistent with the view vector and geometric normal)
|
|
float3 V;
|
|
float3 Nv;
|
|
|
|
#ifdef _PATH_TRACED_DUAL_SCATTERING
|
|
// World space position is required for shooting strand count rays during light evaluation for dual scattered hair.
|
|
float3 positionWS;
|
|
#endif
|
|
};
|
|
|
|
struct MaterialResult
|
|
{
|
|
float3 diffValue;
|
|
float diffPdf;
|
|
float3 specValue;
|
|
float specPdf;
|
|
};
|
|
|
|
void Init(inout MaterialResult result)
|
|
{
|
|
result.diffValue = 0.0;
|
|
result.diffPdf = 0.0;
|
|
result.specValue = 0.0;
|
|
result.specPdf = 0.0;
|
|
}
|
|
|
|
void InitDiffuse(inout MaterialResult result)
|
|
{
|
|
result.diffValue = 0.0;
|
|
result.diffPdf = 0.0;
|
|
}
|
|
|
|
void InitSpecular(inout MaterialResult result)
|
|
{
|
|
result.specValue = 0.0;
|
|
result.specPdf = 0.0;
|
|
}
|
|
|
|
bool IsAbove(float3 normalWS, float3 dirWS)
|
|
{
|
|
return dot(normalWS, dirWS) >= 0.0;
|
|
}
|
|
|
|
bool IsAbove(MaterialData mtlData, float3 dirWS)
|
|
{
|
|
return IsAbove(mtlData.bsdfData.geomNormalWS, dirWS);
|
|
}
|
|
|
|
bool IsAbove(MaterialData mtlData)
|
|
{
|
|
return IsAbove(mtlData.bsdfData.geomNormalWS, mtlData.V);
|
|
}
|
|
|
|
bool IsBelow(float3 normalWS, float3 dirWS)
|
|
{
|
|
return !IsAbove(normalWS, dirWS);
|
|
}
|
|
|
|
bool IsBelow(MaterialData mtlData, float3 dirWS)
|
|
{
|
|
return !IsAbove(mtlData, dirWS);
|
|
}
|
|
|
|
bool IsBelow(MaterialData mtlData)
|
|
{
|
|
return !IsAbove(mtlData);
|
|
}
|
|
|
|
float3 GetDiffuseNormal(MaterialData mtlData)
|
|
{
|
|
return mtlData.bsdfData.normalWS;
|
|
}
|
|
|
|
float3 GetSpecularNormal(MaterialData mtlData)
|
|
{
|
|
return mtlData.Nv;
|
|
}
|
|
|
|
float3 ComputeConsistentShadingNormal(float3 Wi, float3 G, float3 N)
|
|
{
|
|
// Check in which hemisphere does the incoming view vector fall
|
|
float GdotWi = dot(G, Wi);
|
|
float Hi = sign(GdotWi);
|
|
|
|
// First project N back towards Wi if it's on the other side of the view plane
|
|
float NdotWi = Hi * dot(N, Wi);
|
|
float3 Ni = N - Hi * min(0.0, NdotWi) * Wi;
|
|
|
|
// Then check in which hemisphere does the reflected vector fall
|
|
float3 Wo = reflect(-Wi, Ni);
|
|
float GdotWo = dot(G, Wo);
|
|
float Ho = sign(GdotWo);
|
|
|
|
// Bring reflection direction back to the right hemisphere (slightly offset from the horizon, for more robustness)
|
|
Wo = normalize(Wo - (GdotWo + Ho * 0.001) * G);
|
|
|
|
// Compute a new, consistent shading normal accordingly
|
|
return Hi != Ho ? Hi * normalize(Wi + Wo) : N;
|
|
}
|
|
|
|
#endif // UNITY_PATH_TRACING_MATERIAL_INCLUDED
|