|
|
|
|
|
|
float reflectionHierarchyWeight = 0.0; // Max: 1.0 |
|
|
|
float refractionHierarchyWeight = 0.0; // Max: 1.0 |
|
|
|
|
|
|
|
// Fetch first env light to provide the scene proxy |
|
|
|
EnvLightData firstEnvLight; |
|
|
|
ZERO_INITIALIZE(EnvLightData, firstEnvLight); |
|
|
|
// First loop iteration is: |
|
|
|
// 1. Screen Space Refraction / Reflection |
|
|
|
// 2. Environment Reflection / Refraction |
|
|
|
// 3. Sky Reflection / Refraction |
|
|
|
// |
|
|
|
// Following loop iterations are: |
|
|
|
// 1. Environment Reflection / Refraction |
|
|
|
// 2. Sky Reflection / Refraction |
|
|
|
|
|
|
|
// Common variable for all iterations |
|
|
|
// Define macro for a better understanding of the loop |
|
|
|
#ifdef LIGHTLOOP_TILE_PASS |
|
|
|
uint envLightStart; |
|
|
|
# define FETCHINDEX(index) FetchIndex(envLightStart, index); |
|
|
|
#else |
|
|
|
# define FETCHINDEX(index) index |
|
|
|
#endif |
|
|
|
uint envLightCount; |
|
|
|
|
|
|
|
#define CONCAT(L, R) L##R |
|
|
|
#define EVALUATE_BSDF_ENV(envLightData, TYPE, type) {\ |
|
|
|
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, envLightData, bsdfData, \ |
|
|
|
envLightData.influenceShapeType, \ |
|
|
|
CONCAT(GPUIMAGEBASEDLIGHTINGTYPE_, TYPE), CONCAT(type, HierarchyWeight)); \ |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting);\ |
|
|
|
} |
|
|
|
|
|
|
|
// First loop iteration |
|
|
|
if (featureFlags & ( |
|
|
|
LIGHTFEATUREFLAGS_ENV |
|
|
|
| LIGHTFEATUREFLAGS_SKY |
|
|
|
| LIGHTFEATUREFLAGS_SSREFRACTION |
|
|
|
| LIGHTFEATUREFLAGS_SSREFLECTION |
|
|
|
) |
|
|
|
) |
|
|
|
#ifdef LIGHTLOOP_TILE_PASS |
|
|
|
uint envLightStart; |
|
|
|
uint envLightCount; |
|
|
|
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount); |
|
|
|
#else |
|
|
|
uint envLightCount = _EnvLightCount; |
|
|
|
#endif |
|
|
|
if (envLightCount > 0) |
|
|
|
// Fetch first env light to provide the scene proxy for screen space computation |
|
|
|
EnvLightData envLightData; |
|
|
|
ZERO_INITIALIZE(EnvLightData, envLightData); |
|
|
|
uint envLightIndex = FetchIndex(envLightStart, 0); |
|
|
|
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount); |
|
|
|
uint envLightIndex = 0; |
|
|
|
envLightCount = _EnvLightCount; |
|
|
|
firstEnvLight = _EnvLightDatas[envLightIndex]; |
|
|
|
if (envLightCount > 0) |
|
|
|
{ |
|
|
|
uint envLightIndex = FETCHINDEX(0); |
|
|
|
envLightData = _EnvLightDatas[envLightIndex]; |
|
|
|
} |
|
|
|
else |
|
|
|
envLightData = InitSkyEnvLightData(0); |
|
|
|
} |
|
|
|
|
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION) |
|
|
|
{ |
|
|
|
IndirectLighting lighting = EvaluateBSDF_SSLighting( context, V, posInput, preLightData, bsdfData, envLightData, |
|
|
|
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight); |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
} |
|
|
|
|
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFLECTION) |
|
|
|
{ |
|
|
|
IndirectLighting lighting = EvaluateBSDF_SSLighting( context, V, posInput, preLightData, bsdfData, envLightData, |
|
|
|
GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight); |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
} |
|
|
|
|
|
|
|
if ((featureFlags & LIGHTFEATUREFLAGS_ENV) && envLightCount > 0) |
|
|
|
{ |
|
|
|
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES; |
|
|
|
|
|
|
|
EVALUATE_BSDF_ENV(envLightData, REFLECTION, reflection); |
|
|
|
|
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION) |
|
|
|
EVALUATE_BSDF_ENV(envLightData, REFRACTION, refraction); |
|
|
|
else |
|
|
|
firstEnvLight = InitSkyEnvLightData(0); |
|
|
|
} |
|
|
|
|
|
|
|
// Only apply the sky IBL if the sky texture is available |
|
|
|
if ((featureFlags & LIGHTFEATUREFLAGS_SKY) && _EnvLightSkyEnabled) |
|
|
|
{ |
|
|
|
// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression) |
|
|
|
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY; |
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION) |
|
|
|
{ |
|
|
|
IndirectLighting lighting = EvaluateBSDF_SSLighting( |
|
|
|
context, |
|
|
|
V, |
|
|
|
posInput, |
|
|
|
preLightData, |
|
|
|
bsdfData, |
|
|
|
firstEnvLight, |
|
|
|
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, |
|
|
|
refractionHierarchyWeight); |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
} |
|
|
|
// The sky data are generated on the fly so the compiler can optimize the code |
|
|
|
EnvLightData envLightSky = InitSkyEnvLightData(0); |
|
|
|
EVALUATE_BSDF_ENV(envLightSky, REFLECTION, reflection); |
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFLECTION) |
|
|
|
{ |
|
|
|
IndirectLighting lighting = EvaluateBSDF_SSLighting( |
|
|
|
context, |
|
|
|
V, |
|
|
|
posInput, |
|
|
|
preLightData, |
|
|
|
bsdfData, |
|
|
|
firstEnvLight, |
|
|
|
GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, |
|
|
|
reflectionHierarchyWeight); |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION) |
|
|
|
EVALUATE_BSDF_ENV(envLightSky, REFRACTION, refraction); |
|
|
|
} |
|
|
|
// Following loop iterations |
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_ENV || featureFlags & LIGHTFEATUREFLAGS_SKY) |
|
|
|
{ |
|
|
|
// Reflection probes are sorted by volume (in the increasing order). |
|
|
|
|
|
|
|
|
|
|
#ifdef LIGHTLOOP_TILE_PASS |
|
|
|
uint envLightStart; |
|
|
|
uint envLightCount; |
|
|
|
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount); |
|
|
|
#else |
|
|
|
uint envLightCount = _EnvLightCount; |
|
|
|
#endif |
|
|
|
|
|
|
|
#ifdef LIGHTLOOP_TILE_PASS |
|
|
|
uint envLightIndex = FetchIndex(envLightStart, i); |
|
|
|
#else |
|
|
|
uint envLightIndex = i; |
|
|
|
#endif |
|
|
|
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], bsdfData, |
|
|
|
_EnvLightDatas[envLightIndex].influenceShapeType, |
|
|
|
GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight); |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
uint envLightIndex = FETCHINDEX(i); |
|
|
|
EVALUATE_BSDF_ENV(_EnvLightDatas[envLightIndex], REFLECTION, reflection); |
|
|
|
} |
|
|
|
|
|
|
|
// Refraction probe and reflection probe will process exactly the same weight. It will be good for performance to be able to share this computation |
|
|
|
|
|
|
{ |
|
|
|
for (i = 0; i < envLightCount && refractionHierarchyWeight < 1.0; ++i) |
|
|
|
{ |
|
|
|
#ifdef LIGHTLOOP_TILE_PASS |
|
|
|
uint envLightIndex = FetchIndex(envLightStart, i); |
|
|
|
#else |
|
|
|
uint envLightIndex = i; |
|
|
|
#endif |
|
|
|
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], bsdfData, |
|
|
|
_EnvLightDatas[envLightIndex].influenceShapeType, |
|
|
|
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight); |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
uint envLightIndex = FETCHINDEX(i); |
|
|
|
EVALUATE_BSDF_ENV(_EnvLightDatas[envLightIndex], REFRACTION, refraction); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
// The sky data are generated on the fly so the compiler can optimize the code |
|
|
|
EnvLightData envLightSky = InitSkyEnvLightData(0); |
|
|
|
|
|
|
|
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, envLightSky, bsdfData, |
|
|
|
ENVSHAPETYPE_SKY, |
|
|
|
GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight); |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
EVALUATE_BSDF_ENV(envLightSky, REFLECTION, reflection); |
|
|
|
} |
|
|
|
|
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION) |
|
|
|
|
|
|
|
|
|
|
// The sky data are generated on the fly so the compiler can optimize the code |
|
|
|
EnvLightData envLightSky = InitSkyEnvLightData(0); |
|
|
|
|
|
|
|
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, envLightSky, bsdfData, |
|
|
|
ENVSHAPETYPE_SKY, |
|
|
|
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight); |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
EVALUATE_BSDF_ENV(envLightSky, REFRACTION, refraction); |
|
|
|
#undef EVALUATE_BSDF_ENV |
|
|
|
#undef CONCAT |
|
|
|
#undef FETCHINDEX |
|
|
|
|
|
|
|
// Also Apply indiret diffuse (GI) |
|
|
|
// PostEvaluateBSDF will perform any operation wanted by the material and sum everything into diffuseLighting and specularLighting |
|
|
|