浏览代码

HDRenderPipeline: Refactor LightLoop glue code

- add a "Lighting" structure in material that replace LightAccumulator
- use it in all prototype
- Material now apply the weights
/Add-support-for-light-specular-color-tint
Sebastien Lagarde 7 年前
当前提交
935bfd9b
共有 11 个文件被更改,包括 201 次插入202 次删除
  1. 6
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Deferred.shader
  2. 2
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Deferred.compute
  3. 20
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  4. 19
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl
  5. 18
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  6. 104
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  7. 181
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  8. 32
      ScriptableRenderPipeline/HDRenderPipeline/Material/Material.hlsl
  9. 13
      ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl
  10. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/UnlitData.hlsl
  11. 6
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl

6
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Deferred.shader


UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
uint featureFlags = 0xFFFFFFFF;
DECODE_FROM_GBUFFER(gbuffer, featureFlags, bsdfData, bakeDiffuseLighting);
DECODE_FROM_GBUFFER(gbuffer, MATERIAL_FEATURE_MASK_FLAGS, bsdfData, bakeDiffuseLighting);
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, featureFlags, diffuseLighting, specularLighting);
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, LIGHT_FEATURE_MASK_FLAGS_OPAQUE, diffuseLighting, specularLighting);
Outputs outputs;
#ifdef OUTPUT_SPLIT_LIGHTING

2
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Deferred.compute


{
uint2 tileCoord = (16 * groupId) / GetTileSize();
uint2 pixelCoord = dispatchThreadId;
uint featureFlags = 0xFFFFFFFF;
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIAL_FEATURE_MASK_FLAGS;
#endif

20
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


public enum LightFeatureFlags
{
// Light bit mask must match LightDefinitions.s_LightFeatureMaskFlags value
Punctual = 1 << 8,
Area = 1 << 9,
Directional = 1 << 10,
Env = 1 << 11,
Sky = 1 << 12,
SSL = 1 << 13 // If adding more light be sure to not overflow LightDefinitions.s_LightFeatureMaskFlags
Punctual = 1 << 12,
Area = 1 << 13,
Directional = 1 << 14,
Env = 1 << 15,
Sky = 1 << 16,
SSRefraction = 1 << 17,
SSReflection = 1 << 18,
// If adding more light be sure to not overflow LightDefinitions.s_LightFeatureMaskFlags
}
[GenerateHLSL]

public static int s_NumFeatureVariants = 27;
// Following define the maximum number of bits use in each feature category.
public static uint s_LightFeatureMaskFlags = 0xFF00;
public static uint s_MaterialFeatureMaskFlags = 0x00FF; // don't use all bits just to be safe from signed and/or float conversions :/
public static uint s_LightFeatureMaskFlags = 0xFFF000;
public static uint s_LightFeatureMaskFlagsOpaque = 0xFFF000 & ~((uint)LightFeatureFlags.SSRefraction); // Opaque don't support screen space refraction
public static uint s_LightFeatureMaskFlagsTransparent = 0xFFF000 & ~((uint)LightFeatureFlags.SSReflection); // Transparent don't support screen space reflection
public static uint s_MaterialFeatureMaskFlags = 0x000FFF; // don't use all bits just to be safe from signed and/or float conversions :/
}
[GenerateHLSL]

19
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs.hlsl


//
// UnityEngine.Experimental.Rendering.HDPipeline.TilePass.LightFeatureFlags: static fields
//
#define LIGHTFEATUREFLAGS_PUNCTUAL (256)
#define LIGHTFEATUREFLAGS_AREA (512)
#define LIGHTFEATUREFLAGS_DIRECTIONAL (1024)
#define LIGHTFEATUREFLAGS_ENV (2048)
#define LIGHTFEATUREFLAGS_SKY (4096)
#define LIGHTFEATUREFLAGS_SSL (8192)
#define LIGHTFEATUREFLAGS_PUNCTUAL (4096)
#define LIGHTFEATUREFLAGS_AREA (8192)
#define LIGHTFEATUREFLAGS_DIRECTIONAL (16384)
#define LIGHTFEATUREFLAGS_ENV (32768)
#define LIGHTFEATUREFLAGS_SKY (65536)
#define LIGHTFEATUREFLAGS_SSREFRACTION (131072)
#define LIGHTFEATUREFLAGS_SSREFLECTION (262144)
//
// UnityEngine.Experimental.Rendering.HDPipeline.TilePass.LightDefinitions: static fields

#define TILE_SIZE_FPTL (16)
#define TILE_SIZE_CLUSTERED (32)
#define NUM_FEATURE_VARIANTS (27)
#define LIGHT_FEATURE_MASK_FLAGS (65280)
#define MATERIAL_FEATURE_MASK_FLAGS (255)
#define LIGHT_FEATURE_MASK_FLAGS (16773120)
#define LIGHT_FEATURE_MASK_FLAGS_OPAQUE (16642048)
#define LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT (16510976)
#define MATERIAL_FEATURE_MASK_FLAGS (4095)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.TilePass.SFiniteLightBound
// PackingRules = Exact

18
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl


ShadowContext shadowContext;
};
// Store all the accumulated lighting produce by the light loop
struct LightLoopAccumulatedLighting
{
float3 dirDiffuseLighting;
float3 dirSpecularLighting;
float3 punctualDiffuseLighting;
float3 punctualSpecularLighting;
float3 areaDiffuseLighting;
float3 areaSpecularLighting;
float3 envDiffuseLighting;
float3 envSpecularLighting;
float envDiffuseLightingWeight;
};
//-----------------------------------------------------------------------------
// Cookie sampling functions
// ----------------------------------------------------------------------------

104
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl


#endif // LIGHTLOOP_TILE_PASS
void applyWeigthedIblLighting(float3 localDiffuseLighting, float3 localSpecularLighting, float2 weight, inout float3 iblDiffuseLighting, inout float3 iblSpecularLighting, inout float totalIblWeight)
{
// IBL weights should not exceed 1.
float accumulatedWeight = totalIblWeight + weight.y;
totalIblWeight = saturate(accumulatedWeight);
weight.y -= saturate(accumulatedWeight - totalIblWeight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x);
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BSDFData bsdfData, float3 bakeDiffuseLighting, uint featureFlags,
out float3 diffuseLighting,

context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
// This struct is use to store accumulated lighting, summation is done in PostEvaluateBSDF
LightLoopAccumulatedLighting accLighting;
ZERO_INITIALIZE(LightLoopAccumulatedLighting, accLighting);
// This struct is define in the material. the Lightloop must not access it
// PostEvaluateBSDF call at the end will convert Lighting to diffuse and specular lighting
Lighting lighting;
ZERO_INITIALIZE(Lighting, lighting); // LightLoop is in charge of initializing the struct
uint i = 0; // Declare once to avoid the D3D11 compiler warning.

{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional(context, V, posInput, preLightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
accLighting.dirDiffuseLighting += localDiffuseLighting;
accLighting.dirSpecularLighting += localSpecularLighting;
EvaluateBSDF_Directional(context, V, posInput, preLightData, _DirectionalLightDatas[i], bsdfData, lighting);
}
}

for (i = 0; i < punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, preLightData, _LightDatas[punctualIndex], bsdfData, _LightDatas[punctualIndex].lightType,
localDiffuseLighting, localSpecularLighting);
accLighting.punctualDiffuseLighting += localDiffuseLighting;
accLighting.punctualSpecularLighting += localSpecularLighting;
EvaluateBSDF_Punctual(context, V, posInput, preLightData, _LightDatas[punctualIndex], bsdfData, _LightDatas[punctualIndex].lightType, lighting);
}
#else

float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, preLightData, _LightDatas[i], bsdfData, _LightDatas[i].lightType,
localDiffuseLighting, localSpecularLighting);
accLighting.punctualDiffuseLighting += localDiffuseLighting;
accLighting.punctualSpecularLighting += localSpecularLighting;
EvaluateBSDF_Punctual(context, V, posInput, preLightData, _LightDatas[i], bsdfData, _LightDatas[i].lightType, lighting);
}
#endif

while (i < areaLightCount && lightType == GPULIGHTTYPE_LINE)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Area( context, V, posInput, preLightData, _LightDatas[areaIndex], bsdfData, GPULIGHTTYPE_LINE,
localDiffuseLighting, localSpecularLighting);
accLighting.areaDiffuseLighting += localDiffuseLighting;
accLighting.areaSpecularLighting += localSpecularLighting;
EvaluateBSDF_Area(context, V, posInput, preLightData, _LightDatas[areaIndex], bsdfData, GPULIGHTTYPE_LINE, lighting);
i++;
areaIndex = i < areaLightCount ? FetchIndex(areaLightStart, i) : 0;
lightType = i < areaLightCount ? _LightDatas[areaIndex].lightType : 0xFF;

{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Area( context, V, posInput, preLightData, _LightDatas[areaIndex], bsdfData, GPULIGHTTYPE_RECTANGLE,
localDiffuseLighting, localSpecularLighting);
accLighting.areaDiffuseLighting += localDiffuseLighting;
accLighting.areaSpecularLighting += localSpecularLighting;
EvaluateBSDF_Area(context, V, posInput, preLightData, _LightDatas[areaIndex], bsdfData, GPULIGHTTYPE_RECTANGLE, lighting);
i++;
areaIndex = i < areaLightCount ? FetchIndex(areaLightStart, i) : 0;
lightType = i < areaLightCount ? _LightDatas[areaIndex].lightType : 0xFF;

#else
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Area( context, V, posInput, preLightData, _LightDatas[i], bsdfData, _LightDatas[i].lightType,
localDiffuseLighting, localSpecularLighting);
accLighting.areaDiffuseLighting += localDiffuseLighting;
accLighting.areaSpecularLighting += localSpecularLighting;
EvaluateBSDF_Area(context, V, posInput, preLightData, _LightDatas[i], bsdfData, _LightDatas[i].lightType, lighting);
float totalIblWeight = 0.0; // Max: 1
float reflectionHierarchyWeight = 0.0; // Max: 1.0
float refractionHierarchyWeight = 0.0; // Max: 1.0
if (featureFlags & LIGHTFEATUREFLAGS_SSL)
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION)
// SSR and rough refraction
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
EvaluateBSDF_SSL(V, posInput, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
applyWeigthedIblLighting(localDiffuseLighting, localSpecularLighting, weight, accLighting.envDiffuseLighting, accLighting.envSpecularLighting, totalIblWeight);
accLighting.envDiffuseLightingWeight = weight.x;
EvaluateBSDF_SSRefraction(context, V, posInput, preLightData, bsdfData, lighting, refractionHierarchyWeight);
}
if (featureFlags & LIGHTFEATUREFLAGS_SSREFLECTION)
{
EvaluateBSDF_SSReflection(context, V, posInput, preLightData, bsdfData, lighting, reflectionHierarchyWeight);
}
if (featureFlags & LIGHTFEATUREFLAGS_ENV || featureFlags & LIGHTFEATUREFLAGS_SKY)

{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
#ifdef LIGHTLOOP_TILE_PASS

#endif
// Note: In case of IBL we are sorted from smaller to bigger projected solid angle bounds. We are not sorted by type so we can't do a 'while' approach like for area light.
for (i = 0; i < envLightCount && totalIblWeight < 1.0; ++i)
for (i = 0; i < envLightCount && reflectionHierarchyWeight < 1.0; ++i)
{
#ifdef LIGHTLOOP_TILE_PASS
uint envLightIndex = FetchIndex(envLightStart, i);

EvaluateBSDF_Env(context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], bsdfData, _EnvLightDatas[envLightIndex].envShapeType, localDiffuseLighting, localSpecularLighting, weight);
applyWeigthedIblLighting(localDiffuseLighting, localSpecularLighting, weight, accLighting.envDiffuseLighting, accLighting.envSpecularLighting, totalIblWeight);
EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], bsdfData, _EnvLightDatas[envLightIndex].envShapeType,
lighting, reflectionHierarchyWeight);
}
}

if (_EnvLightSkyEnabled && totalIblWeight < 1.0)
if (_EnvLightSkyEnabled && reflectionHierarchyWeight < 1.0)
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
EvaluateBSDF_Env(context, V, posInput, preLightData, envLightSky, bsdfData, ENVSHAPETYPE_SKY, localDiffuseLighting, localSpecularLighting, weight);
applyWeigthedIblLighting(localDiffuseLighting, localSpecularLighting, weight, accLighting.envDiffuseLighting, accLighting.envSpecularLighting, totalIblWeight);
EvaluateBSDF_Env(context, V, posInput, preLightData, envLightSky, bsdfData, ENVSHAPETYPE_SKY, lighting, reflectionHierarchyWeight);
}
}
}

PostEvaluateBSDF( context, V, posInput, preLightData, accLighting, bsdfData, bakeDiffuseLighting,
PostEvaluateBSDF( context, V, posInput, preLightData, bsdfData, bakeDiffuseLighting, lighting,
diffuseLighting, specularLighting);
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);

181
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


/* 2 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_AREA | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 3 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 4 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 5 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 5 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_STANDARD,
// SSS
/* 6 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_SSS,

/* 10 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_SSS,
/* 10 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_SSS,
// Aniso
/* 11 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_ANISO,

/* 15 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_ANISO,
/* 15 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_ANISO,
// With foliage or crowd with SSS and standard can overlap a lot, better to have a dedicated combination
/* 16 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,

/* 20 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 20 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_SSS | MATERIALFEATUREFLAGS_LIT_STANDARD,
// ClearCoat
/* 21 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,

/* 25 */ LIGHT_FEATURE_MASK_FLAGS | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 25 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT,
/* 26 */ LIGHT_FEATURE_MASK_FLAGS | MATERIAL_FEATURE_MASK_FLAGS, // Catch all case with MATERIAL_FEATURE_MASK_FLAGS is needed in case we disable material classification
/* 26 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIAL_FEATURE_MASK_FLAGS, // Catch all case with MATERIAL_FEATURE_MASK_FLAGS is needed in case we disable material classification
};
uint FeatureFlagsToTileVariant(uint featureFlags)

// We deem the intensity difference of a couple of percent for high values of roughness
// to not be worth the cost of another precomputed table.
// Note: this formulation bakes the BSDF non-symmetric!
preLightData.energyCompensation = 1 / reflectivity - 1;
preLightData.energyCompensation = 1.0 / reflectivity - 1.0;
preLightData.energyCompensation = 0;
preLightData.energyCompensation = 0.0;
#endif // LIT_USE_GGX_ENERGY_COMPENSATION
// Area light

#ifdef HAS_LIGHTLOOP
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
// This structure allow to accumulate lighting accross the Lit material
// It is init to zero and transfer by the LightLoop, but the LightLoop can't access its content.
struct Lighting
{
float3 directDiffuse;
float3 directSpecular;
float3 refraction;
float3 envSpecular;
};
//-----------------------------------------------------------------------------
// BSDF share between directional light, punctual light and area light (reference)
//-----------------------------------------------------------------------------

}
else
{
isInBounds = Max3(abs(positionNDC.x), abs(positionNDC.y), 1 - positionLS.z) <= 1;
isInBounds = Max3(abs(positionNDC.x), abs(positionNDC.y), 1.0 - positionLS.z) <= 1.0;
}
// We let the sampler handle tiling or clamping to border.

cookie.a = isInBounds ? cookie.a : 0;
cookie.a = isInBounds ? cookie.a : 0.0;
return cookie;
}

DirectionalLightData lightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting)
inout Lighting lighting)
{
float3 positionWS = posInput.positionWS;

diffuseLighting = float3(0, 0, 0); // TODO: check whether using 'out' instead of 'inout' increases the VGPR pressure
specularLighting = float3(0, 0, 0); // TODO: check whether using 'out' instead of 'inout' increases the VGPR pressure
float3 diffuseLighting = float3(0, 0, 0);
float3 specularLighting = float3(0, 0, 0);
float shadow = 1;
[branch] if (lightData.shadowIndex >= 0)

// Save ALU by applying 'lightData.color' only once.
diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
lighting.directDiffuse += diffuseLighting;
lighting.directSpecular += specularLighting;
}
//-----------------------------------------------------------------------------

void EvaluateBSDF_Punctual( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData, int GPULightType,
out float3 diffuseLighting,
out float3 specularLighting)
inout Lighting lighting)
{
float3 positionWS = posInput.positionWS;
int lightType = GPULightType;

lightData.diffuseScale *= attenuation;
lightData.specularScale *= attenuation;
diffuseLighting = float3(0, 0, 0); // TODO: check whether using 'out' instead of 'inout' increases the VGPR pressure
specularLighting = float3(0, 0, 0); // TODO: check whether using 'out' instead of 'inout' increases the VGPR pressure
float shadow = 1;
float3 diffuseLighting = float3(0.0, 0.0, 0.0);
float3 specularLighting = float3(0.0, 0.0, 0.0);
float shadow = 1.0;
[branch] if (lightData.shadowIndex >= 0)
{

// Save ALU by applying 'lightData.color' only once.
diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
lighting.directDiffuse += diffuseLighting;
lighting.directSpecular += specularLighting;
}
#include "LitReference.hlsl"

void EvaluateBSDF_Line(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData,
out float3 diffuseLighting, out float3 specularLighting)
inout Lighting lighting)
float3 diffuseLighting = float3(0.0, 0.0, 0.0);
float3 specularLighting = float3(0.0, 0.0, 0.0);
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
float len = lightData.size.x;
float3 T = lightData.right;

diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
#endif // LIT_DISPLAY_REFERENCE_AREA
lighting.directDiffuse += diffuseLighting;
lighting.directSpecular += specularLighting;
}
//-----------------------------------------------------------------------------

void EvaluateBSDF_Rect( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightData lightData, BSDFData bsdfData,
out float3 diffuseLighting, out float3 specularLighting)
inout Lighting lighting)
float3 diffuseLighting = float3(0.0, 0.0, 0.0);
float3 specularLighting = float3(0.0, 0.0, 0.0);
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
float3 unL = lightData.positionWS - positionWS;
[branch]

diffuseLighting *= lightData.color;
specularLighting *= lightData.color;
#endif // LIT_DISPLAY_REFERENCE_AREA
lighting.directDiffuse += diffuseLighting;
lighting.directSpecular += specularLighting;
out float3 diffuseLighting, out float3 specularLighting)
inout Lighting lighting)
EvaluateBSDF_Line(lightLoopContext, V, posInput, preLightData, lightData, bsdfData, diffuseLighting, specularLighting);
EvaluateBSDF_Line(lightLoopContext, V, posInput, preLightData, lightData, bsdfData, lighting);
EvaluateBSDF_Rect(lightLoopContext, V, posInput, preLightData, lightData, bsdfData, diffuseLighting, specularLighting);
EvaluateBSDF_Rect(lightLoopContext, V, posInput, preLightData, lightData, bsdfData, lighting);
// EvaluateBSDF_SSL
// EvaluateBSDF_SSLighting for screen space lighting
void EvaluateBSDF_SSL(float3 V, PositionInputs posInput, BSDFData bsdfData, out float3 diffuseLighting, out float3 specularLighting, out float2 weight)
void EvaluateBSDF_SSReflection( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, BSDFData bsdfData,
inout Lighting lighting, inout float hierarchyWeight)
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
weight = float2(0.0, 0.0);
// TODO
}
void EvaluateBSDF_SSRefraction( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, BSDFData bsdfData,
inout Lighting lighting, inout float hierarchyWeight)
{
// 3. If this point is available (ie: in color GBuffer and point is not in front of the object)
// 3. If this point is available (ie: in color buffer and point is not in front of the object)
weight.x = bsdfData.transmittanceMask;
float3 diffuseLighting = float3(0.0, 0.0, 0.0);
float3 refractedBackPointWS = float3(0.0, 0.0, 0.0);
float opticalDepth = 0.0;

// we approximate the scene as a plane (back plane) with normal -V at the depth hit point.
// (We avoid to raymarch the depth texture to get the refracted point.)
#if defined(_REFRACTION_PLANE)
// Plane shape model:
// We approximate locally the shape of the object as a plane with normal {bsdfData.normalWS} at {bsdfData.positionWS}
// with a thickness {bsdfData.thickness}
// Plane shape model:
// We approximate locally the shape of the object as a plane with normal {bsdfData.normalWS} at {bsdfData.positionWS}
// with a thickness {bsdfData.thickness}
// Refracted ray
// Refracted ray
// Get the depth of the approximated back plane
// Get the depth of the approximated back plane
// Distance from point to the back plane
// Distance from point to the back plane
// Optical depth within the thin plane
// Optical depth within the thin plane
// The refracted ray exiting the thin plane is the same as the incident ray (parallel interfaces and same ior)
// The refracted ray exiting the thin plane is the same as the incident ray (parallel interfaces and same ior)
float VoR = dot(-V, R);
float VoN = dot(V, bsdfData.normalWS);
refractedBackPointWS = posInput.positionWS + R * opticalDepth - V * (distFromP - VoR * opticalDepth);

|| any(refractedBackPointSS > 1.0))
{
diffuseLighting = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb;
// TODO: check with fred. If a pixel is in front of the object we should not sample at all and put hierarchyWeight to 1.0 so we discard the effect as it is occlusion
// Otherwise fallback on cubemap
return;
}

// Beer-Lamber law for absorption
float3 transmittance = exp(-bsdfData.absorptionCoefficient * opticalDepth);
diffuseLighting *= transmittance;
#endif // HAS_REFRACTION
float weight = 1.0;
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
lighting.refraction += diffuseLighting * weight;
#else
// No refraction, no need to go further
hierarchyWeight = 1.0;
#endif
}
//-----------------------------------------------------------------------------

void EvaluateBSDF_Env( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int envShapeType,
out float3 diffuseLighting, out float3 specularLighting, out float2 weight)
inout Lighting lighting, inout float hierarchyWeight)
weight = float2(0.0, 1.0);
float3 specularLighting = float3(0.0, 0.0, 0.0);
float weight = 1.0;
#ifdef LIT_DISPLAY_REFERENCE_IBL

#ifdef LIT_DIFFUSE_LAMBERT_BRDF
diffuseLighting = IntegrateLambertIBLRef(lightData, V, bsdfData);
lighting.directDiffuse += IntegrateLambertIBLRef(lightData, V, bsdfData);
diffuseLighting = IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
lighting.directDiffuse += IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
diffuseLighting = float3(0.0, 0.0, 0.0);
hierarchyWeight = 0.0;
#else

// 2. Process the influence
float distFade = max(length(positionLS) - lightData.innerDistance.x, 0.0);
weight.y = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero
weight = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero
}
else if (envShapeType == ENVSHAPETYPE_BOX)
{

// Influence volume
// Calculate falloff value, so reflections on the edges of the volume would gradually blend to previous reflection.
float distFade = DistancePointBox(positionLS, -lightData.innerDistance, lightData.innerDistance);
weight.y = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero
weight = saturate(1.0 - distFade / max(lightData.blendDistance, 0.0001)); // avoid divide by zero
weight.y = Smoothstep01(weight.y);
weight = Smoothstep01(weight);
specularLighting = float3(0.0, 0.0, 0.0);
// Evaluate the Clear Coat component if needed and change the BSDF roughness to match Fresnel transmission
if (bsdfData.materialId == MATERIALID_LIT_CLEAR_COAT && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))

float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, R, preLightData.iblMipLevel);
specularLighting += F * preLD.rgb * preLightData.specularFGD;
diffuseLighting = float3(0.0, 0.0, 0.0);
#endif
#endif
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
lighting.envSpecular += specularLighting * weight;
}
//-----------------------------------------------------------------------------

void PostEvaluateBSDF( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, LightLoopAccumulatedLighting accLighting, BSDFData bsdfData, float3 bakeDiffuseLighting,
PreLightData preLightData, BSDFData bsdfData, float3 bakeDiffuseLighting, Lighting lighting,
out float3 diffuseLighting, out float3 specularLighting)
{
// Use GTAOMultiBounce approximation for ambient occlusion (allow to get a tint from the baseColor)

// Try to mimic multibounce with specular color. Not the point of the original formula but ok result.
// Take the min of screenspace specular occlusion and visibility cone specular occlusion
#if GTAO_MULTIBOUNCE_APPROX
accLighting.envSpecularLighting *= GTAOMultiBounce(min(bsdfData.specularOcclusion, specularOcclusion), bsdfData.fresnel0);
lighting.envSpecular *= GTAOMultiBounce(min(bsdfData.specularOcclusion, specularOcclusion), bsdfData.fresnel0);
accLighting.envSpecularLighting *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(bsdfData.specularOcclusion, specularOcclusion));
lighting.envSpecular *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(bsdfData.specularOcclusion, specularOcclusion));
float3 directDiffuseLighting = (accLighting.dirDiffuseLighting + accLighting.punctualDiffuseLighting + accLighting.areaDiffuseLighting)
lighting.directDiffuse *=
* GTAOMultiBounce(directAmbientOcclusion, bsdfData.diffuseColor);
GTAOMultiBounce(directAmbientOcclusion, bsdfData.diffuseColor);
* lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), directAmbientOcclusion);
lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), directAmbientOcclusion);
#endif
diffuseLighting = lighting.directDiffuse + bakeDiffuseLighting;
// If refraction is enable we use the transmittanceMask to lerp between current diffuse lighting and refraction value
// Physically speaking, it should be transmittanceMask should be 1, but for artistic reasons, we let the value varie
#if HAS_REFRACTION
diffuseLighting = lerp(diffuseLighting, lighting.refraction, bsdfData.transmittanceMask);
// envDiffuseLighting is used for refraction in this Lit material. Use the weight to balance between transmission and reflection
diffuseLighting = lerp(directDiffuseLighting + bakeDiffuseLighting, accLighting.envDiffuseLighting, accLighting.envDiffuseLightingWeight);
specularLighting = accLighting.dirSpecularLighting + accLighting.punctualSpecularLighting + accLighting.areaSpecularLighting + accLighting.envSpecularLighting;
specularLighting = lighting.directSpecular + lighting.envSpecular;
specularLighting *= 1 + bsdfData.fresnel0 * preLightData.energyCompensation;
specularLighting *= 1.0 + bsdfData.fresnel0 * preLightData.energyCompensation;
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO)

#endif
#endif
}
#endif // #ifdef HAS_LIGHTLOOP

32
ScriptableRenderPipeline/HDRenderPipeline/Material/Material.hlsl


return result;
}
//-----------------------------------------------------------------------------
// Alpha test replacement
//-----------------------------------------------------------------------------
// This function must be use instead of clip instruction. It allow to manage in which case the clip is perform
void DoAlphaTest(float alpha, float alphaCutoff)
{
// For Deferred:
// If we have a prepass, we need to remove the clip from the GBuffer pass (otherwise HiZ does not work on PS4) - SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
// For Forward (Lit or Unlit)
// Opaque geometry always has a depth pre-pass so we never want to do the clip here. For transparent we perform the clip as usual.
// Also no alpha test for light transport
#if !(SHADERPASS == SHADERPASS_FORWARD && !defined(_SURFACE_TYPE_TRANSPARENT)) && !(SHADERPASS == SHADERPASS_FORWARD_UNLIT && !defined(_SURFACE_TYPE_TRANSPARENT)) && !defined(SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST) && !(SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)
clip(alpha - alphaCutoff);
#endif
}
//-----------------------------------------------------------------------------
// Reflection / Refraction hierarchy handling
//-----------------------------------------------------------------------------
// This function is use with reflection and refraction hierarchy of LightLoop
// It will add weight to hierarchyWeight but ensure that hierarchyWeight is not more than one
// by updating the weight value. Returned weight value must be apply on current lighting
// Example: Total hierarchyWeight is 0.8 and weight is 0.4. Function return hierarchyWeight of 1.0 and weight of 0.2
// hierarchyWeight and weight must be positive and between 0 and 1
void UpdateLightingHierarchyWeights(inout float hierarchyWeight, inout float weight)
{
float accumulatedWeight = hierarchyWeight + weight;
hierarchyWeight = saturate(accumulatedWeight);
weight -= saturate(accumulatedWeight - hierarchyWeight);
}
//-----------------------------------------------------------------------------
// BuiltinData

13
ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl


#endif
}
// This function must be use instead of clip instruction. It allow to manage in which case the clip is perform
void DoAlphaTest(float alpha, float alphaCutoff)
{
// For Deferred:
// If we have a prepass, we need to remove the clip from the GBuffer pass (otherwise HiZ does not work on PS4) - SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
// For Forward (Lit or Unlit)
// Opaque geometry always has a depth pre-pass so we never want to do the clip here. For transparent we perform the clip as usual.
// Also no alpha test for light transport
#if !(SHADERPASS == SHADERPASS_FORWARD && !defined(_SURFACE_TYPE_TRANSPARENT)) && !(SHADERPASS == SHADERPASS_FORWARD_UNLIT && !defined(_SURFACE_TYPE_TRANSPARENT)) && !defined(SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST) && !(SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)
clip(alpha - alphaCutoff);
#endif
}
float2 CalculateVelocity(float4 positionCS, float4 previousPositionCS)
{
// This test on define is required to remove warning of divide by 0 when initializing empty struct

2
ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/UnlitData.hlsl


#include "../MaterialUtilities.hlsl"
//-------------------------------------------------------------------------------------
// Fill SurfaceData/Builtin data function
//-------------------------------------------------------------------------------------

6
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl


if (_DebugLightingMode != DEBUGLIGHTINGMODE_NONE)
#endif
{
uint featureFlags = 0xFFFFFFFF;
#ifdef _SURFACE_TYPE_TRANSPARENT
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT;
#else
uint featureFlags = LIGHT_FEATURE_MASK_FLAGS_OPAQUE;
#endif
float3 diffuseLighting;
float3 specularLighting;
float3 bakeDiffuseLighting = GetBakedDiffuseLigthing(surfaceData, builtinData, bsdfData, preLightData);

正在加载...
取消
保存