无法将ShadowMap投影到曲面

时间:2018-04-15 17:13:10

标签: c# unity3d graphics hlsl cg

所以我在着色器中渲染阴影贴图时遇到问题我对着色器编码很新(大约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
  }

 }

}

1 个答案:

答案 0 :(得分:0)

一些让我大吃一惊的东西:

  1. 更改:将
    cb.SetGlobalTexture("_MyShadowMap", shadowmap);更改为
    cb.SetGlobalTexture("_MyShadowMap", m_ShadowmapCopy);

  2. 更改:将
    uniform sampler2D _MyShadowMap;更改为
    UNITY_DECLARE_SHADOWMAP(_MyShadowMap);


  3. float shadow = tex2D(_MyShadowMap, shadowCoord);更改为
    float shadow = UNITY_SAMPLE_SHADOW(_MyShadowMap, shadowCoord);