|
|
|
|
|
|
// Aniso |
|
|
|
float TdotV; |
|
|
|
float BdotV; |
|
|
|
|
|
|
|
|
|
|
|
// image based lighting |
|
|
|
// These variables aim to be use with EvaluateBSDF_Env |
|
|
|
float3 iblNormalWS; // Normal to be use with image based lighting |
|
|
|
float3 iblR; // Reflection vector, same as above. |
|
|
|
float3 iblDirWS; // Dominant specular direction, used for IBL in EvaluateBSDF_Env() |
|
|
|
|
|
|
|
float3 specularFGD; // Store preconvole BRDF for both specular and diffuse |
|
|
|
float diffuseFGD; |
|
|
|
|
|
|
|
|
|
|
preLightData.ggxLambdaV = GetSmithJointGGXLambdaV(preLightData.NdotV, bsdfData.roughness); |
|
|
|
|
|
|
|
float iblNdotV = preLightData.NdotV; |
|
|
|
float iblNdotV = preLightData.NdotV; |
|
|
|
float3 iblNormalWS = bsdfData.normalWS; |
|
|
|
|
|
|
|
// Check if we precompute anisotropy too |
|
|
|
|
|
|
preLightData.anisoGGXLambdaV = GetSmithJointGGXAnisoLambdaV(preLightData.TdotV, preLightData.BdotV, preLightData.NdotV, bsdfData.roughnessT, bsdfData.roughnessB); |
|
|
|
// Tangent = highlight stretch (anisotropy) direction. Bitangent = grain (brush) direction. |
|
|
|
iblNormalWS = GetAnisotropicModifiedNormal(bsdfData.bitangentWS, bsdfData.normalWS, V, bsdfData.anisotropy); |
|
|
|
|
|
|
|
|
|
|
|
// NOTE: If we follow the theory we should use the modified normal for the different calculation implying a normal (like NDotV) and use iblNormalWS |
|
|
|
// into function like GetSpecularDominantDir(). However modified normal is just a hack. The goal is just to stretch a cubemap, no accuracy here. |
|
|
|
// With this in mind and for performance reasons we chose to only use modified normal to calculate R. |
|
|
|
|
|
|
// We need to take into account the modified normal for faking anisotropic here. |
|
|
|
preLightData.iblR = reflect(-V, iblNormalWS); |
|
|
|
|
|
|
|
// We need to take into account the modified normal for faking anisotropic here. |
|
|
|
float3 iblR = reflect(-V, iblNormalWS); |
|
|
|
preLightData.iblDirWS = GetSpecularDominantDir(bsdfData.normalWS, iblR, bsdfData.roughness); |
|
|
|
|
|
|
|
// #if SHADERPASS == SHADERPASS_GBUFFER |
|
|
|
// preLightData.ambientOcclusion = LOAD_TEXTURE2D(_AmbientOcclusion, coord.unPositionSS).x; |
|
|
|
|
|
|
|
|
|
|
// TODO: test the strech from Tomasz |
|
|
|
// float shrinkedRoughness = AnisotropicStrechAtGrazingAngle(bsdfData.roughness, bsdfData.perceptualRoughness, NdotV); |
|
|
|
|
|
|
|
// Note: As explain in GetPreLightData we use normalWS and not iblNormalWS here (in case of anisotropy) |
|
|
|
float3 rayWS = GetSpecularDominantDir(bsdfData.normalWS, preLightData.iblR, bsdfData.roughness); |
|
|
|
|
|
|
|
float3 R = rayWS; |
|
|
|
weight = float2(1.0, 1.0); |
|
|
|
|
|
|
|
// In Unity the cubemaps are capture with the localToWorld transform of the component. |
|
|
|
|
|
|
|
// In Unity the cubemaps are capture with the localToWorld transform of the component. |
|
|
|
|
|
|
|
|
|
|
|
float3 R = preLightData.iblDirWS; |
|
|
|
float3x3 worldToLocal = transpose(float3x3(lightData.right, lightData.up, lightData.forward)); // worldToLocal assume no scaling |
|
|
|
float3 positionLS = positionWS - lightData.positionWS; |
|
|
|
positionLS = mul(positionLS, worldToLocal).xyz - lightData.offsetLS; // We want to calculate the intersection from the center of the bounding box. |
|
|
|
|
|
|
float3 rayLS = mul(rayWS, worldToLocal); |
|
|
|
float3 dirLS = mul(preLightData.iblDirWS, worldToLocal); |
|
|
|
float dist = BoxRayIntersectSimple(positionLS, rayLS, -boxOuterDistance, boxOuterDistance); |
|
|
|
float dist = BoxRayIntersectSimple(positionLS, dirLS, -boxOuterDistance, boxOuterDistance); |
|
|
|
R = (positionWS + dist * rayWS) - lightData.positionWS; |
|
|
|
|
|
|
|
R = (positionWS + dist * preLightData.iblDirWS) - lightData.positionWS; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
float3 rayLS = mul(rayWS, worldToLocal); |
|
|
|
float3 dirLS = mul(preLightData.iblDirWS, worldToLocal); |
|
|
|
float dist = SphereRayIntersectSimple(positionLS, rayLS, sphereOuterDistance); |
|
|
|
float dist = SphereRayIntersectSimple(positionLS, dirLS, sphereOuterDistance); |
|
|
|
R = (positionWS + dist * rayWS) - lightData.positionWS; |
|
|
|
R = (positionWS + dist * preLightData.iblDirWS) - lightData.positionWS; |
|
|
|
weight.y = 1.0; |
|
|
|
|
|
|
|
if (lightData.envShapeType == ENVSHAPETYPE_SPHERE) |
|
|
|
{ |
|
|
|
float distFade = max(length(positionLS) - lightData.innerDistance.x, 0.0); |
|
|
|