Upload project file
This commit is contained in:
239
Runtime/HDRP/Shaders/EnvLighting.hlsl
Normal file
239
Runtime/HDRP/Shaders/EnvLighting.hlsl
Normal file
@@ -0,0 +1,239 @@
|
||||
#define unity_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1 - 0.04)
|
||||
|
||||
// _preIntegratedFGD and _CubemapLD are unique for each BRDF
|
||||
IndirectLighting EvaluateBSDF_Env(LightLoopContext lightLoopContext,
|
||||
float3 V, PositionInputs posInput,
|
||||
PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData,
|
||||
int influenceShapeType,
|
||||
inout float hierarchyWeight)
|
||||
{
|
||||
IndirectLighting lighting;
|
||||
ZERO_INITIALIZE(IndirectLighting, lighting);
|
||||
|
||||
float3 envLighting;
|
||||
float weight = 1.0;
|
||||
|
||||
float3 R = reflect(-V, bsdfData.normalWS);
|
||||
|
||||
EvaluateLight_EnvIntersection(posInput.positionWS, bsdfData.normalWS, lightData, influenceShapeType, R, weight);
|
||||
|
||||
// 31 bit index, 1 bit cache type
|
||||
uint cacheType = IsEnvIndexCubemap(lightData.envIndex) ? ENVCACHETYPE_CUBEMAP : ENVCACHETYPE_TEXTURE2D;
|
||||
// Index start at 1, because -0 == 0, so we can't known which cache to sample for that index. Thus it is invalid.
|
||||
int index = abs(lightData.envIndex) - 1;
|
||||
|
||||
float lod = PerceptualRoughnessToMipmapLevel(preLightData.iblPerceptualRoughness) * lightData.roughReflections;
|
||||
float2 atlasCoords = GetReflectionAtlasCoordsCube(CUBE_SCALE_OFFSET[index], R, lod);
|
||||
|
||||
// No distance based roughness for simple lit
|
||||
float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, R, PerceptualRoughnessToMipmapLevel(preLightData.iblPerceptualRoughness) * lightData.roughReflections, lightData.rangeCompressionFactorCompensation, posInput.positionNDC);
|
||||
weight *= preLD.a; // Used by planar reflection to discard pixel
|
||||
|
||||
//envLighting = F_Schlick(bsdfData.fresnel0, dot(bsdfData.normalWS, V)) * preLD.rgb;
|
||||
envLighting = preLD.rgb;
|
||||
|
||||
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
|
||||
envLighting *= weight * lightData.multiplier;
|
||||
|
||||
lighting.specularReflected = envLighting;
|
||||
|
||||
return lighting;
|
||||
}
|
||||
|
||||
float4 ComputeReflection(LightLoopContext context, PositionInputs posInput, PreLightData preLightData, BuiltinData builtinData, float3 V, float lod, BSDFData bsdfData)
|
||||
{
|
||||
float3 refcolor = 0;
|
||||
float reflectionHierarchyWeight = 0.0; // Max: 1.0
|
||||
|
||||
uint envLightStart, envLightCount;
|
||||
|
||||
// Fetch first env light to provide the scene proxy for screen space computation
|
||||
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
|
||||
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
|
||||
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
|
||||
envLightCount = _EnvLightCount;
|
||||
envLightStart = 0;
|
||||
#endif
|
||||
|
||||
bool fastPath = false;
|
||||
#if SCALARIZE_LIGHT_LOOP
|
||||
uint envStartFirstLane;
|
||||
fastPath = IsFastPath(envLightStart, envStartFirstLane);
|
||||
#endif
|
||||
|
||||
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
|
||||
|
||||
#if SCALARIZE_LIGHT_LOOP
|
||||
if (fastPath)
|
||||
{
|
||||
envLightStart = envStartFirstLane;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Scalarized loop, same rationale of the punctual light version
|
||||
uint v_envLightListOffset = 0;
|
||||
uint v_envLightIdx = envLightStart;
|
||||
#if NEED_TO_CHECK_HELPER_LANE
|
||||
// On some platform helper lanes don't behave as we'd expect, therefore we prevent them from entering the loop altogether.
|
||||
// IMPORTANT! This has implications if ddx/ddy is used on results derived from lighting, however given Lightloop is called in compute we should be
|
||||
// sure it will not happen.
|
||||
bool isHelperLane = WaveIsHelperLane();
|
||||
while (!isHelperLane && v_envLightListOffset < envLightCount)
|
||||
#else
|
||||
while (v_envLightListOffset < envLightCount)
|
||||
#endif
|
||||
{
|
||||
v_envLightIdx = FetchIndex(envLightStart, v_envLightListOffset);
|
||||
#if SCALARIZE_LIGHT_LOOP
|
||||
uint s_envLightIdx = ScalarizeElementIndex(v_envLightIdx, fastPath);
|
||||
#else
|
||||
uint s_envLightIdx = v_envLightIdx;
|
||||
#endif
|
||||
if (s_envLightIdx == -1)
|
||||
break;
|
||||
|
||||
EnvLightData s_envLightData = FetchEnvLight(s_envLightIdx); // Scalar load.
|
||||
|
||||
// If current scalar and vector light index match, we process the light. The v_envLightListOffset for current thread is increased.
|
||||
// Note that the following should really be ==, however, since helper lanes are not considered by WaveActiveMin, such helper lanes could
|
||||
// end up with a unique v_envLightIdx value that is smaller than s_envLightIdx hence being stuck in a loop. All the active lanes will not have this problem.
|
||||
if (s_envLightIdx >= v_envLightIdx)
|
||||
{
|
||||
v_envLightListOffset++;
|
||||
if (reflectionHierarchyWeight < 1.0)
|
||||
{
|
||||
if (IsMatchingLightLayer(s_envLightData.lightLayers, builtinData.renderingLayers))
|
||||
{
|
||||
IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, s_envLightData, bsdfData, s_envLightData.influenceShapeType, reflectionHierarchyWeight);
|
||||
#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)
|
||||
float3 lightInReflDir = float3(-1, -1, -1);
|
||||
if (s_envLightData.normalizeWithAPV > 0 && all(lightInReflDir >= 0))
|
||||
{
|
||||
float factor = GetReflectionProbeNormalizationFactor(lightInReflDir, bsdfData.normalWS, s_envLightData.L0L1, s_envLightData.L2_1, s_envLightData.L2_2);
|
||||
lighting.specularReflected *= factor;
|
||||
}
|
||||
#endif
|
||||
refcolor += lighting.specularReflected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return float4(refcolor.r, refcolor.g, refcolor.b, reflectionHierarchyWeight);
|
||||
}
|
||||
|
||||
float3 ComputeFresnelLerp(float3 c0, float3 c1, float cosA)
|
||||
{
|
||||
float t = pow(1 - cosA, 5);
|
||||
return lerp(c0, c1, t);
|
||||
}
|
||||
|
||||
float3 ComputeIndirectDiffuse(PositionInputs posInput, BSDFData bsdfData, float3 V)
|
||||
{
|
||||
float3 indirectDiffuse = 0.0;
|
||||
|
||||
if(_ID_Intensity > 0)
|
||||
{
|
||||
#ifdef _PBR_Mode_ANISO
|
||||
GetGGXAnisotropicModifiedNormalAndRoughness(bsdfData.bitangentWS, bsdfData.tangentWS , bsdfData.normalWS, V, bsdfData.anisotropy, bsdfData.perceptualRoughness, bsdfData.normalWS, bsdfData.perceptualRoughness);
|
||||
#endif
|
||||
|
||||
float NdotV = saturate(dot(bsdfData.normalWS, V));
|
||||
|
||||
#if defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)
|
||||
BuiltinData apvBuiltinData;
|
||||
ZERO_INITIALIZE(BuiltinData, apvBuiltinData);
|
||||
|
||||
#if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON)
|
||||
EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(posInput.positionWS), 0.0, 0.0, V, posInput.positionSS, apvBuiltinData.bakeDiffuseLighting, apvBuiltinData.backBakeDiffuseLighting);
|
||||
#else
|
||||
EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(posInput.positionWS), bsdfData.normalWS, -bsdfData.normalWS, V, posInput.positionSS, apvBuiltinData.bakeDiffuseLighting, apvBuiltinData.backBakeDiffuseLighting);
|
||||
#endif
|
||||
|
||||
float3 probeDiffuse = apvBuiltinData.bakeDiffuseLighting * GetCurrentExposureMultiplier();
|
||||
|
||||
indirectDiffuse = probeDiffuse;
|
||||
#else
|
||||
#if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON)
|
||||
indirectDiffuse = EvaluateAmbientProbe(0.0) * GetCurrentExposureMultiplier();
|
||||
#else
|
||||
indirectDiffuse = EvaluateAmbientProbe(bsdfData.normalWS) * GetCurrentExposureMultiplier();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//SSGI
|
||||
if(_ReceivesSSGI == 1)
|
||||
{
|
||||
float4 ssgiLighting = LOAD_TEXTURE2D_X(_IndirectDiffuseTexture, posInput.positionSS);
|
||||
ssgiLighting *= _GIMultiplier;
|
||||
indirectDiffuse = lerp(indirectDiffuse, ssgiLighting.rgb, ssgiLighting.a);
|
||||
}
|
||||
|
||||
//Compelete the indirect lighting
|
||||
indirectDiffuse = indirectDiffuse * bsdfData.diffuseColor * _BaseColor;
|
||||
|
||||
//SSAO
|
||||
if(_ReceivesSSAO == 1)
|
||||
{
|
||||
AmbientOcclusionFactor aoFactor;
|
||||
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, NdotV, bsdfData.perceptualRoughness, bsdfData.ambientOcclusion, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
|
||||
indirectDiffuse *= lerp(_AOMin, 1, aoFactor.indirectAmbientOcclusion);
|
||||
}
|
||||
indirectDiffuse = indirectDiffuse * bsdfData.ambientOcclusion;
|
||||
}
|
||||
|
||||
return indirectDiffuse;
|
||||
}
|
||||
|
||||
float3 ComputeIndirectSpecular(LightLoopContext lightLoopContext, PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, SurfaceData surfaceData, BuiltinData builtinData, float3 V)
|
||||
{
|
||||
#if defined(_PBR_Mode_OFF) || defined(_PBR_Mode_TOON)
|
||||
return 0;
|
||||
#else
|
||||
float3 indirectSpecular = 0;
|
||||
|
||||
if(_IR_Intensity > 0)
|
||||
{
|
||||
#ifdef _PBR_Mode_ANISO
|
||||
GetGGXAnisotropicModifiedNormalAndRoughness(bsdfData.bitangentWS, bsdfData.tangentWS , bsdfData.normalWS, V, bsdfData.anisotropy, bsdfData.perceptualRoughness, bsdfData.normalWS, bsdfData.perceptualRoughness);
|
||||
#endif
|
||||
|
||||
float3 albedo = _BaseColor.rgb * surfaceData.baseColor;
|
||||
float mip = PerceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness);
|
||||
float NdotV = saturate(dot(bsdfData.normalWS, V));
|
||||
|
||||
indirectSpecular = SampleSkyTexture(reflect(-V, bsdfData.normalWS), mip, 0).rgb;
|
||||
float3 specColor = lerp(unity_ColorSpaceDielectricSpec, albedo, surfaceData.metallic);;
|
||||
float oneMinusReflectivity = unity_ColorSpaceDielectricSpec.a * (1 - surfaceData.metallic);
|
||||
float grazingTerm = saturate((1 - bsdfData.perceptualRoughness) + (1 - oneMinusReflectivity));
|
||||
|
||||
//Reflection Probe
|
||||
float4 refProbe = ComputeReflection(lightLoopContext, posInput, preLightData, builtinData, V, mip, bsdfData);
|
||||
indirectSpecular = lerp(indirectSpecular, refProbe.rgb, refProbe.a);
|
||||
|
||||
//SSR
|
||||
if(_ReceivesSSR == 1)
|
||||
{
|
||||
float4 ssrLighting = LOAD_TEXTURE2D_X(_SsrLightingTexture, posInput.positionSS);
|
||||
InversePreExposeSsrLighting(ssrLighting);
|
||||
ApplyScreenSpaceReflectionWeight(ssrLighting);
|
||||
indirectSpecular = lerp(indirectSpecular, ssrLighting.rgb, ssrLighting.a);
|
||||
}
|
||||
|
||||
//Compelete the indirect lighting
|
||||
indirectSpecular = indirectSpecular * ComputeFresnelLerp(specColor, grazingTerm, NdotV) * GetCurrentExposureMultiplier();
|
||||
|
||||
// Occlusion
|
||||
if(_ReceivesSSAO == 1)
|
||||
{
|
||||
AmbientOcclusionFactor aoFactor;
|
||||
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, NdotV, bsdfData.perceptualRoughness, bsdfData.ambientOcclusion, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
|
||||
|
||||
indirectSpecular *= lerp(_AOMin, 1, aoFactor.indirectSpecularOcclusion);
|
||||
}
|
||||
indirectSpecular = indirectSpecular * bsdfData.specularOcclusion;
|
||||
}
|
||||
return indirectSpecular;
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user