所以我在着色器中渲染阴影贴图时遇到问题我对着色器编码很新(大约3个月),我会告诉你我正在做什么(我认为我在做什么)我在做。)
首先,创建一个复制阴影贴图的脚本( ShadowCopy.cs )然后将其传递给全局变量( _MyShadowMap )。现在是着色器( ShadowMapping.shader ),然后我创建 getShadowCoord 来计算shadowMap,然后将 getCascadeWeights()应用到阴影坐标(用于最佳原因)。
然后我创建 computeCameraSpacePosFromDepthAndInvProjMat(),它根据深度和反投影矩阵计算相机空间位置。现在是渲染像素的frag函数 使它在应用程序中可见,但整体上只是屏幕空间阴影。
所以我面临的问题是投影价值观,老实说,我不知道如何修复。您可以在图片中看到问题。 enter image description here
ShadowMapping.shader的材质设置。 enter image description here
ShadowCopy.cs
using UnityEngine;
using UnityEngine.Rendering;
public class ShadowCopy : MonoBehaviour
{
public Light m_Light;
RenderTexture m_ShadowmapCopy;
public int TextureSize = 512;
void Start()
{
RenderTargetIdentifier shadowmap = BuiltinRenderTextureType.CurrentActive;
m_ShadowmapCopy = new RenderTexture(TextureSize, TextureSize, 16, RenderTextureFormat.ARGB32);
m_ShadowmapCopy.filterMode = FilterMode.Point;
CommandBuffer cb = new CommandBuffer();
cb.SetShadowSamplingMode(shadowmap, ShadowSamplingMode.RawDepth);
cb.Blit(shadowmap, new RenderTargetIdentifier(m_ShadowmapCopy));
cb.SetGlobalTexture("_MyShadowMap", shadowmap);
m_Light.AddCommandBuffer(LightEvent.AfterShadowMap, cb);
}
void OnGUI()
{
if (m_ShadowmapCopy != null)
{
GUI.DrawTextureWithTexCoords(new Rect(0, 20, 150, 150), m_ShadowmapCopy, new Rect(0, 0, 1, 1), false);
}
}
ShadowMapping.shader
Shader "Custom/ShadowMapping" {
Properties {
_Color("Main Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGBA)", 2D) = "white" {}
}
SubShader {
Pass {
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
#include "AutoLight.cginc"
uniform float4 _Color;
uniform sampler2D _MyShadowMap;
//UNITY_DECLARE_SHADOWMAP(_MyShadowMap);
uniform sampler2D _MainTex;
float4 LowResDepth_TexelSize;
float4 _ShadowMapTexture_TexelSize;
#define SHADOWMAPSAMPLER_AND_TEXELSIZE_DEFINED
#define UNITY_USE_CASCADE_BLENDING 0
#define UNITY_CASCADE_BLEND_DISTANCE 0.1
struct appdata {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
#ifdef UNITY_STEREO_INSTANCING_ENABLED
float3 ray0 : TEXCOORD1;
float3 ray1 : TEXCOORD2;
#else
float3 ray : TEXCOORD1;
#endif
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 pos : SV_POSITION;
// xy uv / zw screenpos
float4 uv : TEXCOORD0;
// View space ray, for perspective case
float3 ray : TEXCOORD1;
// Orthographic view space positions (need xy as well for oblique matrices)
float3 orthoPosNear : TEXCOORD2;
float3 orthoPosFar : TEXCOORD3;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert (appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
float4 clipPos = UnityObjectToClipPos(v.vertex);
o.pos = clipPos;
o.uv.xy = v.texcoord;
o.uv.zw = ComputeNonStereoScreenPos(clipPos);
clipPos.y *= _ProjectionParams.x;
float3 orthoPosNear = mul(unity_CameraInvProjection, float4(clipPos.x,clipPos.y,-1,1)).xyz;
float3 orthoPosFar = mul(unity_CameraInvProjection, float4(clipPos.x,clipPos.y, 1,1)).xyz;
orthoPosNear.z *= -1;
orthoPosFar.z *= -1;
o.orthoPosNear = orthoPosNear;
o.orthoPosFar = orthoPosFar;
return o;
}
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
inline fixed4 getCascadeWeights(float3 wpos, float z)
{
fixed4 zNear = float4( z >= _LightSplitsNear );
fixed4 zFar = float4( z < _LightSplitsFar );
fixed4 weights = zNear * zFar;
return weights;
}
inline float4 getShadowCoord( float4 wpos, fixed4 cascadeWeights )
{
float3 sc0 = mul (unity_WorldToShadow[0], wpos).xyz;
float3 sc1 = mul (unity_WorldToShadow[1], wpos).xyz;
float3 sc2 = mul (unity_WorldToShadow[2], wpos).xyz;
float3 sc3 = mul (unity_WorldToShadow[3], wpos).xyz;
float4 shadowMapCoordinate = float4(sc0 * cascadeWeights[0] + sc1 * cascadeWeights[1] + sc2 * cascadeWeights[2] + sc3 * cascadeWeights[3], 1);
#if defined(UNITY_REVERSED_Z)
float noCascadeWeights = 1 - dot(cascadeWeights, float4(1, 1, 1, 1));
shadowMapCoordinate.z += noCascadeWeights;
#endif
return shadowMapCoordinate;
}
inline float3 computeCameraSpacePosFromDepthAndInvProjMat(v2f i)
{
float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
#if defined(UNITY_REVERSED_Z)
zdepth = 1 - zdepth;
#endif
float4 clipPos = float4(i.uv.zw, zdepth, 1.0);
clipPos.xyz = 2.0f * clipPos.xyz - 1.0f;
float4 camPos = mul(unity_CameraInvProjection, clipPos);
camPos.xyz /= camPos.w;
camPos.z *= -1;
return camPos.xyz;
}
half4 frag(v2f i) : COLOR
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
float3 vpos = computeCameraSpacePosFromDepthAndInvProjMat(i);
float4 wpos = mul (unity_CameraToWorld, float4(vpos,1));
fixed4 cascadeWeights = getCascadeWeights (wpos, vpos.z);
float4 shadowCoord = getShadowCoord(wpos, cascadeWeights);
float shadow = tex2D(_MyShadowMap, shadowCoord);
shadow = lerp(_LightShadowData.r, 1.0, shadow);
fixed4 res = shadow;
return shadow * tex2D(_MainTex, i.uv) * _Color;
}
ENDCG
}
}
}
答案 0 :(得分:0)
一些让我大吃一惊的东西:
更改:将
cb.SetGlobalTexture("_MyShadowMap", shadowmap);
更改为
cb.SetGlobalTexture("_MyShadowMap", m_ShadowmapCopy);
更改:将
uniform sampler2D _MyShadowMap;
更改为
UNITY_DECLARE_SHADOWMAP(_MyShadowMap);
将
float shadow = tex2D(_MyShadowMap, shadowCoord);
更改为
float shadow = UNITY_SAMPLE_SHADOW(_MyShadowMap, shadowCoord);