|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
float reflectionHierarchyWeight = 0.0; // Max: 1.0 |
|
|
|
float refractionHierarchyWeight = 0.0; // Max: 1.0 |
|
|
|
|
|
|
|
// 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 |
|
|
|
#ifdef LIGHTLOOP_TILE_PASS |
|
|
|
uint envLightStart; |
|
|
|
# define FETCHINDEX(index) FetchIndex(envLightStart, index); |
|
|
|
#else |
|
|
|
# define FETCHINDEX(index) index |
|
|
|
#endif |
|
|
|
uint envLightCount; |
|
|
|
|
|
|
|
#define EVALUATE_BSDF_ENV(envLightData, TYPE, type) {\ |
|
|
|
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, envLightData, bsdfData, \ |
|
|
|
envLightData.influenceShapeType, \ |
|
|
|
MERGE_NAME (GPUIMAGEBASEDLIGHTINGTYPE_, TYPE), MERGE_NAME (type, HierarchyWeight)); \ |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting);\ |
|
|
|
} |
|
|
|
#define EVALUATE_BSDF_ENV(envLightData, TYPE, type) \ |
|
|
|
IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightData, bsdfData, envLightData.influenceShapeType, MERGE_NAME(GPUIMAGEBASEDLIGHTINGTYPE_, TYPE), MERGE_NAME(type, HierarchyWeight)); \ |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
if (featureFlags & ( |
|
|
|
LIGHTFEATUREFLAGS_ENV |
|
|
|
| LIGHTFEATUREFLAGS_SKY |
|
|
|
| LIGHTFEATUREFLAGS_SSREFRACTION |
|
|
|
| LIGHTFEATUREFLAGS_SSREFLECTION |
|
|
|
) |
|
|
|
) |
|
|
|
if (featureFlags & (LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_SSREFRACTION | LIGHTFEATUREFLAGS_SSREFLECTION)) |
|
|
|
float reflectionHierarchyWeight = 0.0; // Max: 1.0 |
|
|
|
float refractionHierarchyWeight = 0.0; // Max: 1.0 |
|
|
|
|
|
|
|
uint envLightStart, envLightCount; |
|
|
|
|
|
|
|
#ifdef LIGHTLOOP_TILE_PASS |
|
|
|
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount); |
|
|
|
#else |
|
|
|
envLightCount = _EnvLightCount; |
|
|
|
envLightStart = 0; |
|
|
|
#endif |
|
|
|
|
|
|
|
// Reflection / Refraction hierarchy is |
|
|
|
// 1. Screen Space Refraction / Reflection |
|
|
|
// 2. Environment Reflection / Refraction |
|
|
|
// 3. Sky Reflection / Refraction |
|
|
|
ZERO_INITIALIZE(EnvLightData, envLightData); |
|
|
|
if (envLightCount > 0) |
|
|
|
#ifdef LIGHTLOOP_TILE_PASS |
|
|
|
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount); |
|
|
|
#else |
|
|
|
envLightCount = _EnvLightCount; |
|
|
|
#endif |
|
|
|
if (envLightCount > 0) |
|
|
|
{ |
|
|
|
uint envLightIndex = FETCHINDEX(0); |
|
|
|
envLightData = _EnvLightDatas[envLightIndex]; |
|
|
|
} |
|
|
|
else |
|
|
|
envLightData = InitSkyEnvLightData(0); |
|
|
|
envLightData = FetchEnvLight(envLightStart, 0); |
|
|
|
|
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION) |
|
|
|
else |
|
|
|
IndirectLighting lighting = EvaluateBSDF_SSLighting( context, V, posInput, preLightData, bsdfData, envLightData, |
|
|
|
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight); |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
envLightData = InitSkyEnvLightData(0); |
|
|
|
} |
|
|
|
|
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFLECTION) |
|
|
|
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
} |
|
|
|
|
|
|
|
if ((featureFlags & LIGHTFEATUREFLAGS_ENV) && envLightCount > 0) |
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION) |
|
|
|
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES; |
|
|
|
|
|
|
|
EVALUATE_BSDF_ENV(envLightData, REFLECTION, reflection); |
|
|
|
|
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION) |
|
|
|
EVALUATE_BSDF_ENV(envLightData, REFRACTION, refraction); |
|
|
|
IndirectLighting lighting = EvaluateBSDF_SSLighting( context, V, posInput, preLightData, bsdfData, envLightData, |
|
|
|
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight); |
|
|
|
AccumulateIndirectLighting(lighting, aggregateLighting); |
|
|
|
} |
|
|
|
// Following loop iterations |
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_ENV || featureFlags & LIGHTFEATUREFLAGS_SKY) |
|
|
|
{ |
|
|
|
// Reflection probes are sorted by volume (in the increasing order). |
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_ENV) |
|
|
|
{ |
|
|
|
|
|
|
for (i = 1; i < envLightCount && reflectionHierarchyWeight < 1.0; ++i) |
|
|
|
for (i = 0; i < envLightCount && reflectionHierarchyWeight < 1.0; ++i) |
|
|
|
uint envLightIndex = FETCHINDEX(i); |
|
|
|
EVALUATE_BSDF_ENV(_EnvLightDatas[envLightIndex], REFLECTION, reflection); |
|
|
|
EVALUATE_BSDF_ENV(FetchEnvLight(envLightStart, i), 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 |
|
|
|
|
|
|
// We reuse LIGHTFEATUREFLAGS_SSREFRACTION flag as refraction is mainly base on the screen. Would be aa waste to not use screen and only cubemap. |
|
|
|
// We reuse LIGHTFEATUREFLAGS_SSREFRACTION flag as refraction is mainly base on the screen. Would be a waste to not use screen and only cubemap. |
|
|
|
for (i = 1; i < envLightCount && refractionHierarchyWeight < 1.0; ++i) |
|
|
|
for (i = 0; i < envLightCount && refractionHierarchyWeight < 1.0; ++i) |
|
|
|
uint envLightIndex = FETCHINDEX(i); |
|
|
|
EVALUATE_BSDF_ENV(_EnvLightDatas[envLightIndex], REFRACTION, refraction); |
|
|
|
EVALUATE_BSDF_ENV(FetchEnvLight(envLightStart, i), REFRACTION, refraction); |
|
|
|
if (featureFlags & LIGHTFEATUREFLAGS_SKY && _EnvLightSkyEnabled) |
|
|
|
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; |
|
|
|
|
|
|
|
// The sky data are generated on the fly so the compiler can optimize the code |
|
|
|
EnvLightData envLightSky = InitSkyEnvLightData(0); |
|
|
|
|
|
|
|
// 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; |
|
|
|
|
|
|
|
// 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); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
// 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; |
|
|
|
|
|
|
|
// The sky data are generated on the fly so the compiler can optimize the code |
|
|
|
EnvLightData envLightSky = InitSkyEnvLightData(0); |
|
|
|
EVALUATE_BSDF_ENV(envLightSky, REFRACTION, refraction); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
#undef FETCHINDEX |
|
|
|
|
|
|
|
// Also Apply indiret diffuse (GI) |
|
|
|
// PostEvaluateBSDF will perform any operation wanted by the material and sum everything into diffuseLighting and specularLighting |
|
|
|