浏览代码

Convert LightEvaluation

/improve-shader-generator-data
Sebastien Lagarde 7 年前
当前提交
52fb6cc5
共有 2 个文件被更改,包括 31 次插入28 次删除
  1. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightDefinition.cs
  2. 56
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightEvaluation.hlsl

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightDefinition.cs


};
// These structures share between C# and hlsl need to be align on float4, so we pad them.
// All element should be order by access: Group together variable that are accessed at the same time
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
[GenerateHLSL(PackingRules.AtomicElement)]
public struct DirectionalLightData

public Vector4 shadowMaskSelector; // Use with ShadowMask feature
};
// All element should be order by access: Group together variable that are accessed at the same time
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
[GenerateHLSL(PackingRules.AtomicElement)]
public struct LightData

// 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
// All element should be order by access: Group together variable that are accessed at the same time
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
[GenerateHLSL(PackingRules.AtomicElement)]
public struct EnvLightData

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


// This files include various function uses to evaluate lights
// To use deferred directional shadow with cascaded shadow map,
// To use deferred directional shadow with cascaded shadow map,
// it is required to define USE_DEFERRED_DIRECTIONAL_SHADOWS before including this files
//-----------------------------------------------------------------------------

{
// Translate and rotate 'positionWS' into the light space.
// 'lightData.right' and 'lightData.up' are pre-scaled on CPU.
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
// 'GetRight(lightData)' and 'GetUp(lightData)' are pre-scaled on CPU.
float3x3 lightToWorld = float3x3(GetRight(lightData), GetUp(lightData), GetForward(lightData));
float3 positionLS = mul(lightToSample, transpose(lightToWorld));
// Perform orthographic projection.

float2 positionNDC = positionCS * 0.5 + 0.5;
// We let the sampler handle clamping to border.
return SampleCookie2D(lightLoopContext, positionNDC, lightData.cookieIndex, lightData.tileCookie);
return SampleCookie2D(lightLoopContext, positionNDC, GetCookieIndex(lightData), GetTileCookie(lightData));
}
// None of the outputs are premultiplied.

float shadow = 1.0;
float shadowMask = 1.0;
color = lightData.color;
color = GetColor(lightData);
[branch] if (lightData.cookieIndex >= 0)
[branch] if (GetCookieIndex(lightData) >= 0)
float3 lightToSample = positionWS - lightData.positionWS;
float3 lightToSample = positionWS - GetPositionWS(lightData);
float3 cookie = EvaluateCookie_Directional(lightLoopContext, lightData, lightToSample);
color *= cookie;

// shadowMaskSelector.x is -1 if there is no shadow mask
// Note that we override shadow value (in case we don't have any dynamic shadow)
shadow = shadowMask = (lightData.shadowMaskSelector.x >= 0.0) ? dot(bakeLightingData.bakeShadowMask, lightData.shadowMaskSelector) : 1.0;
shadow = shadowMask = (GetShadowMaskSelector(lightData).x >= 0.0) ? dot(bakeLightingData.bakeShadowMask, GetShadowMaskSelector(lightData)) : 1.0;
[branch] if (lightData.shadowIndex >= 0)
[branch] if (GetShadowIndex(lightData) >= 0)
shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, N, lightData.shadowIndex, L, posInput.positionSS);
shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, N, GetShadowIndex(lightData), L, posInput.positionSS);
float fade = saturate(posInput.linearDepth * lightData.fadeDistanceScaleAndBias.x + lightData.fadeDistanceScaleAndBias.y);
float fade = saturate(posInput.linearDepth * GetFadeDistanceScaleAndBias(lightData).x + GetFadeDistanceScaleAndBias(lightData).y);
shadow = lightData.dynamicShadowCasterOnly ? min(shadowMask, shadow) : shadow;
shadow = GetDynamicShadowCasterOnly(lightData) ? min(shadowMask, shadow) : shadow;
shadow = lerp(shadow, shadowMask, fade); // Caution to lerp parameter: fade is the reverse of shadowDimmer
// Note: There is no shadowDimmer when there is no shadow mask

float4 EvaluateCookie_Punctual(LightLoopContext lightLoopContext, LightData lightData,
float3 lightToSample)
{
int lightType = lightData.lightType;
int lightType = GetLightType(lightData);
// 'lightData.right' and 'lightData.up' are pre-scaled on CPU.
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
// 'GetRight(lightData)' and 'GetUp(lightData)' are pre-scaled on CPU.
float3x3 lightToWorld = float3x3(GetRight(lightData), GetUp(lightData), GetForward(lightData));
float3 positionLS = mul(lightToSample, transpose(lightToWorld));
float4 cookie;

cookie.rgb = SampleCookieCube(lightLoopContext, positionLS, lightData.cookieIndex);
cookie.rgb = SampleCookieCube(lightLoopContext, positionLS, GetCookieIndex(lightData));
cookie.a = 1;
}
else

float2 positionNDC = positionCS * 0.5 + 0.5;
// Manually clamp to border (black).
cookie.rgb = SampleCookie2D(lightLoopContext, positionNDC, lightData.cookieIndex, false);
cookie.rgb = SampleCookie2D(lightLoopContext, positionNDC, GetCookieIndex(lightData), false);
cookie.a = isInBounds ? 1 : 0;
}

float shadow = 1.0;
float shadowMask = 1.0;
color = lightData.color;
attenuation = SmoothPunctualLightAttenuation(distances, lightData.invSqrAttenuationRadius,
lightData.angleScale, lightData.angleOffset);
color = GetColor(lightData);
attenuation = SmoothPunctualLightAttenuation(distances, GetInvSqrAttenuationRadius(lightData),
GetAngleScale(lightData), GetAngleOffset(lightData));
float distVol = (lightData.lightType == GPULIGHTTYPE_PROJECTOR_BOX) ? distances.w : distances.x;
float distVol = (GetLightType(lightData) == GPULIGHTTYPE_PROJECTOR_BOX) ? distances.w : distances.x;
[branch] if (lightData.cookieIndex >= 0)
[branch] if (GetCookieIndex(lightData) >= 0)
{
float4 cookie = EvaluateCookie_Punctual(lightLoopContext, lightData, lightToSample);

#ifdef SHADOWS_SHADOWMASK
// shadowMaskSelector.x is -1 if there is no shadow mask
// Note that we override shadow value (in case we don't have any dynamic shadow)
shadow = shadowMask = (lightData.shadowMaskSelector.x >= 0.0) ? dot(bakeLightingData.bakeShadowMask, lightData.shadowMaskSelector) : 1.0;
shadow = shadowMask = (GetShadowMaskSelector(lightData).x >= 0.0) ? dot(bakeLightingData.bakeShadowMask, GetShadowMaskSelector(lightData)) : 1.0;
[branch] if (lightData.shadowIndex >= 0)
[branch] if (GetShadowIndex(lightData) >= 0)
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, N, lightData.shadowIndex, L_dist, posInput.positionSS);
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, N, GetShadowIndex(lightData), L_dist, posInput.positionSS);
#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)).

// The second case for blend with distance is handled with ShadowDimmer. ShadowDimmer is define manually and by shadowDistance by light.
// With distance, ShadowDimmer become one and only the ShadowMask appear, we get the blend with distance behavior.
shadow = lightData.dynamicShadowCasterOnly ? min(shadowMask, shadow) : shadow;
shadow = lerp(shadowMask, shadow, lightData.shadowDimmer);
shadow = GetDynamicShadowCasterOnly(lightData) ? min(shadowMask, shadow) : shadow;
shadow = lerp(shadowMask, shadow, GetShadowDimmer(lightData));
shadow = lerp(1.0, shadow, lightData.shadowDimmer);
shadow = lerp(1.0, shadow, GetShadowDimmer(lightData));
#endif
}

正在加载...
取消
保存