浏览代码

Added optimized single light path for DIRECTIONAL, SPOT, POINT

/RenderPassXR_Sandbox
Felipe Lira 7 年前
当前提交
c9cb44ad
共有 7 个文件被更改,包括 227 次插入142 次删除
  1. 189
      Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs
  2. 49
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader
  3. 5
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineBRDF.cginc
  4. 9
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineCore.cginc
  5. 26
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineInput.cginc
  6. 87
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineLighting.cginc
  7. 4
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineShadows.cginc

189
Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs


public int pixelLightsCount;
public int vertexLightsCount;
public int shadowLightIndex;
public bool isSingleDirectionalLight;
public bool isSingleLight;
public bool shadowsRendered;
}

private Vector4[] m_LightSpotDirections = new Vector4[kMaxVisibleLights];
private Camera m_CurrCamera = null;
private LightType m_SingleLightType = LightType.Directional;
private int m_LightIndicesCount = 0;
private ComputeBuffer m_LightIndexListBuffer;

if (m_Asset.EnableAmbientProbe)
configuration |= RendererConfiguration.PerObjectLightProbe;
if (!lightData.isSingleDirectionalLight)
if (!lightData.isSingleLight)
configuration |= RendererConfiguration.PerObjectLightIndices8;

private void InitializeLightData(VisibleLight[] lights, out LightData lightData)
{
for (int i = 0; i < kMaxVisibleLights; ++i)
{
m_LightPositions[i] = Vector4.zero;
m_LightColors[i] = Vector4.zero;
m_LightAttenuations[i] = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
m_LightSpotDirections[i] = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
}
lightData.isSingleDirectionalLight = lightData.pixelLightsCount == 1 && lightData.vertexLightsCount == 0 && lights[0].lightType == LightType.Directional;
// Directional light path can handle unlit.
if (lightsCount == 0)
lightData.isSingleDirectionalLight = true;
// TODO: Handle Vertex lights in this case
lightData.isSingleLight = lightData.pixelLightsCount <= 1;
if (lightData.isSingleLight)
m_SingleLightType = (lightData.pixelLightsCount == 1) ? lights[0].lightType : LightType.Directional;
lightData.shadowsRendered = false;

private void SetupShaderLightConstants(VisibleLight[] lights, ref LightData lightData, ref CullResults cullResults, ref ScriptableRenderContext context)
{
if (lights.Length == 0)
if (lightData.isSingleLight)
SetupShaderSingleLightConstants(lights, (lightData.pixelLightsCount > 0) ? 0 : -1, ref context);
else
SetupShaderLightListConstants(lights, ref lightData, ref context);
}
private void InitializeLightConstants(VisibleLight[] lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightSpotDir,
out Vector4 lightAttenuationParams)
{
lightPos = Vector4.zero;
lightColor = Color.black;
lightAttenuationParams = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
lightSpotDir = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
// When no lights are available in the pipeline or maxPixelLights is set to 0
// In this case we want to initialize the lightData to default values and return
if (lightIndex < 0)
if (lightData.isSingleDirectionalLight)
SetupShaderSingleDirectionalLightConstants(ref lights [0], ref context);
VisibleLight light = lights[lightIndex];
if (light.lightType == LightType.Directional)
{
Vector4 dir = -light.localToWorld.GetColumn(2);
lightPos = new Vector4(dir.x, dir.y, dir.z, 0.0f);
}
else
{
Vector4 pos = light.localToWorld.GetColumn(3);
lightPos = new Vector4(pos.x, pos.y, pos.z, 1.0f);
}
lightColor = light.finalColor;
float rangeSq = light.range * light.range;
float quadAtten = (light.lightType == LightType.Directional) ? 0.0f : 25.0f / rangeSq;
if (light.lightType == LightType.Spot)
{
Vector4 dir = light.localToWorld.GetColumn(2);
lightSpotDir = new Vector4(-dir.x, -dir.y, -dir.z, 0.0f);
float spotAngle = Mathf.Deg2Rad * light.spotAngle;
float cosOuterAngle = Mathf.Cos(spotAngle * 0.5f);
float cosInneAngle = Mathf.Cos(spotAngle * 0.25f);
float angleRange = cosInneAngle - cosOuterAngle;
lightAttenuationParams = new Vector4(cosOuterAngle,
Mathf.Approximately(angleRange, 0.0f) ? 1.0f : angleRange, quadAtten, rangeSq);
}
SetupShaderLightListConstants(lights, ref lightData, ref context);
{
lightSpotDir = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
lightAttenuationParams = new Vector4(-1.0f, 1.0f, quadAtten, rangeSq);
}
private void SetupShaderSingleDirectionalLightConstants(ref VisibleLight light, ref ScriptableRenderContext context)
private void SetupShaderSingleLightConstants(VisibleLight[] lights, int lightIndex, ref ScriptableRenderContext context)
Vector4 lightDir = -light.localToWorld.GetColumn(2);
Vector4 lightPos, lightColor, lightSpotDir, lightAttenuationParams;
InitializeLightConstants(lights, lightIndex, out lightPos, out lightColor, out lightSpotDir, out lightAttenuationParams);
CommandBuffer cmd = new CommandBuffer() { name = "SetupLightConstants" };
cmd.SetGlobalVector("_LightPosition0", new Vector4(lightDir.x, lightDir.y, lightDir.z, 0.0f));
cmd.SetGlobalColor("_LightColor0", light.finalColor);
CommandBuffer cmd = new CommandBuffer() { name = "SetupSingleLightConstants" };
cmd.SetGlobalVector("_LightPosition", lightPos);
cmd.SetGlobalColor("_LightColor", lightColor);
cmd.SetGlobalVector("_LightSpotDir", lightSpotDir);
cmd.SetGlobalVector("_LightAttenuationParams", lightAttenuationParams);
if (m_Asset.AttenuationTexture != null) cmd.SetGlobalTexture("_AttenuationTexture", m_Asset.AttenuationTexture);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}

int maxLights = Math.Min(kMaxVisibleLights, lights.Length);
for (int i = 0; i < maxLights; ++i)
{
VisibleLight currLight = lights [i];
if (currLight.lightType == LightType.Directional)
{
Vector4 dir = -currLight.localToWorld.GetColumn (2);
m_LightPositions [i] = new Vector4 (dir.x, dir.y, dir.z, 0.0f);
}
else
{
Vector4 pos = currLight.localToWorld.GetColumn (3);
m_LightPositions [i] = new Vector4 (pos.x, pos.y, pos.z, 1.0f);
}
m_LightColors[i] = currLight.finalColor;
float rangeSq = currLight.range * currLight.range;
float quadAtten = (currLight.lightType == LightType.Directional) ? 0.0f : 25.0f / rangeSq;
if (currLight.lightType == LightType.Spot)
{
Vector4 dir = currLight.localToWorld.GetColumn (2);
m_LightSpotDirections [i] = new Vector4 (-dir.x, -dir.y, -dir.z, 0.0f);
float spotAngle = Mathf.Deg2Rad * currLight.spotAngle;
float cosOuterAngle = Mathf.Cos (spotAngle * 0.5f);
float cosInneAngle = Mathf.Cos (spotAngle * 0.25f);
float angleRange = cosInneAngle - cosOuterAngle;
m_LightAttenuations [i] = new Vector4 (cosOuterAngle,
Mathf.Approximately (angleRange, 0.0f) ? 1.0f : angleRange, quadAtten, rangeSq);
}
else
{
m_LightSpotDirections [i] = new Vector4 (0.0f, 0.0f, 1.0f, 0.0f);
m_LightAttenuations [i] = new Vector4 (-1.0f, 1.0f, quadAtten, rangeSq);
}
}
InitializeLightConstants(lights, i, out m_LightPositions[i], out m_LightColors[i], out m_LightSpotDirections[i], out m_LightAttenuations[i]);
// Lightweight pipeline only upload kMaxVisibleLights to shader cbuffer.
// We tell the pipe to disable remaining lights by setting it to -1.

m_CullResults.SetLightIndexMap(lightIndexMap);
CommandBuffer cmd = CommandBufferPool.Get("SetupShadowShaderConstants");
CommandBuffer cmd = CommandBufferPool.Get("SetupLightShaderConstants");
cmd.SetGlobalVector("globalLightCount", new Vector4 (lightData.pixelLightsCount, lightData.vertexLightsCount, 0.0f, 0.0f));
cmd.SetGlobalVectorArray ("globalLightPos", m_LightPositions);
cmd.SetGlobalVectorArray ("globalLightColor", m_LightColors);

private void SetShaderKeywords(ref LightData lightData, ref ScriptableRenderContext context)
{
CommandBuffer cmd = new CommandBuffer() { name = "SetShaderKeywords" };
SetShaderKeywords(cmd, lightData.shadowsRendered, lightData.isSingleDirectionalLight, lightData.vertexLightsCount > 0);
SetShaderKeywords(cmd, lightData.shadowsRendered, lightData.isSingleLight, lightData.vertexLightsCount > 0);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}

CommandBufferPool.Release(setupShadow);
}
private void SetShaderKeywords(CommandBuffer cmd, bool renderShadows, bool singleDirecitonal, bool vertexLightSupport)
private void SetKeyword(CommandBuffer cmd, string keyword, bool enable)
if (m_Asset.ForceLinearRendering)
cmd.EnableShaderKeyword("LIGHTWEIGHT_LINEAR");
if (enable)
cmd.EnableShaderKeyword(keyword);
cmd.DisableShaderKeyword("LIGHTWEIGHT_LINEAR");
cmd.DisableShaderKeyword(keyword);
}
if (vertexLightSupport)
cmd.EnableShaderKeyword("_VERTEX_LIGHTS");
private void SetShaderKeywords(CommandBuffer cmd, bool renderShadows, bool singleLight, bool vertexLightSupport)
{
SetKeyword(cmd, "LIGHTWEIGHT_LINEAR", m_Asset.ForceLinearRendering);
SetKeyword(cmd, "_VERTEX_LIGHTS", vertexLightSupport);
SetKeyword(cmd, "_ATTENUATION_TEXTURE", m_Asset.AttenuationTexture != null);
SetKeyword(cmd, "_LIGHT_PROBES_ON", m_Asset.EnableAmbientProbe);
SetKeyword(cmd, "LIGHTWEIGHT_LINEAR", m_Asset.ForceLinearRendering);
if (!singleLight)
{
SetKeyword(cmd, "_SINGLE_DIRECTIONAL_LIGHT", false);
SetKeyword(cmd, "_SINGLE_SPOT_LIGHT", false);
SetKeyword(cmd, "_SINGLE_POINT_LIGHT", false);
}
cmd.DisableShaderKeyword("_VERTEX_LIGHTS");
{
switch (m_SingleLightType)
{
case LightType.Directional:
SetKeyword(cmd, "_SINGLE_DIRECTIONAL_LIGHT", true);
SetKeyword(cmd, "_SINGLE_SPOT_LIGHT", false);
SetKeyword(cmd, "_SINGLE_POINT_LIGHT", false);
break;
if (singleDirecitonal)
cmd.EnableShaderKeyword("_SINGLE_DIRECTIONAL_LIGHT");
else
cmd.DisableShaderKeyword("_SINGLE_DIRECTIONAL_LIGHT");
case LightType.Spot:
SetKeyword(cmd, "_SINGLE_DIRECTIONAL_LIGHT", false);
SetKeyword(cmd, "_SINGLE_SPOT_LIGHT", true);
SetKeyword(cmd, "_SINGLE_POINT_LIGHT", false);
break;
if (m_Asset.AttenuationTexture != null)
cmd.EnableShaderKeyword("_ATTENUATION_TEXTURE");
else
cmd.DisableShaderKeyword("_ATTENUATION_TEXTURE");
case LightType.Point:
SetKeyword(cmd, "_SINGLE_DIRECTIONAL_LIGHT", false);
SetKeyword(cmd, "_SINGLE_SPOT_LIGHT", false);
SetKeyword(cmd, "_SINGLE_POINT_LIGHT", true);
break;
}
}
string[] shadowKeywords = new string[] { "_HARD_SHADOWS", "_SOFT_SHADOWS", "_HARD_SHADOWS_CASCADES", "_SOFT_SHADOWS_CASCADES" };
for (int i = 0; i < shadowKeywords.Length; ++i)

keywordIndex += 2;
cmd.EnableShaderKeyword(shadowKeywords[keywordIndex]);
}
if (m_Asset.EnableAmbientProbe)
cmd.EnableShaderKeyword("_LIGHT_PROBES_ON");
else
cmd.DisableShaderKeyword("_LIGHT_PROBES_ON");
}
private void InitializeMainShadowLightIndex(VisibleLight[] lights, out int shadowIndex)

49
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader


#pragma multi_compile _ LIGHTWEIGHT_LINEAR
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#pragma multi_compile _ _SINGLE_DIRECTIONAL_LIGHT
#pragma multi_compile _ _SINGLE_DIRECTIONAL_LIGHT _SINGLE_SPOT_LIGHT _SINGLE_POINT_LIGHT
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ _LIGHT_PROBES_ON
#pragma multi_compile _ _HARD_SHADOWS _SOFT_SHADOWS _HARD_SHADOWS_CASCADES _SOFT_SHADOWS_CASCADES

#endif
o.hpos = UnityObjectToClipPos(v.vertex);
o.posWS = mul(unity_ObjectToWorld, v.vertex).xyz;
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.posWS = worldPos;
o.viewDir.xyz = normalize(_WorldSpaceCameraPos - o.posWS);
half3 normal = normalize(UnityObjectToWorldNormal(v.normal));

o.normal = normal;
#endif
#if defined(_VERTEX_LIGHTS) && !defined(_SINGLE_DIRECTIONAL_LIGHT)
half4 diffuseAndSpecular = half4(1.0, 1.0, 1.0, 1.0);
// TODO: change to only support point lights per vertex. This will greatly simplify shader ALU
#if defined(_VERTEX_LIGHTS) && defined(_MULTIPLE_LIGHTS)
half3 diffuse = half3(1.0, 1.0, 1.0);
// pixel lights shaded = min(pixelLights, perObjectLights)
// vertex lights shaded = min(vertexLights, perObjectLights) - pixel lights shaded
// Therefore vertexStartIndex = pixelLightCount; vertexEndIndex = min(vertexLights, perObjectLights)

int lightIndex = unity_4LightIndices0[lightIter];
LightInput lightInput;
INITIALIZE_LIGHT(lightInput, lightIndex);
o.fogCoord.yzw += EvaluateOneLight(lightInput, diffuseAndSpecular.rgb, diffuseAndSpecular, normal, o.posWS, o.viewDir.xyz);
half3 lightDirection;
half atten = ComputeLightAttenuationVertex(lightInput, normal, worldPos, lightDirection);
o.fogCoord.yzw += LightingLambert(diffuse, lightDirection, normal, atten);
}
#endif

half3 viewDir = i.viewDir.xyz;
#ifdef _SINGLE_DIRECTIONAL_LIGHT
half3 color = EvaluateDirectionalLight(diffuse, specularGloss, normal, _LightPosition0, viewDir) * _LightColor0;
#ifdef _SHADOWS
color *= ComputeShadowAttenuation(i, _LightPosition0.xyz);
#endif
half3 lightDirection;
#ifndef _MULTIPLE_LIGHTS
LightInput lightInput;
INITIALIZE_MAIN_LIGHT(lightInput);
half lightAtten = ComputeLightAttenuation(lightInput, normal, i.posWS, lightDirection);
#ifdef _SHADOWS
lightAtten *= ComputeShadowAttenuation(i, _ShadowLightDirection.xyz);
#endif
#ifdef LIGHTWEIGHT_SPECULAR_HIGHLIGHTS
half3 color = LightingBlinnPhong(diffuse, specularGloss, lightDirection, normal, viewDir, lightAtten) * lightInput.color;
#else
half3 color = LightingLambert(diffuse, lightDirection, normal, lightAtten) * lightInput.color;
#endif
#ifdef _SHADOWS
half shadowAttenuation = ComputeShadowAttenuation(i, _ShadowLightDirection.xyz);
#endif

LightInput lightData;
int lightIndex = unity_4LightIndices0[lightIter];
INITIALIZE_LIGHT(lightData, lightIndex);
half lightAtten = ComputeLightAttenuation(lightData, normal, i.posWS, lightDirection);
half currLightAttenuation = max(shadowAttenuation, half(lightIter != _ShadowData.x));
color += EvaluateOneLight(lightData, diffuse, specularGloss, normal, i.posWS, viewDir) * currLightAttenuation;
lightAtten *= max(shadowAttenuation, half(lightIter != _ShadowData.x));
#endif
#ifdef LIGHTWEIGHT_SPECULAR_HIGHLIGHTS
color += LightingBlinnPhong(diffuse, specularGloss, lightDirection, normal, viewDir, lightAtten) * lightData.color;
color += EvaluateOneLight(lightData, diffuse, specularGloss, normal, i.posWS, viewDir);
color += LightingLambert(diffuse, lightDirection, normal, lightAtten) * lightData.color;
#endif // SINGLE_DIRECTIONAL_LIGHT
#endif // _MULTIPLE_LIGHTS
#ifdef _EMISSION
color += LIGHTWEIGHT_GAMMA_TO_LINEAR(tex2D(_EmissionMap, i.uv01.xy).rgb) * _EmissionColor;

5
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineBRDF.cginc


#ifndef LIGHTWEIGHT_BRDF_INCLUDED
#define LIGHTWEIGHT_BRDF_INCLUDED
half MetallicSetup_Reflectivity()
{
return 1.0h - OneMinusReflectivityFromMetallic(_Metallic);
}
//sampler2D unity_NHxRoughness;
half3 LightweightBRDFDirect(half3 diffColor, half3 specColor, half smoothness, half RdotL)
{

9
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineCore.cginc


#include "LightweightPipelineShadows.cginc"
#endif
#if defined(_SPECGLOSSMAP_BASE_ALPHA) || defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
#define LIGHTWEIGHT_SPECULAR_HIGHLIGHTS
#endif
// Does not support: _PARALLAXMAP, DIRLIGHTMAP_COMBINED
#define GLOSSMAP (defined(_SPECGLOSSMAP) || defined(_METALLICGLOSSMAP))

#else
return half4(LIGHTWEIGHT_LINEAR_TO_GAMMA(color), 1);
#endif
}
half MetallicSetup_Reflectivity()
{
return 1.0h - OneMinusReflectivityFromMetallic(_Metallic);
}
#ifdef _NORMALMAP

26
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineInput.cginc


#define MAX_VISIBLE_LIGHTS 16
// Main light initialized without indexing
#define INITIALIZE_MAIN_LIGHT(light) \
light.pos = _LightPosition; \
light.color = _LightColor; \
light.atten = _LightAttenuationParams; \
light.spotDir = _LightSpotDir;
// Indexing might have a performance hit for old mobile hardware
#define INITIALIZE_LIGHT(light, lightIndex) \
light.pos = globalLightPos[lightIndex]; \
light.color = globalLightColor[lightIndex]; \

#if !(defined(_SINGLE_DIRECTIONAL_LIGHT) || defined(_SINGLE_SPOT_LIGHT) || defined(_SINGLE_POINT_LIGHT))
#define _MULTIPLE_LIGHTS
#endif
half4 pos;
float4 pos;
half4 atten;
float4 atten;
half4 spotDir;
};

#ifndef _SINGLE_DIRECTIONAL_LIGHT
#ifdef _MULTIPLE_LIGHTS
half4 unity_LightIndicesOffsetAndCount;
half4 unity_4LightIndices0;

half4 globalLightColor[MAX_VISIBLE_LIGHTS];
float4 globalLightPos[MAX_VISIBLE_LIGHTS];
half4 globalLightSpotDir[MAX_VISIBLE_LIGHTS];
half4 globalLightAtten[MAX_VISIBLE_LIGHTS];
float4 globalLightAtten[MAX_VISIBLE_LIGHTS];
float4 _LightPosition0;
float4 _LightPosition;
half4 _LightColor;
float4 _LightAttenuationParams;
half4 _LightSpotDir;
struct LightweightVertexInput
{

87
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineLighting.cginc


return o;
}
inline half3 EvaluateDirectionalLight(half3 diffuseColor, half4 specularGloss, half3 normal, half3 lightDir, half3 viewDir)
inline half ComputeLightAttenuationVertex(LightInput lightInput, half3 normal, float3 worldPos, out half3 lightDirection)
half NdotL = saturate(dot(normal, lightDir));
half3 diffuse = diffuseColor * NdotL;
float4 attenuationParams = lightInput.atten;
float3 posToLightVec = lightInput.pos - worldPos;
float distanceSqr = max(dot(posToLightVec, posToLightVec), 0.001);
#if defined(_SPECGLOSSMAP_BASE_ALPHA) || defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
half3 halfVec = normalize(lightDir + viewDir);
half NdotH = saturate(dot(normal, halfVec));
half3 specular = specularGloss.rgb * pow(NdotH, _Shininess * 128.0) * specularGloss.a;
return diffuse + specular;
#else
return diffuse;
//// attenuationParams.z = kQuadFallOff = (25.0) / (lightRange * lightRange)
//// attenuationParams.w = lightRange * lightRange
//// TODO: we can precompute 1.0 / (attenuationParams.w * 0.64 - attenuationParams.w)
//// falloff is computed from 80% light range squared
float lightAtten = half(1.0 / (1.0 + distanceSqr * attenuationParams.z));
// normalized light dir
lightDirection = half3(posToLightVec * rsqrt(distanceSqr));
#if !(defined(_SINGLE_POINT_LIGHT) || defined(_SINGLE_DIRECTIONAL_LIGHT))
half SdotL = saturate(dot(lightInput.spotDir.xyz, lightDirection));
lightAtten *= saturate((SdotL - attenuationParams.x) / attenuationParams.y);
return half(lightAtten);
inline half3 EvaluateOneLight(LightInput lightInput, half3 diffuseColor, half4 specularGloss, half3 normal, float3 posWorld, half3 viewDir)
inline half ComputeLightAttenuation(LightInput lightInput, half3 normal, float3 worldPos, out half3 lightDirection)
float3 posToLight = lightInput.pos.xyz;
posToLight -= posWorld * lightInput.pos.w;
float4 attenuationParams = lightInput.atten;
#ifdef _SINGLE_DIRECTIONAL_LIGHT
// Light pos holds normalized light dir
lightDirection = lightInput.pos;
return 1.0;
float distanceSqr = max(dot(posToLight, posToLight), 0.001);
#else
float3 posToLightVec = lightInput.pos.xyz - worldPos * lightInput.pos.w;
float distanceSqr = max(dot(posToLightVec, posToLightVec), 0.001);
half lightAtten = tex2D(_AttenuationTexture, float2(distanceSqr / lightInput.atten.w, 0.0)).a;
float lightAtten = tex2D(_AttenuationTexture, float2(distanceSqr / attenuationParams.w, 0.0)).a;
//// lightInput.atten.z = kQuadFallOff = (25.0) / (lightRange * lightRange)
//// lightInput.atten.w = lightRange * lightRange
//// TODO: we can precompute 1.0 / (lightInput.atten.w * 0.64 - lightInput.atten.w)
//// attenuationParams.z = kQuadFallOff = (25.0) / (lightRange * lightRange)
//// attenuationParams.w = lightRange * lightRange
//// TODO: we can precompute 1.0 / (attenuationParams.w * 0.64 - attenuationParams.w)
float lightAtten = 1.0 / (1.0 + distanceSqr * lightInput.atten.z);
float falloff = saturate((distanceSqr - lightInput.atten.w) / (lightInput.atten.w * 0.64 - lightInput.atten.w));
lightAtten *= falloff;
float lightAtten = half(1.0 / (1.0 + distanceSqr * attenuationParams.z));
float falloff = saturate((distanceSqr - attenuationParams.w) / (attenuationParams.w * 0.64 - attenuationParams.w));
lightAtten *= half(falloff);
float3 lightDir = posToLight * rsqrt(distanceSqr);
half SdotL = saturate(dot(lightInput.spotDir.xyz, lightDir));
lightAtten *= saturate((SdotL - lightInput.atten.x) / lightInput.atten.y);
// normalized light dir
lightDirection = half3(posToLightVec * rsqrt(distanceSqr));
#ifndef _SINGLE_POINT_LIGHT
half SdotL = saturate(dot(lightInput.spotDir.xyz, lightDirection));
lightAtten *= saturate((SdotL - attenuationParams.x) / attenuationParams.y);
#endif
return half(lightAtten);
#endif // _SINGLE_DIRECTIONAL_LIGHT
}
inline half3 LightingLambert(half3 diffuseColor, half3 lightDir, half3 normal, half atten)
{
return diffuseColor * (NdotL * atten);
}
half3 lightColor = lightInput.color.rgb * lightAtten;
half3 diffuse = diffuseColor * lightColor * NdotL;
inline half3 LightingBlinnPhong(half3 diffuseColor, half4 specularGloss, half3 lightDir, half3 normal, half3 viewDir, half atten)
{
half NdotL = saturate(dot(normal, lightDir));
half3 diffuse = diffuseColor * NdotL;
#if defined(_SPECGLOSSMAP_BASE_ALPHA) || defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
half3 specular = specularGloss.rgb * lightColor * pow(NdotH, _Shininess * 128.0) * specularGloss.a;
return diffuse + specular;
#else
return diffuse;
#endif
half3 specular = specularGloss.rgb * (pow(NdotH, _Shininess * 128.0) * specularGloss.a);
return (diffuse + specular) * atten;
}
#endif

4
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineShadows.cginc


float4x4 _WorldToShadow[MAX_SHADOW_CASCADES];
float4 _DirShadowSplitSpheres[MAX_SHADOW_CASCADES];
half4 _ShadowData;
// In case of single directional light, shadow light dir is the same of light dir
#ifndef _SINGLE_DIRECTIONAL_LIGHT
#endif
inline half ShadowAttenuation(float3 shadowCoord)
{

正在加载...
取消
保存