- Home /
Question by
wechat_os_Qy08vhbrHS3TecmItsTAfOPh0 · Sep 21, 2019 at 07:51 AM ·
shadowspipeline
SRP Shadow error
Hello,I am working on SRP Pipeline and when I try to add shadow for spotlight,unity editor complained about 'light index must be a valid shadow casting light'. There is only one spotlight in my scene and I try hard to find where the problem is but failed.I am working on unity 2018.3.And following is my code Pipeline
private void RenderShadow(ScriptableRenderContext context,int size)
{
ShadowMap = RenderTexture.GetTemporary(size, size, 16, RenderTextureFormat.Shadowmap);
ShadowMap.filterMode = FilterMode.Bilinear;
ShadowMap.wrapMode = TextureWrapMode.Clamp;
//Bounds bound;
CoreUtils.SetRenderTarget(ShadowBuffer,ShadowMap,
RenderBufferLoadAction.DontCare,RenderBufferStoreAction.Store,ClearFlag.Depth);
//context.ExecuteCommandBuffer(ShadowBuffer);
//ShadowBuffer.Clear();
Matrix4x4 viewMatrix, proMatrix;
ShadowSplitData spd;
cullResult.ComputeSpotShadowMatricesAndCullingPrimitives(0, out viewMatrix, out proMatrix, out spd);
ShadowBuffer.SetViewProjectionMatrices(viewMatrix, proMatrix);
CoreUtils.SetKeyword(ShadowBuffer, shadowSoftKey, cullResult.visibleLights[0].light.shadows == LightShadows.Soft);
ShadowBuffer.SetGlobalFloat(shadowBiasID, cullResult.visibleLights[0].light.shadowBias);
ShadowBuffer.SetGlobalFloat(shadowStrangthID, cullResult.visibleLights[0].light.shadowStrength);
if (SystemInfo.usesReversedZBuffer)
{
proMatrix.m20 = -proMatrix.m20;
proMatrix.m21 = -proMatrix.m21;
proMatrix.m22 = -proMatrix.m22;
proMatrix.m23 = -proMatrix.m23;
}
var scaleOffset = Matrix4x4.identity;
scaleOffset.m00 = scaleOffset.m11 = scaleOffset.m22 = 0.5f;
scaleOffset.m03 = scaleOffset.m13 = scaleOffset.m23 = 0.5f;
Matrix4x4 WorldShadowM = scaleOffset * (viewMatrix * proMatrix);
ShadowBuffer.SetGlobalMatrix(WorldToShadowMapMatrixID, WorldShadowM);
ShadowBuffer.SetGlobalTexture(ShadowMapID, ShadowMap);
float invShadowMapSize = 1f / size;
ShadowBuffer.SetGlobalVector(shadowMapSizeID, new Vector4(invShadowMapSize, invShadowMapSize, size, size));
context.ExecuteCommandBuffer(ShadowBuffer);
ShadowBuffer.Clear();
DrawShadowsSettings shadowSetting = new DrawShadowsSettings(cullResult, 0);
context.DrawShadows(ref shadowSetting);
//
//cullResult.GetShadowCasterBounds(0,out bound);
//
context.ExecuteCommandBuffer(ShadowBuffer);
ShadowBuffer.Clear();
}`
And light
private void ConfigureLight()
{
int count = Mathf.Min(cullResult.visibleLights.Count, LightNum);
//for (;i< cullResult.visibleLights.Count; i++)
for (int i = 0 ; i < count; i++)
{
Vector4 attenuation = Vector4.zero;
attenuation.w = 1.0f;
Vector4 shadow = Vector4.zero;
VisibleLight light = cullResult.visibleLights[i];
LightColor[i] = light.finalColor;
if (light.lightType == LightType.Directional)
{
Vector4 v = light.localToWorld.GetColumn(2);
v.x = -v.x;
v.y = -v.y;
v.z = -v.z;
LightDirection[i] = v;
}
if (light.lightType == LightType.Point)
{
LightDirection[i] = light.localToWorld.GetColumn(3);
attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);
}
if (light.lightType == LightType.Spot)
{
Light shadowlight = light.light;
Bounds shadowBound;
if(shadowlight.shadows!=LightShadows.None&&cullResult.GetShadowCasterBounds(i,out shadowBound))
{
shadow.x = shadowlight.shadowStrength;
shadow.y = shadowlight.shadows == LightShadows.Soft ? 1f : 0f;
}
LightDirection[i] = light.localToWorld.GetColumn(3);
attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);
Vector4 v = light.localToWorld.GetColumn(2);
v.x = -v.x;
v.y = -v.y;
v.z = -v.z;
SpotDirection[i] = v;
float outerRad = Mathf.Deg2Rad * 0.5f * light.spotAngle;
float outerCos = Mathf.Cos(outerRad);
float outerTan = Mathf.Tan(outerRad);
float innerCos =
Mathf.Cos(Mathf.Atan(((46f / 64f) * outerTan)));
float angleRange = Mathf.Max(innerCos - outerCos, 0.001f);
attenuation.z = 1f / angleRange;
attenuation.w = -outerCos * attenuation.z;
}
LightRangeAtten[i] = attenuation;
ShadowData[i] = shadow;
}
}
And my shader
#ifndef NRP_UNLIT_INCLUDED
#define NRP_UNLIT_INCLUDED
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Shadow/ShadowSamplingTent.hlsl"
//#include "CoreRP/ShaderLibrary/UnityInstancing.hlsl"
struct appdata {
float4 vertex: POSITION;
float3 normal:NORMAL;
};
struct v2f {
float4 clipPos: SV_POSITION;
float3 normal:TEXCOORD0;
float3 worldPos:TEXCOORD1;
//float2 uv:TEXCOORD1;
};
cbuffer UnityPerFrame
{
float4x4 unity_MatrixVP;
};
cbuffer UnityPerDraw
{
float4x4 unity_ObjectToWorld;
float4 unity_LightIndicesOffsetAndCount;
float4 unity_4LightIndices0, unity_4LightIndices1;
};
#define Light_Num 4
cbuffer UnityLightBuffer
{
float4 lightColor[Light_Num];
float4 lightDir[Light_Num];
float4 lightRange[Light_Num];
float4 SpotlightDir[Light_Num];
};
cbuffer ShadowPerDraw
{
float4x4 WorldToShadowMapMatrix;
float shadowStrangth;
float4 _shadowMapSize;
};
TEXTURE2D_SHADOW(ShadowMap);
SAMPLER_CMP(sampler_ShadowMap);
float ShadowAttenuation(float3 worldPos){
float4 shadowPos = mul(WorldToShadowMapMatrix,float4(worldPos,1.0));
shadowPos.xyz /= shadowPos.w;
float ShadowAttenuation= SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowPos.xyz);
#if defined(_SHADOWS_SOFT)
real tentWeight[9];
real2 tentUV[9];
SampleShadow_ComputeSamples_Tent_5x5(_shadowMapSize, shadowPos.xy, tentWeight, tentUV);
ShadowAttenuation = 0;
for (int i = 0; i < 9; i++)
{
ShadowAttenuation += tentWeight[i] * SAMPLE_TEXTURE2D_SHADOW
(ShadowMap, sampler_ShadowMap, float3(tentUV[i].xy, shadowPos.z));
}
#endif
return lerp(1, ShadowAttenuation, shadowStrangth);
}
float3 DiffuseLight(int i, float3 WorldNormal, float3 WorldPos,float ShadowAttenuation)
{
float3 LightColor = lightColor[i].rgb;
float4 atten = lightRange[i];
float3 lightVec= lightDir[i].xyz- WorldPos* lightDir[i].w;
float3 LDir = normalize(lightVec);
float3 SpotDirection = SpotlightDir[i].xyz;
float d = max(dot(lightVec, lightVec), 0.00001);
float3 diffuse= saturate(dot(WorldNormal, LDir));
float rangeFade = dot(lightVec,lightVec)*atten.x;
rangeFade = saturate(1.0 - rangeFade * rangeFade);
rangeFade *= rangeFade;
float spotFade = dot(SpotDirection, LDir);
spotFade = saturate(spotFade*atten.z + atten.w);
spotFade *= spotFade;
diffuse *= ShadowAttenuation * spotFade * rangeFade / d;
//diffuse *= spotFade * rangeFade / d;
//diffuse *= rangeFade / d;
return diffuse* LightColor;
//return diffuse * lightColor[i].rgb;
}
v2f vert(appdata i) {
v2f o;
//UNITY_SETUP_INSTANCE_ID(i);
float4 worldPos = mul(unity_ObjectToWorld, float4(i.vertex.xyz, 1));
o.normal = normalize(mul((float3x3)unity_ObjectToWorld, i.normal));
o.clipPos = mul(unity_MatrixVP, worldPos);
o.worldPos = worldPos.xyz;
return o;
}
float4 frag(v2f i) : SV_TARGET{
float3 diffuse = 0;
for (int j = 0; j < unity_LightIndicesOffsetAndCount.y; j++)
{
int LightIndex = unity_4LightIndices0[j];
float sAttenuation = ShadowAttenuation(i.worldPos);
//float sAttenuation = 1;
diffuse += DiffuseLight(LightIndex, i.normal,i.worldPos, sAttenuation);
}
return float4(diffuse, 1);
}
#endif // NRP_UNLIT_INCLUDED
Comment
Your answer
![](https://koobas.hobune.stream/wayback/20220612212435im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
PBR Custom Shader produces no shadow 0 Answers
HDRP Point Light shadows issue 0 Answers
HD Renderer Pipeline not casting Shadows 1 Answer
Can particles cast shadows in Universal Render Pipeline? 0 Answers