sebastienlagarde 6 年前
当前提交
00be7084
共有 6 个文件被更改,包括 146 次插入166 次删除
  1. 17
      com.unity.render-pipelines.core/CoreRP/ShaderLibrary/ImageBasedLighting.hlsl
  2. 1
      com.unity.render-pipelines.high-definition/CHANGELOG.md
  3. 25
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightEvaluation.hlsl
  4. 4
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.cs
  5. 108
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl
  6. 157
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl

17
com.unity.render-pipelines.core/CoreRP/ShaderLibrary/ImageBasedLighting.hlsl


return normalize(lerp(N, grainNormal, anisotropy));
}
// For GGX aniso and IBL we have done an empirical (eye balled) approximation compare to the reference.
// We use a single fetch, and we stretch the normal to use based on various criteria.
// result are far away from the reference but better than nothing
// Anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction) - positive use bitangentWS - negative use tangentWS
// Note: returned iblPerceptualRoughness shouldn't be use for sampling FGD texture in a pre-integration
void GetGGXAnisotropicModifiedNormalAndRoughness(real3 bitangentWS, real3 tangentWS, real3 N, real3 V, real anisotropy, real perceptualRoughness, out real3 iblN, out real iblPerceptualRoughness)
{
// For positive anisotropy values: tangent = highlight stretch (anisotropy) direction, bitangent = grain (brush) direction.
float3 grainDirWS = (anisotropy >= 0.0) ? bitangentWS : tangentWS;
// Reduce stretching for (perceptualRoughness < 0.2).
float stretch = abs(anisotropy) * saturate(5.0 * perceptualRoughness);
// NOTE: If we follow the theory we should use the modified normal for the different calculation implying a normal (like NdotV)
// However modified normal is just a hack. The goal is just to stretch a cubemap, no accuracy here. Let's save performance instead.
iblN = GetAnisotropicModifiedNormal(grainDirWS, N, V, stretch);
iblPerceptualRoughness = perceptualRoughness * saturate(1.2 - abs(anisotropy));
}
// Ref: "Moving Frostbite to PBR", p. 69.
real3 GetSpecularDominantDir(real3 N, real3 R, real perceptualRoughness, real NdotV)
{

1
com.unity.render-pipelines.high-definition/CHANGELOG.md


- Fixed compilation errors on Nintendo Switch (limited XRSetting support).
- Fixed apply range attenuation option on punctual light
- Fixed issue when using more than one volume mask texture with density volumes.
- Fixed an error which prevented volumetric lighting from working if no density volumes with 3D textures were present.
### Added
- Add option supportDitheringCrossFade on HDRP Asset to allow to remove shader variant during player build if needed

25
com.unity.render-pipelines.high-definition/HDRP/Lighting/LightEvaluation.hlsl


// Punctual Light evaluation helper
//-----------------------------------------------------------------------------
// Return L vector for punctual light (normalize surface to light), lightToSample (light to surface non normalize) and distances {d, d^2, 1/d, d_proj}
void GetPunctualLightVectors(float3 positionWS, LightData lightData, out float3 L, out float3 lightToSample, out float4 distances)
{
lightToSample = positionWS - lightData.positionWS;
int lightType = lightData.lightType;
distances.w = dot(lightToSample, lightData.forward);
if (lightType == GPULIGHTTYPE_PROJECTOR_BOX)
{
L = -lightData.forward;
distances.xyz = 1; // No distance or angle attenuation
}
else
{
float3 unL = -lightToSample;
float distSq = dot(unL, unL);
float distRcp = rsqrt(distSq);
float dist = distSq * distRcp;
L = unL * distRcp;
distances.xyz = float3(dist, distSq, distRcp);
}
}
float4 EvaluateCookie_Punctual(LightLoopContext lightLoopContext, LightData lightData,
float3 lightToSample)
{

4
com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.cs


volumeAtlasDimensions.y = 1.0f / volumeAtlas.width;
volumeAtlasDimensions.z = volumeAtlas.width;
}
else
{
volumeAtlas = CoreUtils.blackVolumeTexture;
}
cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VBufferDensity, m_DensityBufferHandle);
cmd.SetComputeBufferParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeBounds, s_VisibleVolumeBoundsBuffer);

108
com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl


TEXTURE2D(_GBufferTexture2);
TEXTURE2D(_GBufferTexture3);
#include "../LTCAreaLight/LTCAreaLight.hlsl"
#include "../PreIntegratedFGD/PreIntegratedFGD.hlsl"
#include "HDRP/Material/LTCAreaLight/LTCAreaLight.hlsl"
#include "HDRP/Material/PreIntegratedFGD/PreIntegratedFGD.hlsl"
//-----------------------------------------------------------------------------
// Definition

float energyCompensation;
// IBL
float3 iblR; // Dominant specular direction, used for IBL in EvaluateBSDF_Env()
float3 iblR; // Reflected specular direction, used for IBL in EvaluateBSDF_Env()
float iblPerceptualRoughness;
float3 specularFGD; // Store preintegrated BSDF for both specular and diffuse

preLightData.coatIblF = F_Schlick(CLEAR_COAT_F0, NdotV) * bsdfData.coatMask;
}
float3 iblN, iblR;
// We avoid divergent evaluation of the GGX, as that nearly doubles the cost.
// If the tile has anisotropy, all the pixels within the tile are evaluated as anisotropic.
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);
preLightData.partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// For GGX aniso and IBL we have done an empirical (eye balled) approximation compare to the reference.
// We use a single fetch, and we stretch the normal to use based on various criteria.
// result are far away from the reference but better than nothing
// For positive anisotropy values: tangent = highlight stretch (anisotropy) direction, bitangent = grain (brush) direction.
float3 grainDirWS = (bsdfData.anisotropy >= 0.0) ? bsdfData.bitangentWS : bsdfData.tangentWS;
// Reduce stretching for (perceptualRoughness < 0.2).
float stretch = abs(bsdfData.anisotropy) * saturate(5 * preLightData.iblPerceptualRoughness);
// NOTE: If we follow the theory we should use the modified normal for the different calculation implying a normal (like NdotV) and use 'anisoIblNormalWS'
// into function like GetSpecularDominantDir(). However modified normal is just a hack. The goal is just to stretch a cubemap, no accuracy here.
// With this in mind and for performance reasons we chose to only use modified normal to calculate R.
iblN = GetAnisotropicModifiedNormal(grainDirWS, N, V, stretch);
}
else
{
preLightData.partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, bsdfData.roughnessT);
iblN = N;
}
// IBL
// Handle IBL + multiscattering. Note FGD texture is also use for area light
// Handle IBL + area light + multiscattering.
// Note: use the not modified by anisotropy iblPerceptualRoughness here.
float specularReflectivity;
GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV, preLightData.iblPerceptualRoughness, bsdfData.fresnel0, preLightData.specularFGD, preLightData.diffuseFGD, specularReflectivity);
#ifdef USE_DIFFUSE_LAMBERT_BRDF

iblR = reflect(-V, iblN);
// This is a ad-hoc tweak to better match reference of anisotropic GGX.
// TODO: We need a better hack.
preLightData.iblPerceptualRoughness *= saturate(1.2 - abs(bsdfData.anisotropy));
// Corretion of reflected direction for better handling of rough material
preLightData.iblR = iblR;
#ifdef LIT_USE_GGX_ENERGY_COMPENSATION
// Ref: Practical multiple scattering compensation for microfacet models.
// We only apply the formulation for metals.

preLightData.energyCompensation = 0.0;
#endif // LIT_USE_GGX_ENERGY_COMPENSATION
float3 iblN;
// We avoid divergent evaluation of the GGX, as that nearly doubles the cost.
// If the tile has anisotropy, all the pixels within the tile are evaluated as anisotropic.
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_ANISOTROPY))
{
float TdotV = dot(bsdfData.tangentWS, V);
float BdotV = dot(bsdfData.bitangentWS, V);
preLightData.partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// perceptualRoughness is use as input and output here
GetGGXAnisotropicModifiedNormalAndRoughness(bsdfData.bitangentWS, bsdfData.tangentWS, N, V, bsdfData.anisotropy, preLightData.iblPerceptualRoughness, iblN, preLightData.iblPerceptualRoughness);
}
else
{
preLightData.partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, bsdfData.roughnessT);
iblN = N;
}
preLightData.iblR = reflect(-V, iblN);
// Area light
// UVs for sampling the LUTs
float theta = FastACosPos(NdotV); // For Area light - UVs for sampling the LUTs

// This function require the 3 structure surfaceData, builtinData, bsdfData because it may require both the engine side data, and data that will not be store inside the gbuffer.
float3 GetBakedDiffuseLighting(SurfaceData surfaceData, BuiltinData builtinData, BSDFData bsdfData, PreLightData preLightData)
{
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING)) // This test is static as it is done in GBuffer or forward pass, will be remove by compiler
{
bsdfData.diffuseColor = GetModifiedDiffuseColorForSSS(bsdfData); // local modification of bsdfData
}
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUX_METER)
{

#endif
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING)) // This test is static as it is done in GBuffer or forward pass, will be remove by compiler
{
bsdfData.diffuseColor = GetModifiedDiffuseColorForSSS(bsdfData); // local modification of bsdfData
}
// Premultiply bake diffuse lighting information with DisneyDiffuse pre-integration
return builtinData.bakeDiffuseLighting * preLightData.diffuseFGD * surfaceData.ambientOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor;

DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 N = bsdfData.normalWS;
float3 L = -lightData.forward;
float NdotL = dot(N, L);
float3 L = -lightData.forward;
float3 N = bsdfData.normalWS;
float NdotL = dot(N, L);
float3 transmittance = float3(0.0, 0.0, 0.0);
if (HasFlag(bsdfData.materialFeatures, MATERIAL_FEATURE_FLAGS_TRANSMISSION_MODE_THIN_THICKNESS))

DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 lightToSample = posInput.positionWS - lightData.positionWS;
int lightType = lightData.lightType;
float3 lightToSample;
distances.w = dot(lightToSample, lightData.forward);
if (lightType == GPULIGHTTYPE_PROJECTOR_BOX)
{
L = -lightData.forward;
distances.xyz = 1; // No distance or angle attenuation
}
else
{
float3 unL = -lightToSample;
float distSq = dot(unL, unL);
float distRcp = rsqrt(distSq);
float dist = distSq * distRcp;
L = unL * distRcp;
distances.xyz = float3(dist, distSq, distRcp);
}
GetPunctualLightVectors(posInput.positionWS, lightData, L, lightToSample, distances);
float3 N = bsdfData.normalWS;
float NdotL = dot(N, L);

#else
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, bsdfData.perceptualRoughness, 1.0, bsdfData.specularOcclusion, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
#endif
ApplyAmbientOcclusionFactor(aoFactor, bakeLightingData, lighting);
// Subsurface scattering mode

157
com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl


// Required for SSS, GBuffer texture declaration
TEXTURE2D(_GBufferTexture0);
#include "../LTCAreaLight/LTCAreaLight.hlsl"
// Declare the BSDF specific FGD property and its fetching function
#include "../PreIntegratedFGD/PreIntegratedFGD.hlsl"
#include "HDRP/Material/LTCAreaLight/LTCAreaLight.hlsl"
#include "HDRP/Material/PreIntegratedFGD/PreIntegratedFGD.hlsl"
//-----------------------------------------------------------------------------
// Definition

// Otherwise, the calculation of these is done for each light
//
// Handle IBL + area light + multiscattering.
// Note: use the not modified by anisotropy iblPerceptualRoughness here.
// Here, we will fetch our actual FGD terms, see ComputeAdding for details: the F0 params
// will be replaced by our energy coefficients. Note that the way to do it depends on the
// formulation of ComputeAdding (with FGD fetches or only Fresnel terms).
// Also note that while the fetch directions for the light samples (IBL) are the ones
// at the top interface, for the FGD terms (in fact, for all angle dependent BSDF
// parametrization data), we need to use the actual interface angle a propagated direction
// would have. So, for the base layer, this is a refracted direction through the coat.
// Same for the top, but this is just NdotV.
// This is because we should really have fetched FGD with the tracked cti (cos theta incoming)
// at the bottom layer or top layer during ComputeAdding itself. We delayed the fetch after,
// because our ComputeAdding formulation is with "energy" coefficients calculated with a
// chain of Fresnel terms instead of a correct chain computed with the true FGD.
float baseLayerNdotV = PreLightData_GetBaseNdotVForFGD(bsdfData, preLightData, NdotV);
float diffuseFGDTmp; // unused, for coat layer FGD fetch
GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV[COAT_NORMAL_IDX],
preLightData.iblPerceptualRoughness[COAT_LOBE_IDX],
preLightData.vLayerEnergyCoeff[TOP_VLAYER_IDX],
preLightData.specularFGD[COAT_LOBE_IDX],
diffuseFGDTmp,
specularReflectivity[COAT_LOBE_IDX]);
GetPreIntegratedFGDGGXAndDisneyDiffuse(baseLayerNdotV,
preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX],
preLightData.vLayerEnergyCoeff[BOTTOM_VLAYER_IDX],
preLightData.specularFGD[BASE_LOBEA_IDX],
diffuseFGD[0],
specularReflectivity[BASE_LOBEA_IDX]);
GetPreIntegratedFGDGGXAndDisneyDiffuse(baseLayerNdotV,
preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX],
preLightData.vLayerEnergyCoeff[BOTTOM_VLAYER_IDX],
preLightData.specularFGD[BASE_LOBEB_IDX],
diffuseFGD[1],
specularReflectivity[BASE_LOBEB_IDX]);
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_ANISOTROPY))
{
// Note: there's no anisotropy possible on coat.

preLightData.TdotV = TdotV;
preLightData.BdotV = BdotV;
#endif
// For GGX aniso and IBL we have done an empirical (eye balled) approximation compare to the reference.
// We use a single fetch, and we stretch the normal to use based on various criteria.
// result are far away from the reference but better than nothing
// For positive anisotropy values: tangent = highlight stretch (anisotropy) direction, bitangent = grain (brush) direction.
float3 grainDirWS[2];
//grainDirWS[0] = (bsdfData.anisotropy >= 0.0) ? bsdfData.bitangentWS : bsdfData.tangentWS;
grainDirWS[0] = (preLightData.iblAnisotropy[0] >= 0.0) ? bsdfData.bitangentWS : bsdfData.tangentWS;
grainDirWS[1] = (preLightData.iblAnisotropy[1] >= 0.0) ? bsdfData.bitangentWS : bsdfData.tangentWS;
// Reduce stretching for (perceptualRoughness < 0.2).
float stretch[2];
stretch[0] = abs(preLightData.iblAnisotropy[0]) * saturate(5 * preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX]);
stretch[1] = abs(preLightData.iblAnisotropy[1]) * saturate(5 * preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX]);
// perceptualRoughness is use as input and output here
GetGGXAnisotropicModifiedNormalAndRoughness(bsdfData.bitangentWS, bsdfData.tangentWS, N, V, preLightData.iblAnisotropy[0], preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX], iblN[BASE_LOBEA_IDX], preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX]);
GetGGXAnisotropicModifiedNormalAndRoughness(bsdfData.bitangentWS, bsdfData.tangentWS, N, V, preLightData.iblAnisotropy[1], preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX], iblN[BASE_LOBEB_IDX], preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX]);
iblN[BASE_LOBEA_IDX] = GetAnisotropicModifiedNormal(grainDirWS[0], N[BASE_NORMAL_IDX], V, stretch[0]);
iblN[BASE_LOBEB_IDX] = GetAnisotropicModifiedNormal(grainDirWS[1], N[BASE_NORMAL_IDX], V, stretch[1]);
}
else
{

// IBL
// Handle IBL pre calculated data + GGX multiscattering energy loss compensation term
// Here, we will fetch our actual FGD terms, see ComputeAdding for details: the F0 params
// will be replaced by our energy coefficients. Note that the way to do it depends on the
// formulation of ComputeAdding (with FGD fetches or only Fresnel terms).
// Also note that while the fetch directions for the light samples (IBL) are the ones
// at the top interface, for the FGD terms (in fact, for all angle dependent BSDF
// parametrization data), we need to use the actual interface angle a propagated direction
// would have. So, for the base layer, this is a refracted direction through the coat.
// Same for the top, but this is just NdotV.
// This is because we should really have fetched FGD with the tracked cti (cos theta incoming)
// at the bottom layer or top layer during ComputeAdding itself. We delayed the fetch after,
// because our ComputeAdding formulation is with "energy" coefficients calculated with a
// chain of Fresnel terms instead of a correct chain computed with the true FGD.
float baseLayerNdotV = PreLightData_GetBaseNdotVForFGD(bsdfData, preLightData, NdotV);
float diffuseFGDTmp; // unused, for coat layer FGD fetch
GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV[COAT_NORMAL_IDX],
preLightData.iblPerceptualRoughness[COAT_LOBE_IDX],
preLightData.vLayerEnergyCoeff[TOP_VLAYER_IDX],
preLightData.specularFGD[COAT_LOBE_IDX],
diffuseFGDTmp,
specularReflectivity[COAT_LOBE_IDX]);
GetPreIntegratedFGDGGXAndDisneyDiffuse(baseLayerNdotV,
preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX],
preLightData.vLayerEnergyCoeff[BOTTOM_VLAYER_IDX],
preLightData.specularFGD[BASE_LOBEA_IDX],
diffuseFGD[0],
specularReflectivity[BASE_LOBEA_IDX]);
GetPreIntegratedFGDGGXAndDisneyDiffuse(baseLayerNdotV,
preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX],
preLightData.vLayerEnergyCoeff[BOTTOM_VLAYER_IDX],
preLightData.specularFGD[BASE_LOBEB_IDX],
diffuseFGD[1],
specularReflectivity[BASE_LOBEB_IDX]);
// This is a ad-hoc tweak to better match reference of anisotropic GGX.
// TODO: We need a better hack.
preLightData.iblPerceptualRoughness[BASE_LOBEA_IDX] *= saturate(1.2 - abs(preLightData.iblAnisotropy[0]));
preLightData.iblPerceptualRoughness[BASE_LOBEB_IDX] *= saturate(1.2 - abs(preLightData.iblAnisotropy[1]));
// Correction of reflected direction for better handling of rough material

// This function require the 3 structure surfaceData, builtinData, bsdfData because it may require both the engine side data, and data that will not be store inside the gbuffer.
float3 GetBakedDiffuseLighting(SurfaceData surfaceData, BuiltinData builtinData, BSDFData bsdfData, PreLightData preLightData)
{
// Note bsdfData isn't modified outside of this function scope.
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_SUBSURFACE_SCATTERING)) // This test is static as it is done in GBuffer or forward pass, will be remove by compiler
{
// SSS Texturing mode can change albedo because diffuse maps can already contain some SSS too
bsdfData.diffuseColor = GetModifiedDiffuseColorForSSS(bsdfData); // local modification of bsdfData
}
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUX_METER)
{

#endif
// Note bsdfData isn't modified outside of this function scope.
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_SUBSURFACE_SCATTERING)) // This test is static as it is done in GBuffer or forward pass, will be remove by compiler
{
// SSS Texturing mode can change albedo because diffuse maps can already contain some SSS too
bsdfData.diffuseColor = GetModifiedDiffuseColorForSSS(bsdfData); // local modification of bsdfData
}
// Premultiply bake diffuse lighting information
// preLightData.diffuseEnergy will be 1,1,1 if no vlayering or no VLAYERED_DIFFUSE_ENERGY_HACKED_TERM
return builtinData.bakeDiffuseLighting * preLightData.diffuseFGD * preLightData.diffuseEnergy * surfaceData.ambientOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor;

DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 N; float unclampedNdotV;
float3 L = -lightData.forward;
float3 N;
float unclampedNdotV;
float3 L = -lightData.forward;
float NdotL = dot(N, L);
float NdotL = dot(N, L);
// For shadow attenuation (ie receiver bias), always use the geometric normal
float3 shadowBiasNormal = bsdfData.geomNormalWS;

DirectLighting lighting;
ZERO_INITIALIZE(DirectLighting, lighting);
float3 lightToSample = posInput.positionWS - lightData.positionWS;
int lightType = lightData.lightType;
float3 lightToSample;
distances.w = dot(lightToSample, lightData.forward);
if (lightType == GPULIGHTTYPE_PROJECTOR_BOX)
{
L = -lightData.forward;
distances.xyz = 1; // No distance or angle attenuation
}
else
{
float3 unL = -lightToSample;
float distSq = dot(unL, unL);
float distRcp = rsqrt(distSq);
float dist = distSq * distRcp;
L = unL * distRcp;
distances.xyz = float3(dist, distSq, distRcp);
}
GetPunctualLightVectors(posInput.positionWS, lightData, L, lightToSample, distances);
float3 N; float unclampedNdotV;
EvaluateBSDF_GetNormalUnclampedNdotV(bsdfData, preLightData, V, N, unclampedNdotV);

// Use GTAOMultiBounce approximation for ambient occlusion (allow to get a tint from the baseColor)
//GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, preLightData.NdotV, lerp(bsdfData.perceptualRoughnessA, bsdfData.perceptualRoughnessB, bsdfData.lobeMix), bsdfData.ambientOcclusion, 1.0, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
GetScreenSpaceAmbientOcclusionMultibounce(posInput.positionSS, unclampedNdotV, lerp(bsdfData.perceptualRoughnessA, bsdfData.perceptualRoughnessB, bsdfData.lobeMix), bsdfData.ambientOcclusion, 1.0, bsdfData.diffuseColor, bsdfData.fresnel0, aoFactor);
ApplyAmbientOcclusionFactor(aoFactor, bakeLightingData, lighting);
// Subsurface scattering mode

正在加载...
取消
保存