浏览代码

HDRenderPipeline: Sharing envlight code

/main
Sebastien Lagarde 6 年前
当前提交
4a161d5a
共有 5 个文件被更改,包括 110 次插入133 次删除
  1. 9
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/ImageBasedLighting.hlsl
  2. 48
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl
  3. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/VolumeProjection.hlsl
  4. 116
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  5. 60
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.hlsl

9
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/ImageBasedLighting.hlsl


return lerp(N, R, lerpFactor);
}
// To simulate the streching of highlight at grazing angle for IBL we shrink the roughness
// which allow to fake an anisotropic specular lobe.
// Ref: http://www.frostbite.com/2015/08/stochastic-screen-space-reflections/ - slide 84
real AnisotropicStrechAtGrazingAngle(real perceptualRoughness, real NdotV)
{
real p = perceptualRoughness;
return p * lerp(saturate(NdotV * 2.0) * p, p, p);
}
// ----------------------------------------------------------------------------
// Importance sampling BSDF functions
// ----------------------------------------------------------------------------

48
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl


attenuation *= shadow;
}
#include "Reflection/VolumeProjection.hlsl"
void EvaluateLight_EnvIntersection(float3 positionWS, float3 normalWS, EnvLightData lightData, int influenceShapeType, inout float3 R, inout float weight)
{
// Guideline for reflection volume: In HDRenderPipeline we separate the projection volume (the proxy of the scene) from the influence volume (what pixel on the screen is affected)
// However we add the constrain that the shape of the projection and influence volume is the same (i.e if we have a sphere shape projection volume, we have a shape influence).
// It allow to have more coherence for the dynamic if in shader code.
// Users can also chose to not have any projection, in this case we use the property minProjectionDistance to minimize code change. minProjectionDistance is set to huge number
// that simulate effect of no shape projection
float3x3 worldToIS = WorldToInfluenceSpace(lightData);
float3 positionIS = WorldToInfluencePosition(lightData, worldToIS, positionWS);
float3 dirIS = mul(R, worldToIS);
float3x3 worldToPS = WorldToProxySpace(lightData);
float3 positionPS = WorldToProxyPosition(lightData, worldToPS, positionWS);
float3 dirPS = mul(R, worldToPS);
float projectionDistance = 0;
// Process the projection
// In Unity the cubemaps are capture with the localToWorld transform of the component.
// This mean that location and orientation matter. So after intersection of proxy volume we need to convert back to world.
if (influenceShapeType == ENVSHAPETYPE_SPHERE)
{
projectionDistance = IntersectSphereProxy(lightData, dirPS, positionPS);
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.capturePositionWS
float3 capturePositionWS = lightData.capturePositionWS;
R = (positionWS + projectionDistance * R) - capturePositionWS;
weight = InfluenceSphereWeight(lightData, normalWS, positionWS, positionIS, dirIS);
}
else if (influenceShapeType == ENVSHAPETYPE_BOX)
{
projectionDistance = IntersectBoxProxy(lightData, dirPS, positionPS);
// No need to normalize for fetching cubemap
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.capturePositionWS
float3 capturePositionWS = lightData.capturePositionWS;
R = (positionWS + projectionDistance * R) - capturePositionWS;
weight = InfluenceBoxWeight(lightData, normalWS, positionWS, positionIS, dirIS);
}
// Smooth weighting
weight = Smoothstep01(weight);
weight *= lightData.weight;
}

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/VolumeProjection.hlsl


#define ENVMAP_FEATURE_PERFACEFADE
#define ENVMAP_FEATURE_INFLUENCENORMAL
#include "../LightDefinition.cs.hlsl"
float3x3 WorldToProxySpace(EnvLightData lightData)
{
return transpose(

return projectionDistance;
}
float InfluenceSphereWeight(EnvLightData lightData, BSDFData bsdfData, float3 positionWS, float3 positionLS, float3 dirLS)
float InfluenceSphereWeight(EnvLightData lightData, float3 normalWS, float3 positionWS, float3 positionLS, float3 dirLS)
{
float lengthPositionLS = length(positionLS);
float sphereInfluenceDistance = lightData.influenceExtents.x - lightData.blendDistancePositive.x;

#if defined(ENVMAP_FEATURE_INFLUENCENORMAL)
float insideInfluenceNormalVolume = lengthPositionLS <= (lightData.influenceExtents.x - lightData.blendNormalDistancePositive.x) ? 1.0 : 0.0;
float insideWeight = InfluenceFadeNormalWeight(bsdfData.normalWS, normalize(positionWS - lightData.capturePositionWS));
float insideWeight = InfluenceFadeNormalWeight(normalWS, normalize(positionWS - lightData.capturePositionWS));
alpha *= insideInfluenceNormalVolume ? 1.0 : insideWeight;
#endif

float InfluenceBoxWeight(EnvLightData lightData, BSDFData bsdfData, float3 positionWS, float3 positionIS, float3 dirIS)
float InfluenceBoxWeight(EnvLightData lightData, float3 normalWS, float3 positionWS, float3 positionIS, float3 dirIS)
{
float3 influenceExtents = lightData.influenceExtents;
// 2. Process the position influence

float3 belowPositiveInfluenceNormalVolume = positiveDistance / max(0.0001, lightData.blendNormalDistancePositive);
float3 aboveNegativeInfluenceNormalVolume = negativeDistance / max(0.0001, lightData.blendNormalDistanceNegative);
float insideInfluenceNormalVolume = all(belowPositiveInfluenceNormalVolume >= 1.0) && all(aboveNegativeInfluenceNormalVolume >= 1.0) ? 1.0 : 0;
float insideWeight = InfluenceFadeNormalWeight(bsdfData.normalWS, normalize(positionWS - lightData.capturePositionWS));
float insideWeight = InfluenceFadeNormalWeight(normalWS, normalize(positionWS - lightData.capturePositionWS));
alpha *= insideInfluenceNormalVolume ? 1.0 : insideWeight;
#endif

116
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


//-----------------------------------------------------------------------------
#if HAS_REFRACTION
# include "CoreRP/ShaderLibrary/Refraction.hlsl"
# include "HDRP/Lighting/Reflection/VolumeProjection.hlsl"
# include "HDRP/Lighting/LightDefinition.cs.hlsl"
# define SSRTID Refraction
# include "HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl"
# undef SSRTID
#include "CoreRP/ShaderLibrary/Refraction.hlsl"
#include "HDRP/Lighting/LightDefinition.cs.hlsl"
#include "HDRP/Lighting/Reflection/VolumeProjection.hlsl"
#define SSRTID Refraction
#include "HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl"
#undef SSRTID
# if defined(_REFRACTION_PLANE)
# define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModelPlane(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
# elif defined(_REFRACTION_SPHERE)
# define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModelSphere(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
# endif
#if defined(_REFRACTION_PLANE)
#define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModelPlane(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
#elif defined(_REFRACTION_SPHERE)
#define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModelSphere(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
#endif
# if defined(_REFRACTION_SSRAY_PROXY)
# define REFRACTION_SSRAY_IN ScreenSpaceProxyRaycastInput
# define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceProxyRaycastRefraction(input, hit)
# elif defined(_REFRACTION_SSRAY_HIZ)
# define REFRACTION_SSRAY_IN ScreenSpaceHiZRaymarchInput
# define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceHiZRaymarchRefraction(input, hit)
# endif
#if defined(_REFRACTION_SSRAY_PROXY)
#define REFRACTION_SSRAY_IN ScreenSpaceProxyRaycastInput
#define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceProxyRaycastRefraction(input, hit)
#elif defined(_REFRACTION_SSRAY_HIZ)
#define REFRACTION_SSRAY_IN ScreenSpaceHiZRaymarchInput
#define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceHiZRaymarchRefraction(input, hit)
#endif
#endif
// This method allows us to know at compile time what material features should be removed from the code by Tile (Indepenently of the value of material feature flag per pixel).

#endif
#include "../../Lighting/LightEvaluation.hlsl"
#include "../../Lighting/Reflection/VolumeProjection.hlsl"
//-----------------------------------------------------------------------------
// Lighting structure for light accumulation

#else
// TODO: factor this code in common, so other material authoring don't require to rewrite everything,
// TODO: test the strech from Tomasz
// float roughness = PerceptualRoughnessToRoughness(preLightData.IblPerceptualRoughness);
// float shrunkRoughness = AnisotropicStrechAtGrazingAngle(roughness, roughness, NdotV);
// Guideline for reflection volume: In HDRenderPipeline we separate the projection volume (the proxy of the scene) from the influence volume (what pixel on the screen is affected)
// However we add the constrain that the shape of the projection and influence volume is the same (i.e if we have a sphere shape projection volume, we have a shape influence).
// It allow to have more coherence for the dynamic if in shader code.
// Users can also chose to not have any projection, in this case we use the property minProjectionDistance to minimize code change. minProjectionDistance is set to huge number
// that simulate effect of no shape projection
float3 coatR = preLightData.coatIblR;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
{

// In Unity the cubemaps are capture with the localToWorld transform of the component.
// This mean that location and orientation matter. So after intersection of proxy volume we need to convert back to world.
float3x3 worldToIS = WorldToInfluenceSpace(lightData);
float3 positionIS = WorldToInfluencePosition(lightData, worldToIS, positionWS);
float3 dirIS = mul(R, worldToIS);
float3x3 worldToPS = WorldToProxySpace(lightData);
float3 positionPS = WorldToProxyPosition(lightData, worldToPS, positionWS);
float3 dirPS = mul(R, worldToPS);
float projectionDistance = 0;
// 1. First process the projection
if (influenceShapeType == ENVSHAPETYPE_SPHERE)
{
projectionDistance = IntersectSphereProxy(lightData, dirPS, positionPS);
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.capturePositionWS
float3 capturePositionWS = lightData.capturePositionWS;
R = (positionWS + projectionDistance * R) - capturePositionWS;
// Test again for clear coat
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
dirPS = mul(coatR, worldToPS);
projectionDistance = IntersectSphereProxy(lightData, dirPS, positionPS);
coatR = (positionWS + projectionDistance * coatR) - capturePositionWS;
}
weight = InfluenceSphereWeight(lightData, bsdfData, positionWS, positionIS, dirIS);
}
else if (influenceShapeType == ENVSHAPETYPE_BOX)
{
projectionDistance = IntersectBoxProxy(lightData, dirPS, positionPS);
// No need to normalize for fetching cubemap
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.capturePositionWS
float3 capturePositionWS = lightData.capturePositionWS;
R = (positionWS + projectionDistance * R) - capturePositionWS;
// TODO: add distance based roughness
EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, R, weight);
// Test again for clear coat
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
dirPS = mul(coatR, worldToPS);
projectionDistance = IntersectBoxProxy(lightData, dirPS, positionPS);
coatR = (positionWS + projectionDistance * coatR) - capturePositionWS;
}
weight = InfluenceBoxWeight(lightData, bsdfData, positionWS, positionIS, dirIS);
}
// Don't do clear coating for refraction
float3 coatR = preLightData.coatIblR;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION && HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, coatR, weight);
#ifdef DEBUG_DISPLAY
float3 radiusToProxy = R;

float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, R, iblMipLevel);
weight *= preLD.a;
weight *= preLD.a; // Not used by reflection probe currently, allow the texture to mask itself (fallback to sky)
// Smooth weighting
weight = Smoothstep01(weight);
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
{

#endif // LIT_DISPLAY_REFERENCE_IBL
weight *= lightData.weight;
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
envLighting *= weight * lightData.multiplier;

if (_DebugLightingMode != 0)
{
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
switch (_DebugLightingMode)
{
case DEBUGLIGHTINGMODE_LUX_METER:

case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO:
diffuseLighting = indirectAmbientOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
{
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
break;
}
}

60
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.hlsl


#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUX_METER)
{
diffuseLighting = lighting.direct.diffuse + bakeLightingData.bakeDiffuseLighting;
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO)
{
// NEWLITTODO
//diffuseLighting = indirectAmbientOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO)
{
// NEWLITTODO
//diffuseLighting = specularOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
#if GTAO_MULTIBOUNCE_APPROX
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO)
if (_DebugLightingMode != 0)
// NEWLITTODO
//diffuseLighting = GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO)
{
// NEWLITTODO
//diffuseLighting = GTAOMultiBounce(specularOcclusion, bsdfData.fresnel0);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
switch (_DebugLightingMode)
{
case DEBUGLIGHTINGMODE_LUX_METER:
//diffuseLighting = lighting.direct.diffuse + bakeLightingData.bakeDiffuseLighting;
break;
case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO:
//diffuseLighting = indirectAmbientOcclusion;
break;
case DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO:
//diffuseLighting = specularOcclusion;
break;
#if GTAO_MULTIBOUNCE_APPROX
case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO:
//diffuseLighting = GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
break;
case DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO:
//diffuseLighting = GTAOMultiBounce(specularOcclusion, bsdfData.fresnel0);
break;
#endif
case DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION:
//if (_DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR)
//diffuseLighting = lighting.indirect.specularTransmitted;
break;
}
#endif
// NEWLITTODO
#endif
}
正在加载...
取消
保存