浏览代码

Contact shadows works with point light and spot lights (in addition to directional)

/main
Antoine Lelievre 6 年前
当前提交
c86387b6
共有 5 个文件被更改,包括 48 次插入19 次删除
  1. 8
      com.unity.render-pipelines.high-definition/HDRP/Lighting/DeferredDirectionalShadow.compute
  2. 2
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightDefinition.cs
  3. 5
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightDefinition.cs.hlsl
  4. 12
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightEvaluation.hlsl
  5. 40
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightLoop/LightLoop.cs

8
com.unity.render-pipelines.high-definition/HDRP/Lighting/DeferredDirectionalShadow.compute


#include "Lighting.hlsl"
#pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
#pragma enable_d3d11_debug_symbol
float3 _LightDirection;
float3 _LightDirection;
float4 _ScreenSpaceShadowsParameters;
int _SampleCount;
CBUFFER_END

float shadow = 1;
if (_ContactShadowLength > 0.0f)
{
float4 result = ScreenSpaceShadowRayCast(posInput.positionWS, normalize(_LightDirection), _ContactShadowLength * max(0.5, posInput.linearDepth * _ContactShadowDistanceScaleFactor));
//Here LightDirection is not the light direction but the light position
float4 result = ScreenSpaceShadowRayCast(posInput.positionWS, normalize(_LightDirection - posInput.positionWS), _ContactShadowLength * max(0.5, posInput.linearDepth * _ContactShadowDistanceScaleFactor));
_DeferredShadowTextureUAV[pixelCoord] = float4(shadow, 0.0, 0.0, 0.0);
_DeferredShadowTextureUAV[pixelCoord] = float4(shadow, _LightDirection);
}

2
com.unity.render-pipelines.high-definition/HDRP/Lighting/LightDefinition.cs


public Vector3 color;
public int shadowIndex; // -1 if unused
public int disableContactShadow; // 1 if disabled
public Vector3 forward;
public int cookieIndex; // -1 if unused

5
com.unity.render-pipelines.high-definition/HDRP/Lighting/LightDefinition.cs.hlsl


float invSqrAttenuationRadius;
float3 color;
int shadowIndex;
int disableContactShadow;
float3 forward;
int cookieIndex;
float3 right;

int GetShadowIndex(LightData value)
{
return value.shadowIndex;
}
int GetDisableContactShadow(LightData value)
{
return value.disableContactShadow;
}
float3 GetForward(LightData value)
{

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


float3 N, float3 L, float3 lightToSample, float4 distances,
out float3 color, out float attenuation)
{
float3 positionWS = posInput.positionWS;
float shadow = 1.0;
float shadowMask = 1.0;
float3 positionWS = posInput.positionWS;
float shadow = 1.0;
float shadowMask = 1.0;
float contactShadow = 1.0;
color = lightData.color;
attenuation = SmoothPunctualLightAttenuation(distances, lightData.invSqrAttenuationRadius,

UNITY_BRANCH if (lightData.shadowIndex >= 0)
{
// TODO: make projector lights cast shadows.
contactShadow = LOAD_TEXTURE2D(_DeferredShadowTexture, posInput.positionSS).x;
shadow = min(max(lightData.disableContactShadow, contactShadow), shadow);
#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)
// and ShadowMask_Distance (ShadowMask contain static objects shadow and ShadowMap contain everything and is blend with ShadowMask based on distance (Global distance setup in QualitySettigns)).

40
com.unity.render-pipelines.high-definition/HDRP/Lighting/LightLoop/LightLoop.cs


Light m_CurrentSunLight;
int m_CurrentSunLightShadowIndex = -1;
LightData m_DominantLightData;
int m_DominantLightIndex = -1;
public Light GetCurrentSunLight() { return m_CurrentSunLight; }

var lightData = new LightData();
lightData.lightType = gpuLightType;
lightData.disableContactShadow = 1;
lightData.positionWS = light.light.transform.position;
// Setting 0 for invSqrAttenuationRadius mean we have no range attenuation, but still have inverse square attenuation.

// We need to properly reset this here otherwise if we go from 1 light to no visible light we would keep the old reference active.
m_CurrentSunLight = null;
m_CurrentSunLightShadowIndex = -1;
m_DominantLightIndex = -1;
var stereoEnabled = m_FrameSettings.enableStereo;

//TODO: move this upwards
float biggestLight = 0;
int dominantLightDataIndex = 0;
for (int sortIndex = 0; sortIndex < sortCount; ++sortIndex)
{

lightData.positionWS -= camPosWS;
m_lightList.directionalLights[last] = lightData;
}
if (additionalShadowData.contactShadows)
biggestLight = Single.PositiveInfinity;
}
continue;
}

// Punctual, area, projector lights - the rendering side.
if (GetLightData(cmd, shadowSettings, camera, gpuLightType, light, additionalLightData, additionalShadowData, lightIndex, ref lightDimensions))
{
int last = m_lightList.lights.Count - 1;
switch (lightCategory)
{
case LightCategory.Punctual:

Debug.Assert(false, "TODO: encountered an unknown LightCategory.");
break;
}
if (additionalShadowData != null && additionalShadowData.contactShadows && lightDimensions.magnitude > biggestLight)
{
m_DominantLightIndex = lightIndex;
biggestLight = lightDimensions.magnitude;
}
// Then culling side. Must be call in this order as we pass the created Light data to the function
GetLightVolumeDataAndBound(lightCategory, gpuLightType, lightVolumeType, light, m_lightList.lights[m_lightList.lights.Count - 1], lightDimensions, worldToView);

if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// Caution: 'LightData.positionWS' is camera-relative after this point.
int last = m_lightList.lights.Count - 1;
if (additionalShadowData != null && additionalShadowData.contactShadows && lightDimensions.magnitude > biggestLight)
{
m_DominantLightData = m_lightList.lights[m_lightList.lights.Count - 1];
m_DominantLightIndex = lightIndex;
dominantLightDataIndex = last;
biggestLight = lightDimensions.magnitude;
}
}
//Activate contact shadows on dominant light
if (m_DominantLightIndex != -1)
{
m_DominantLightData.disableContactShadow = 0;
m_lightList.lights[dominantLightDataIndex] = m_DominantLightData;
}
// Sanity check

cmd.SetGlobalTexture(HDShaderIDs._DeferredShadowTexture, RuntimeUtilities.blackTexture);
return;
}
using (new ProfilingSample(cmd, "Deferred Directional Shadow", CustomSamplerId.TPDeferredDirectionalShadow.GetSampler()))
{
ContactShadows contactShadows = VolumeManager.instance.stack.GetComponent<ContactShadows>();

// Debug.Log("contactShadowsSettings: " + contactShadows.enable);
Debug.Log("Contact shadows enabled !");
{
}
else
kernel = s_deferredDirectionalShadow_Contact_Kernel;
}

if (m_CurrentSunLight != null)
lightDirection = -m_CurrentSunLight.transform.forward;
else
lightDirection = Vector3.one; //TODO: put dominant light direction here
lightDirection = m_DominantLightData.positionWS;
m_ShadowMgr.BindResources(cmd, deferredDirectionalShadowComputeShader, kernel);

正在加载...
取消
保存