阴影 - Projector实现

发布时间 2023-04-18 00:03:42作者: yanghui01

脚底一个黑色圈的那种阴影(Blob Shadow)

最终效果

 

1) 关掉Unity内置的阴影投射,将Layer设为Player

 

2) Projector设置

 3) 

 

挂在Player上的移动控制脚本

using UnityEngine;

public class PlayerMove : MonoBehaviour
{
    private Rigidbody m_Rigidbody;
    private Vector3 m_MoveDir;
    private float m_JumpSpeed;

    void Start()
    {
        m_Rigidbody = GetComponent<Rigidbody>();
    }

    void Update()
    {
        var h = Input.GetAxis("Horizontal");
        var v = Input.GetAxis("Vertical");

        m_MoveDir = transform.forward * h;
        m_MoveDir += transform.right * -v;
        m_MoveDir.Normalize();
        m_MoveDir *= 5;
        m_MoveDir.y = 0;

        if (Input.GetKeyDown(KeyCode.Space))
        {
            //Debug.Log($"{m_Rigidbody.velocity.y}");
            if (Mathf.Abs(m_Rigidbody.velocity.y) <= 0.01f)
            {
                m_JumpSpeed = 6;
            }
        }
    }

    void FixedUpdate()
    {
        m_Rigidbody.velocity = new Vector3(m_MoveDir.x, m_Rigidbody.velocity.y, m_MoveDir.z) + Vector3.up * m_JumpSpeed;
        m_JumpSpeed = 0;
    }
}

 

匹配角色外形的阴影

最终效果

 

可以看到在最后的时候,阴影还是有点问题的,这个地方不应该出现阴影的,但是因为Projector与这个物体相交了,就产生了阴影。

不过这边我们先不管,目测应该也需要去用到深度啥的来解决。

 

 

原理:

第1个方案是,手动指定一张做好的图片作为投影器贴图。这边使用Camera实时拍一张贴图,作为投影器的贴图。

 

生成阴影贴图的脚本

using UnityEngine;


[RequireComponent(typeof(Camera))]
public class ProjectorUseCameraTargetTexture : MonoBehaviour
{
    public Projector m_Projector;
    private Camera m_Camera;

    void Start()
    {
        m_Camera = GetComponent<Camera>();
        m_Camera.orthographic = m_Projector.orthographic;
        m_Camera.orthographicSize = m_Projector.orthographicSize;
        m_Camera.nearClipPlane = m_Projector.nearClipPlane;
        m_Camera.farClipPlane = m_Projector.farClipPlane;
        m_Camera.cullingMask = m_Projector.ignoreLayers;
        m_Camera.clearFlags = CameraClearFlags.SolidColor;
        m_Camera.backgroundColor = new Color(1.0f, 1.0f, 1.0f, 0.0f); //透明白

        m_Camera.SetReplacementShader(Shader.Find("Projector/Multiply"), null); //camera下的所有物体都用这个shader绘制
        m_Projector.material.SetTexture("_ShadowTex", m_Camera.targetTexture);
    }

    private void OnApplicationQuit()
    {
        m_Projector.material.SetTexture("_ShadowTex", null);
    }

}

 

shader再贴一遍

Shader "Projector/Multiply" {
    Properties {
        _ShadowTex ("Cookie", 2D) = "gray" {}
        _FalloffTex ("FallOff", 2D) = "white" {}
    }
    Subshader {
        Tags {"Queue"="Transparent"}
        Pass {
            ZWrite Off
            ColorMask RGB
            Blend DstColor Zero
            Offset -1, -1

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog
            #include "UnityCG.cginc"
            
            struct v2f {
                float4 uvShadow : TEXCOORD0;
                float4 uvFalloff : TEXCOORD1;
                UNITY_FOG_COORDS(2)
                float4 pos : SV_POSITION;
            };
            
            float4x4 unity_Projector;
            float4x4 unity_ProjectorClip;
            
            v2f vert (float4 vertex : POSITION)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(vertex);
                o.uvShadow = mul (unity_Projector, vertex);
                o.uvFalloff = mul (unity_ProjectorClip, vertex);
                UNITY_TRANSFER_FOG(o,o.pos);
                return o;
            }
            
            sampler2D _ShadowTex;
            sampler2D _FalloffTex;
            
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
                texS.a = 1.0-texS.a;

                fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
                fixed4 res = lerp(fixed4(1,1,1,0), texS, texF.a);

                UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(1,1,1,1));
                return res;
            }
            ENDCG
        }
    }
}

 

参考

利用Projector实现伪动态阴影 (yrsc.github.io)

Unity的投影阴影 - 知乎 (zhihu.com)

 

Unity 2017 Tutorial - Blob Shadow Projector - Fake Shadow (lmhpoly.com)

Character Pack: Free Sample | 3D 人形角色 | Unity Asset Store

Unity 2017 Tutorial - Blob Shadow Projector - Fake Shadow_哔哩哔哩_bilibili

Unity 5 使用Projector实现纹理投射_blobshadow_v2_1_YiColin的博客-CSDN博客

Unity Shader之投影_unity 投影shader_冰河烈风的博客-CSDN博客

Unity3D中使用Projector生成阴影 (shuzhiduo.com)

Unity3D中Projector怎么用 - 大数据 - 亿速云 (yisu.com)