浏览代码

Fixed contact shadows with light transmission

/main
Antoine Lelievre 6 年前
当前提交
38287b48
共有 4 个文件被更改,包括 29 次插入24 次删除
  1. 19
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightEvaluation.hlsl
  2. 12
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.compute
  3. 11
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl
  4. 11
      com.unity.render-pipelines.high-definition/HDRP/Material/StackLit/StackLit.hlsl

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


void EvaluateLight_Directional(LightLoopContext lightLoopContext, PositionInputs posInput,
DirectionalLightData lightData, BakeLightingData bakeLightingData,
float3 N, float3 L,
out float3 color, out float attenuation)
out float3 color, out float attenuation, out float attenuationNoContactShadow)
{
float3 positionWS = posInput.positionWS;
float shadow = 1.0;

shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, N, lightData.shadowIndex, L, posInput.positionSS);
#endif
float contactShadow = GetContactShadow(lightLoopContext, lightData.contactShadowIndex);
shadow = min(shadow, contactShadow);
#ifdef SHADOWS_SHADOWMASK
// TODO: Optimize this code! Currently it is a bit like brute force to get the last transistion and fade to shadow mask, but there is

// Note: There is no shadowDimmer when there is no shadow mask
#endif
attenuationNoContactShadow = attenuation * shadow;
float contactShadow = GetContactShadow(lightLoopContext, lightData.contactShadowIndex);
shadow = min(shadow, contactShadow);
}
attenuation *= shadow;

void EvaluateLight_Punctual(LightLoopContext lightLoopContext, PositionInputs posInput,
LightData lightData, BakeLightingData bakeLightingData,
float3 N, float3 L, float3 lightToSample, float4 distances,
out float3 color, out float attenuation, out float attenuationWithoutContactShadows)
out float3 color, out float attenuation, out float attenuationNoContactShadows)
{
float3 positionWS = posInput.positionWS;
float shadow = 1.0;

attenuationNoContactShadows = 1;
color = lightData.color;
attenuation = SmoothPunctualLightAttenuation(distances, lightData.invSqrAttenuationRadius,
lightData.angleScale, lightData.angleOffset);

{
// TODO: make projector lights cast shadows.
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS, N, lightData.shadowIndex, L, distances.x, posInput.positionSS);
contactShadow = GetContactShadow(lightLoopContext, lightData.contactShadowIndex);
#ifdef SHADOWS_SHADOWMASK
// Note: Legacy Unity have two shadow mask mode. ShadowMask (ShadowMask contain static objects shadow and ShadowMap contain only dynamic objects shadow, final result is the minimun of both value)

shadow = lerp(1.0, shadow, lightData.shadowDimmer);
#endif
attenuationWithoutContactShadows = attenuation * shadow;
attenuationNoContactShadows = shadow * attenuation;
contactShadow = GetContactShadow(lightLoopContext, lightData.contactShadowIndex);
shadow = min(shadow, contactShadow);
}

12
com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.compute


DirectionalLightData light = _DirectionalLightDatas[i];
float3 L = -light.forward; // Lights point backwards in Unity
float3 color; float attenuation;
float3 color; float attenuation; float attenuationNoContactShadows;
color, attenuation);
color, attenuation, attenuationNoContactShadows);
// Important:
// Ideally, all scattering calculations should use the jittered versions

float4 distances = float4(dist, distSq, distRcp, distProj);
float3 L = -lightToSample * distRcp;
float3 color; float attenuation; float attenuationWithoutContactShadow;
float3 color; float attenuation; float attenuationNoContactShadows;
attenuation, attenuationWithoutContactShadow);
attenuation, attenuationNoContactShadows);
// Important:
// Ideally, all scattering calculations should use the jittered versions

float distProj = dot(lightToSample, light.forward);
float4 distances = float4(1, 1, 1, distProj);
float3 color; float attenuation; float attenuationWithoutContactShadow;
float3 color; float attenuation; float attenuationNoContactShadows;
attenuation, attenuationWithoutContactShadow);
attenuation, attenuationNoContactShadows);
// Important:
// Ideally, all scattering calculations should use the jittered versions

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


float3 color;
float attenuation;
EvaluateLight_Directional(lightLoopContext, posInput, lightData, bakeLightingData, N, L, color, attenuation);
float attenuationNoContactShadows;
EvaluateLight_Directional(lightLoopContext, posInput, lightData, bakeLightingData, N, L, color, attenuation, attenuationNoContactShadows);
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)

if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION) && !mixedThicknessMode)
{
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, bsdfData.transmittance, NdotL, NdotV, LdotV, attenuation * lightData.diffuseScale);
lighting.diffuse += EvaluateTransmission(bsdfData, bsdfData.transmittance, NdotL, NdotV, LdotV, attenuationNoContactShadows * lightData.diffuseScale);
}
// Save ALU by applying light and cookie colors only once.

float3 color;
float attenuation;
float attenuationWithoutContactShadow;
float attenuationNoContactShadows;
lightToSample, distances, color, attenuation, attenuationWithoutContactShadow);
lightToSample, distances, color, attenuation, attenuationNoContactShadows);
// Restore the original shadow index.
lightData.shadowIndex = originalShadowIndex;

// Note: we do not modify the distance to the light, or the light angle for the back face.
// This is a performance-saving optimization which makes sense as long as the thickness is small.
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, transmittance, NdotL, NdotV, LdotV, attenuationWithoutContactShadow * lightData.diffuseScale);
lighting.diffuse += EvaluateTransmission(bsdfData, transmittance, NdotL, NdotV, LdotV, attenuationNoContactShadows * lightData.diffuseScale);
}
// Save ALU by applying light and cookie colors only once.

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


// color and attenuation are outputted by EvaluateLight:
float3 color;
float attenuation;
float attenuationNoContactShadows;
EvaluateLight_Directional(lightLoopContext, posInput, lightData, bakeLightingData, bsdfData.geomNormalWS, L, color, attenuation);
EvaluateLight_Directional(lightLoopContext, posInput, lightData, bakeLightingData, bsdfData.geomNormalWS, L, color, attenuation, attenuationNoContactShadows);
float intensity = max(0, attenuation); // Warning: attenuation can be greater than 1 due to the inverse square attenuation (when position is close to light)

if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_STACK_LIT_TRANSMISSION) && !mixedThicknessMode)
{
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, bsdfData.transmittance, NdotL, NdotV, LdotV, attenuation * lightData.diffuseScale);
lighting.diffuse += EvaluateTransmission(bsdfData, bsdfData.transmittance, NdotL, NdotV, LdotV, attenuationNoContactShadows * lightData.diffuseScale);
}
// Save ALU by applying light and cookie colors only once.

float3 color;
float attenuation;
float attenuationWithoutContactShadow;
float attenuationNoContactShadows;
lightToSample, distances, color, attenuation, attenuationWithoutContactShadow);
lightToSample, distances, color, attenuation, attenuationNoContactShadows);
// Restore the original shadow index.
lightData.shadowIndex = originalShadowIndex;

// Note: we do not modify the distance to the light, or the light angle for the back face.
// This is a performance-saving optimization which makes sense as long as the thickness is small.
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
lighting.diffuse += EvaluateTransmission(bsdfData, transmittance, NdotL, NdotV, LdotV, attenuationWithoutContactShadow * lightData.diffuseScale);
lighting.diffuse += EvaluateTransmission(bsdfData, transmittance, NdotL, NdotV, LdotV, attenuationNoContactShadows * lightData.diffuseScale);
}
// Save ALU by applying light and cookie colors only once.

正在加载...
取消
保存