浏览代码
Factor Lit and StackLit code
Factor Lit and StackLit code
Factor code from Lit and stacklit to MaterialEvaluation.hlsl Move AO function in LightEvalaution.hlsl to MaterialEvaluation.hlsl/main
Sebastien Lagarde
6 年前
当前提交
ba6fd164
共有 9 个文件被更改,包括 628 次插入 和 257 次删除
-
2com.unity.render-pipelines.high-definition/HDRP/Debug/DebugDisplay.hlsl
-
57com.unity.render-pipelines.high-definition/HDRP/Lighting/LightEvaluation.hlsl
-
6com.unity.render-pipelines.high-definition/HDRP/Material/Decal/Decal.cs.hlsl
-
104com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl
-
110com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl
-
168com.unity.render-pipelines.high-definition/HDRP/Material/MaterialEvaluation.hlsl
-
9com.unity.render-pipelines.high-definition/HDRP/Material/MaterialEvaluation.hlsl.meta
-
429com.unity.render-pipelines.high-definition/HDRP/Material/ShaderName/ShaderName.hlsl
|
|||
// This files include various function uses to evaluate material |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// Lighting structure for light accumulation |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
// These structure allow to accumulate lighting accross the Lit material |
|||
// AggregateLighting is init to zero and transfer to EvaluateBSDF, but the LightLoop can't access its content. |
|||
struct DirectLighting |
|||
{ |
|||
float3 diffuse; |
|||
float3 specular; |
|||
}; |
|||
|
|||
struct IndirectLighting |
|||
{ |
|||
float3 specularReflected; |
|||
float3 specularTransmitted; |
|||
}; |
|||
|
|||
struct AggregateLighting |
|||
{ |
|||
DirectLighting direct; |
|||
IndirectLighting indirect; |
|||
}; |
|||
|
|||
void AccumulateDirectLighting(DirectLighting src, inout AggregateLighting dst) |
|||
{ |
|||
dst.direct.diffuse += src.diffuse; |
|||
dst.direct.specular += src.specular; |
|||
} |
|||
|
|||
void AccumulateIndirectLighting(IndirectLighting src, inout AggregateLighting dst) |
|||
{ |
|||
dst.indirect.specularReflected += src.specularReflected; |
|||
dst.indirect.specularTransmitted += src.specularTransmitted; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// Ambient occlusion helper |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
// Ambient occlusion |
|||
struct AmbientOcclusionFactor |
|||
{ |
|||
float3 indirectAmbientOcclusion; |
|||
float3 directAmbientOcclusion; |
|||
float3 indirectSpecularOcclusion; |
|||
}; |
|||
|
|||
void GetScreenSpaceAmbientOcclusion(float2 positionSS, float NdotV, float perceptualRoughness, float ambientOcclusionFromData, float specularOcclusionFromData, out AmbientOcclusionFactor aoFactor) |
|||
{ |
|||
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine) |
|||
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad) |
|||
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral |
|||
|
|||
// Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting) |
|||
#ifndef _SURFACE_TYPE_TRANSPARENT |
|||
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, positionSS).x; |
|||
// Ambient occlusion use for direct lighting (directional, punctual, area) |
|||
float directAmbientOcclusion = lerp(1.0, indirectAmbientOcclusion, _AmbientOcclusionParam.w); |
|||
#else |
|||
float indirectAmbientOcclusion = 1.0; |
|||
float directAmbientOcclusion = 1.0; |
|||
#endif |
|||
|
|||
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness); |
|||
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(NdotV), indirectAmbientOcclusion, roughness); |
|||
|
|||
aoFactor.indirectSpecularOcclusion = lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(specularOcclusionFromData, specularOcclusion)); |
|||
aoFactor.indirectAmbientOcclusion = lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(ambientOcclusionFromData, indirectAmbientOcclusion)); |
|||
aoFactor.directAmbientOcclusion = lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), directAmbientOcclusion); |
|||
} |
|||
|
|||
void GetScreenSpaceAmbientOcclusionMultibounce(float2 positionSS, float NdotV, float perceptualRoughness, float ambientOcclusionFromData, float specularOcclusionFromData, float3 diffuseColor, float3 fresnel0, out AmbientOcclusionFactor aoFactor) |
|||
{ |
|||
// Use GTAOMultiBounce approximation for ambient occlusion (allow to get a tint from the diffuseColor) |
|||
// Note: When we ImageLoad outside of texture size, the value returned by Load is 0 (Note: On Metal maybe it clamp to value of texture which is also fine) |
|||
// We use this property to have a neutral value for AO that doesn't consume a sampler and work also with compute shader (i.e use ImageLoad) |
|||
// We store inverse AO so neutral is black. So either we sample inside or outside the texture it return 0 in case of neutral |
|||
|
|||
// Ambient occlusion use for indirect lighting (reflection probe, baked diffuse lighting) |
|||
#ifndef _SURFACE_TYPE_TRANSPARENT |
|||
float indirectAmbientOcclusion = 1.0 - LOAD_TEXTURE2D(_AmbientOcclusionTexture, positionSS).x; |
|||
// Ambient occlusion use for direct lighting (directional, punctual, area) |
|||
float directAmbientOcclusion = lerp(1.0, indirectAmbientOcclusion, _AmbientOcclusionParam.w); |
|||
#else |
|||
float indirectAmbientOcclusion = 1.0; |
|||
float directAmbientOcclusion = 1.0; |
|||
#endif |
|||
|
|||
float roughness = PerceptualRoughnessToRoughness(perceptualRoughness); |
|||
float specularOcclusion = GetSpecularOcclusionFromAmbientOcclusion(ClampNdotV(NdotV), indirectAmbientOcclusion, roughness); |
|||
|
|||
aoFactor.indirectSpecularOcclusion = GTAOMultiBounce(min(specularOcclusionFromData, specularOcclusion), fresnel0); |
|||
aoFactor.indirectAmbientOcclusion = GTAOMultiBounce(min(ambientOcclusionFromData, indirectAmbientOcclusion), diffuseColor); |
|||
aoFactor.directAmbientOcclusion = GTAOMultiBounce(directAmbientOcclusion, diffuseColor); |
|||
} |
|||
|
|||
void ApplyAmbientOcclusionFactor(AmbientOcclusionFactor aoFactor, inout BakeLightingData bakeLightingData, inout AggregateLighting lighting) |
|||
{ |
|||
// Note: in case of Lit, bakeLightingData.bakeDiffuseLighting contain indirect diffuse + emissive, |
|||
// so Ambient occlusion is multiply by emissive which is wrong but not a big deal |
|||
bakeLightingData.bakeDiffuseLighting *= aoFactor.indirectAmbientOcclusion; |
|||
lighting.indirect.specularReflected *= aoFactor.indirectSpecularOcclusion; |
|||
lighting.direct.diffuse *= aoFactor.directAmbientOcclusion; |
|||
} |
|||
|
|||
#ifdef DEBUG_DISPLAY |
|||
// mipmapColor is color use to store texture streaming information in XXXData.hlsl (look for DEBUGMIPMAPMODE_NONE) |
|||
void PostEvaluateBSDFDebugDisplay( AmbientOcclusionFactor aoFactor, BakeLightingData bakeLightingData, AggregateLighting lighting, float3 mipmapColor, |
|||
inout float3 diffuseLighting, inout float3 specularLighting) |
|||
{ |
|||
if (_DebugLightingMode != 0) |
|||
{ |
|||
// Caution: _DebugLightingMode is used in other part of the code, don't do anything outside of |
|||
// current cases |
|||
switch (_DebugLightingMode) |
|||
{ |
|||
case DEBUGLIGHTINGMODE_LUX_METER: |
|||
diffuseLighting = lighting.direct.diffuse + bakeLightingData.bakeDiffuseLighting; |
|||
|
|||
//Compress lighting values for color picker if enabled |
|||
if (_ColorPickerMode != COLORPICKERDEBUGMODE_NONE) |
|||
diffuseLighting = diffuseLighting / LUXMETER_COMPRESSION_RATIO; |
|||
|
|||
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting |
|||
break; |
|||
|
|||
case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION: |
|||
diffuseLighting = aoFactor.indirectAmbientOcclusion; |
|||
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting |
|||
break; |
|||
|
|||
case DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION: |
|||
diffuseLighting = aoFactor.indirectSpecularOcclusion; |
|||
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting |
|||
break; |
|||
|
|||
case DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION: |
|||
if (_DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR) |
|||
diffuseLighting = lighting.indirect.specularTransmitted; |
|||
break; |
|||
|
|||
case DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFLECTION: |
|||
if (_DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR) |
|||
diffuseLighting = lighting.indirect.specularReflected; |
|||
break; |
|||
|
|||
case DEBUGLIGHTINGMODE_VISUALIZE_SHADOW_MASKS: |
|||
#ifdef SHADOWS_SHADOWMASK |
|||
diffuseLighting = float3( |
|||
bakeLightingData.bakeShadowMask.r / 2 + bakeLightingData.bakeShadowMask.g / 2, |
|||
bakeLightingData.bakeShadowMask.g / 2 + bakeLightingData.bakeShadowMask.b / 2, |
|||
bakeLightingData.bakeShadowMask.b / 2 + bakeLightingData.bakeShadowMask.a / 2 |
|||
); |
|||
specularLighting = float3(0, 0, 0); |
|||
#endif |
|||
break ; |
|||
} |
|||
} |
|||
else if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE) |
|||
{ |
|||
diffuseLighting = mipmapColor; |
|||
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting |
|||
} |
|||
} |
|||
#endif |
|
|||
fileFormatVersion: 2 |
|||
guid: 3c80046db57367445b2a7c154c18879e |
|||
ShaderImporter: |
|||
externalObjects: {} |
|||
defaultTextures: [] |
|||
nonModifiableTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
//----------------------------------------------------------------------------- |
|||
// SurfaceData and BSDFData |
|||
//----------------------------------------------------------------------------- |
|||
// SurfaceData is defined in ShaderName.cs which generates ShaderName.cs.hlsl |
|||
#include "ShaderName.cs.hlsl" |
|||
|
|||
// This function is use to help with debugging and must be implemented by any lit material |
|||
// Implementer must take into account what are the current override component and |
|||
// adjust SurfaceData properties accordingdly |
|||
void ApplyDebugToSurfaceData(float3x3 worldToTangent, inout SurfaceData surfaceData) |
|||
{ |
|||
#ifdef DEBUG_DISPLAY |
|||
// NOTE: THe _Debug* uniforms come from /HDRP/Debug/DebugDisplay.hlsl |
|||
|
|||
// Override value if requested by user |
|||
// this can be use also in case of debug lighting mode like diffuse only |
|||
bool overrideAlbedo = _DebugLightingAlbedo.x != 0.0; |
|||
bool overrideSmoothness = _DebugLightingSmoothness.x != 0.0; |
|||
bool overrideNormal = _DebugLightingNormal.x != 0.0; |
|||
|
|||
if (overrideAlbedo) |
|||
{ |
|||
float3 overrideAlbedoValue = _DebugLightingAlbedo.yzw; |
|||
surfaceData.baseColor = overrideAlbedoValue; |
|||
} |
|||
|
|||
if (overrideSmoothness) |
|||
{ |
|||
//float overrideSmoothnessValue = _DebugLightingSmoothness.y; |
|||
//surfaceData.perceptualSmoothness = overrideSmoothnessValue; |
|||
} |
|||
|
|||
if (overrideNormal) |
|||
{ |
|||
surfaceData.normalWS = worldToTangent[2]; |
|||
} |
|||
#endif |
|||
} |
|||
|
|||
// This function is similar to ApplyDebugToSurfaceData but for BSDFData |
|||
// Note: This will be available and used in ShaderPassForward.hlsl since in ShaderName.shader, |
|||
// just before including the core code of the pass (ShaderPassForward.hlsl) we include |
|||
// Material.hlsl (or Lighting.hlsl which includes it) which in turn includes us, |
|||
// ShaderName.shader, via the #if defined(UNITY_MATERIAL_*) glue mechanism. |
|||
void ApplyDebugToBSDFData(inout BSDFData bsdfData) |
|||
{ |
|||
#ifdef DEBUG_DISPLAY |
|||
// Override value if requested by user |
|||
// this can be use also in case of debug lighting mode like specular only |
|||
|
|||
//bool overrideSpecularColor = _DebugLightingSpecularColor.x != 0.0; |
|||
|
|||
//if (overrideSpecularColor) |
|||
//{ |
|||
// float3 overrideSpecularColor = _DebugLightingSpecularColor.yzw; |
|||
// bsdfData.fresnel0 = overrideSpecularColor; |
|||
//} |
|||
#endif |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// conversion function for forward |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
BSDFData ConvertSurfaceDataToBSDFData(uint2 positionSS, SurfaceData surfaceData) |
|||
{ |
|||
BSDFData bsdfData; |
|||
ZERO_INITIALIZE(BSDFData, bsdfData); |
|||
|
|||
bsdfData.diffuseColor = surfaceData.baseColor; |
|||
bsdfData.normalWS = surfaceData.normalWS; |
|||
|
|||
ApplyDebugToBSDFData(bsdfData); |
|||
return bsdfData; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// Debug method (use to display values) |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
// This function call the generated debug function and allow to override the debug output if needed |
|||
void GetSurfaceDataDebug(uint paramId, SurfaceData surfaceData, inout float3 result, inout bool needLinearToSRGB) |
|||
{ |
|||
GetGeneratedSurfaceDataDebug(paramId, surfaceData, result, needLinearToSRGB); |
|||
} |
|||
|
|||
// This function call the generated debug function and allow to override the debug output if needed |
|||
void GetBSDFDataDebug(uint paramId, BSDFData bsdfData, inout float3 result, inout bool needLinearToSRGB) |
|||
{ |
|||
GetGeneratedBSDFDataDebug(paramId, bsdfData, result, needLinearToSRGB); |
|||
} |
|||
|
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// PreLightData |
|||
// |
|||
// Make sure we respect naming conventions to reuse ShaderPassForward as is, |
|||
// ie struct (even if opaque to the ShaderPassForward) name is PreLightData, |
|||
// GetPreLightData prototype. |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
// Precomputed lighting data to send to the various lighting functions |
|||
struct PreLightData |
|||
{ |
|||
float NdotV; // Could be negative due to normal mapping, use ClampNdotV() |
|||
}; |
|||
|
|||
// This function is call to precompute heavy calculation before lightloop |
|||
PreLightData GetPreLightData(float3 V, PositionInputs posInput, inout BSDFData bsdfData) |
|||
{ |
|||
PreLightData preLightData; |
|||
ZERO_INITIALIZE(PreLightData, preLightData); |
|||
|
|||
float3 N = bsdfData.normalWS; |
|||
preLightData.NdotV = dot(N, V); |
|||
|
|||
//float NdotV = ClampNdotV(preLightData.NdotV); |
|||
|
|||
return preLightData; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// bake lighting function |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
// |
|||
// GetBakedDiffuseLighting will be called from ShaderPassForward.hlsl. |
|||
// |
|||
// GetBakedDiffuseLighting function compute the bake lighting + emissive color to be store in emissive buffer (Deferred case) |
|||
// In forward it must be add to the final contribution. |
|||
// 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) |
|||
{ |
|||
#ifdef DEBUG_DISPLAY |
|||
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUX_METER) |
|||
{ |
|||
// The lighting in SH or lightmap is assume to contain bounced light only (i.e no direct lighting), and is divide by PI (i.e Lambert is apply), so multiply by PI here to get back the illuminance |
|||
return builtinData.bakeDiffuseLighting * PI; |
|||
} |
|||
#endif |
|||
|
|||
// Premultiply bake diffuse lighting information with DisneyDiffuse pre-integration |
|||
//return builtinData.bakeDiffuseLighting * preLightData.diffuseFGD * surfaceData.ambientOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor; |
|||
return builtinData.bakeDiffuseLighting * bsdfData.diffuseColor; |
|||
} |
|||
|
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// light transport functions |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
LightTransportData GetLightTransportData(SurfaceData surfaceData, BuiltinData builtinData, BSDFData bsdfData) |
|||
{ |
|||
LightTransportData lightTransportData; |
|||
|
|||
// diffuseColor for lightmapping |
|||
lightTransportData.diffuseColor = bsdfData.diffuseColor; |
|||
lightTransportData.emissiveColor = builtinData.emissiveColor; |
|||
|
|||
return lightTransportData; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// LightLoop related function (Only include if required) |
|||
// HAS_LIGHTLOOP is define in Lighting.hlsl |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
#ifdef HAS_LIGHTLOOP |
|||
|
|||
#ifndef _SURFACE_TYPE_TRANSPARENT |
|||
// For /Lighting/LightEvaluation.hlsl: |
|||
#define USE_DEFERRED_DIRECTIONAL_SHADOWS // Deferred shadows are always enabled for opaque objects |
|||
#endif |
|||
|
|||
#include "HDRP/Material/MaterialEvaluation.hlsl" |
|||
#include "HDRP/Lighting/LightEvaluation.hlsl" |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// BSDF share between directional light, punctual light and area light (reference) |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
// This function apply BSDF. Assumes that NdotL is positive. |
|||
void BSDF( float3 V, float3 L, float NdotL, float3 positionWS, PreLightData preLightData, BSDFData bsdfData, |
|||
out float3 diffuseLighting, |
|||
out float3 specularLighting) |
|||
{ |
|||
float diffuseTerm = Lambert(); |
|||
|
|||
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF(). |
|||
diffuseLighting = diffuseTerm; |
|||
specularLighting = float3(0.0, 0.0, 0.0); |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// EvaluateBSDF_Directional |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
DirectLighting EvaluateBSDF_Directional(LightLoopContext lightLoopContext, |
|||
float3 V, PositionInputs posInput, PreLightData preLightData, |
|||
DirectionalLightData lightData, BSDFData bsdfData, |
|||
BakeLightingData bakeLightingData) |
|||
{ |
|||
DirectLighting lighting; |
|||
ZERO_INITIALIZE(DirectLighting, lighting); |
|||
|
|||
float3 N = bsdfData.normalWS; |
|||
float3 L = -lightData.forward; // Lights point backward in Unity |
|||
float NdotL = dot(N, L); |
|||
|
|||
// color and attenuation are outputted by EvaluateLight: |
|||
float3 color; |
|||
float attenuation; |
|||
EvaluateLight_Directional(lightLoopContext, posInput, lightData, bakeLightingData, N, L, color, attenuation); |
|||
|
|||
float intensity = max(0, attenuation * NdotL); // Warning: attenuation can be greater than 1 due to the inverse square attenuation (when position is close to light) |
|||
|
|||
// Note: We use NdotL here to early out, but in case of clear coat this is not correct. But we are ok with this |
|||
UNITY_BRANCH if (intensity > 0.0) |
|||
{ |
|||
BSDF(V, L, NdotL, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular); |
|||
|
|||
lighting.diffuse *= intensity * lightData.diffuseScale; |
|||
lighting.specular *= intensity * lightData.specularScale; |
|||
} |
|||
|
|||
// Save ALU by applying light and cookie colors only once. |
|||
lighting.diffuse *= color; |
|||
lighting.specular *= color; |
|||
|
|||
#ifdef DEBUG_DISPLAY |
|||
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUX_METER) |
|||
{ |
|||
// Only lighting, not BSDF |
|||
lighting.diffuse = color * intensity * lightData.diffuseScale; |
|||
} |
|||
#endif |
|||
|
|||
return lighting; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// EvaluateBSDF_Punctual (supports spot, point and projector lights) |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
DirectLighting EvaluateBSDF_Punctual(LightLoopContext lightLoopContext, |
|||
float3 V, PositionInputs posInput, |
|||
PreLightData preLightData, LightData lightData, BSDFData bsdfData, BakeLightingData bakeLightingData) |
|||
{ |
|||
DirectLighting lighting; |
|||
ZERO_INITIALIZE(DirectLighting, lighting); |
|||
|
|||
float3 lightToSample = posInput.positionWS - lightData.positionWS; |
|||
int lightType = lightData.lightType; |
|||
|
|||
float3 L; |
|||
float4 distances; // {d, d^2, 1/d, d_proj} |
|||
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); |
|||
} |
|||
|
|||
float3 N = bsdfData.normalWS; |
|||
float NdotV = ClampNdotV(preLightData.NdotV); |
|||
float NdotL = dot(N, L); |
|||
float LdotV = dot(L, V); |
|||
|
|||
float3 color; |
|||
float attenuation; |
|||
EvaluateLight_Punctual(lightLoopContext, posInput, lightData, bakeLightingData, N, L, |
|||
lightToSample, distances, color, attenuation); |
|||
|
|||
|
|||
float intensity = max(0, attenuation * NdotL); // Warning: attenuation can be greater than 1 due to the inverse square attenuation (when position is close to light) |
|||
|
|||
// Note: We use NdotL here to early out, but in case of clear coat this is not correct. But we are ok with this |
|||
UNITY_BRANCH if (intensity > 0.0) |
|||
{ |
|||
// Shader implementer is free to use minRoughness paramter or not(But better if it is done) |
|||
// Simulate a sphere light with this hack |
|||
// Note that it is not correct with our pre-computation of PartLambdaV (mean if we disable the optimization we will not have the |
|||
// same result) but we don't care as it is a hack anyway |
|||
|
|||
//bsdfData.coatRoughness = max(bsdfData.coatRoughness, lightData.minRoughness); |
|||
//bsdfData.roughnessT = max(bsdfData.roughnessT, lightData.minRoughness); |
|||
//bsdfData.roughnessB = max(bsdfData.roughnessB, lightData.minRoughness); |
|||
|
|||
BSDF(V, L, NdotL, posInput.positionWS, preLightData, bsdfData, lighting.diffuse, lighting.specular); |
|||
|
|||
lighting.diffuse *= intensity * lightData.diffuseScale; |
|||
lighting.specular *= intensity * lightData.specularScale; |
|||
} |
|||
|
|||
// Save ALU by applying light and cookie colors only once. |
|||
lighting.diffuse *= color; |
|||
lighting.specular *= color; |
|||
|
|||
#ifdef DEBUG_DISPLAY |
|||
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUX_METER) |
|||
{ |
|||
// Only lighting, not BSDF |
|||
lighting.diffuse = color * intensity * lightData.diffuseScale; |
|||
} |
|||
#endif |
|||
|
|||
return lighting; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// EvaluateBSDF_Line |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
DirectLighting EvaluateBSDF_Line( LightLoopContext lightLoopContext, |
|||
float3 V, PositionInputs posInput, |
|||
PreLightData preLightData, LightData lightData, BSDFData bsdfData, BakeLightingData bakeLightingData) |
|||
{ |
|||
DirectLighting lighting; |
|||
ZERO_INITIALIZE(DirectLighting, lighting); |
|||
|
|||
// TODO |
|||
|
|||
return lighting; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// EvaluateBSDF_Rect |
|||
//----------------------------------------------------------------------------- |
|||
|
|||
DirectLighting EvaluateBSDF_Rect( LightLoopContext lightLoopContext, |
|||
float3 V, PositionInputs posInput, |
|||
PreLightData preLightData, LightData lightData, BSDFData bsdfData, BakeLightingData bakeLightingData) |
|||
{ |
|||
DirectLighting lighting; |
|||
ZERO_INITIALIZE(DirectLighting, lighting); |
|||
|
|||
// TODO |
|||
|
|||
return lighting; |
|||
} |
|||
|
|||
DirectLighting EvaluateBSDF_Area(LightLoopContext lightLoopContext, |
|||
float3 V, PositionInputs posInput, |
|||
PreLightData preLightData, LightData lightData, |
|||
BSDFData bsdfData, BakeLightingData bakeLightingData) |
|||
{ |
|||
if (lightData.lightType == GPULIGHTTYPE_LINE) |
|||
{ |
|||
return EvaluateBSDF_Line(lightLoopContext, V, posInput, preLightData, lightData, bsdfData, bakeLightingData); |
|||
} |
|||
else |
|||
{ |
|||
return EvaluateBSDF_Rect(lightLoopContext, V, posInput, preLightData, lightData, bsdfData, bakeLightingData); |
|||
} |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// EvaluateBSDF_SSLighting for screen space lighting |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
IndirectLighting EvaluateBSDF_SSLighting(LightLoopContext lightLoopContext, |
|||
float3 V, PositionInputs posInput, |
|||
PreLightData preLightData, BSDFData bsdfData, |
|||
EnvLightData envLightData, |
|||
int GPUImageBasedLightingType, |
|||
inout float hierarchyWeight) |
|||
{ |
|||
IndirectLighting lighting; |
|||
ZERO_INITIALIZE(IndirectLighting, lighting); |
|||
|
|||
// TODO |
|||
|
|||
return lighting; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// EvaluateBSDF_Env |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
// _preIntegratedFGD and _CubemapLD are unique for each BRDF |
|||
IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, |
|||
float3 V, PositionInputs posInput, |
|||
PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, |
|||
int influenceShapeType, int GPUImageBasedLightingType, |
|||
inout float hierarchyWeight) |
|||
{ |
|||
IndirectLighting lighting; |
|||
ZERO_INITIALIZE(IndirectLighting, lighting); |
|||
|
|||
// TODO |
|||
|
|||
return lighting; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------- |
|||
// PostEvaluateBSDF |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
void PostEvaluateBSDF( LightLoopContext lightLoopContext, |
|||
float3 V, PositionInputs posInput, |
|||
PreLightData preLightData, BSDFData bsdfData, BakeLightingData bakeLightingData, AggregateLighting lighting, |
|||
out float3 diffuseLighting, out float3 specularLighting) |
|||
{ |
|||
AmbientOcclusionFactor aoFactor; |
|||
GetScreenSpaceAmbientOcclusion(posInput.positionSS, preLightData.NdotV, 1.0, 1.0, 1.0, aoFactor); |
|||
ApplyAmbientOcclusionFactor(aoFactor, bakeLightingData, lighting); |
|||
|
|||
// Apply the albedo to the direct diffuse lighting and that's about it. |
|||
// diffuse lighting has already had the albedo applied in GetBakedDiffuseLighting(). |
|||
diffuseLighting = bsdfData.diffuseColor * lighting.direct.diffuse + bakeLightingData.bakeDiffuseLighting; |
|||
specularLighting = lighting.direct.specular + lighting.indirect.specularReflected; |
|||
|
|||
#ifdef DEBUG_DISPLAY |
|||
PostEvaluateBSDFDebugDisplay(aoFactor, bakeLightingData, lighting, bsdfData.diffuseColor, diffuseLighting, specularLighting); |
|||
#endif |
|||
} |
|||
|
|||
#endif // #ifdef HAS_LIGHTLOOP |
撰写
预览
正在加载...
取消
保存
Reference in new issue