【Shader】2D阴影

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/stalendp/article/details/84243231

2D阴影

using UnityEngine;
public class Shadow2D : MonoBehaviour {
    public Material matShadow;
    public Texture texture;
    private RenderTexture targetRT;

    void Start() {
        targetRT = new RenderTexture(512, 512, 0);
        GetComponent<MeshRenderer>().materials[0].mainTexture = targetRT;
        doRender();
    }

    private void doRender() {
        RenderTexture tmp1 = RenderTexture.GetTemporary(512, 512);
        RenderTexture tmp2 = RenderTexture.GetTemporary(512, 512);
        Graphics.Blit(texture, tmp1, matShadow, 0);
        Graphics.Blit(tmp1, tmp2, matShadow, 1);
        RenderTexture.ReleaseTemporary(tmp1);

        var cur = tmp2;
        cur.filterMode = FilterMode.Point;
        int y = 512;
        while (y > 1) {
            y /= 2;
            var old = cur;
            cur = RenderTexture.GetTemporary(512, y, 0);
            cur.filterMode = FilterMode.Point;
            Graphics.Blit(old, cur, matShadow, 2);
            RenderTexture.ReleaseTemporary(old);
        }

        Graphics.Blit(cur, targetRT, matShadow, 3);
        RenderTexture.ReleaseTemporary(cur);
    }
}

相关shader:

Shader "Unlit/shadow" {
	Properties {
		_MainTex ("Texture", 2D) = "white" {}
	}

	CGINCLUDE
	#include "UnityCG.cginc"
	
	#define PI 3.14159265358979
	#define PI2 6.28318530717958
	#define NPI 0.318309886183791
	#define NPI2 0.1591549430918955

	sampler2D _MainTex;
	float4 _MainTex_ST;
	float4 _MainTex_TexelSize;
	
	struct appdata {
		float4 vertex : POSITION;
		float2 uv : TEXCOORD0;
	};

	struct v2f {
		float2 uv : TEXCOORD0;
		float4 vertex : SV_POSITION;
	};

	v2f vert (appdata v) {
		v2f o;
		o.vertex = UnityObjectToClipPos(v.vertex);
		o.uv = TRANSFORM_TEX(v.uv, _MainTex);
		return o;
	}

	float4 frag0_Depth (v2f i) : SV_Target {
		float4 col = tex2D(_MainTex, i.uv);
		float distance = col.r < 0.5 ? length(i.uv * 2 - 1) : 1;
		return fixed4(1, 1, 1, 1) * distance;
	}

	float4 frag1_Distort (v2f i) : SV_Target {
		float a = i.uv.x * PI2;
		float len = i.uv.y * 2;
		return tex2D(_MainTex, (float2(cos(a), sin(a)) * len + 1) * 0.5);
	}

	float4 frag2_MapReduce (v2f i) : SV_Target {
		float c1 = tex2D(_MainTex, float2(i.uv.x, i.uv.y - _MainTex_TexelSize.y)).r;
		float c2 = tex2D(_MainTex, float2(i.uv.x, i.uv.y)).r;
		float c3 = tex2D(_MainTex, float2(i.uv.x, i.uv.y + _MainTex_TexelSize.y)).r;
		return float4(1, 1, 1, 1) * min(min(c1, c2), c3);
	}

	fixed4 frag3_Show (v2f i) : SV_Target {
		float2 uv = (i.uv * 2 - 1);
		float a = fmod(atan2(uv.y, uv.x) * NPI + 2, 2) * 0.5;
		return float4(1, 1, 1, 1) * step(clamp(length(uv), 0, 1), tex2D(_MainTex, float2(a, 0.5)).r);
	}

	fixed4 frag4_Copy (v2f i) : SV_Target {
		return tex2D(_MainTex, i.uv);
	}

	ENDCG

	SubShader {
		ZTest Off Cull Off ZWrite Off Blend Off
	 	Fog { Mode off }
		Tags { "RenderType"="Opaque" }
		LOD 100

		// pass 0 depth
		Pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag0_Depth
			ENDCG
		}

		// pass 1 distort
		Pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag1_Distort
			ENDCG
		}

		// pass 2 map
		Pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag2_MapReduce
			ENDCG
		}

		// pass 3 show
		Pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag3_Show
			ENDCG
		}

		// pass 4 copy
		Pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag4_Copy
			ENDCG
		}
	}
}

参考:

https://github.com/mattdesl/lwjgl-basics/wiki/2D-Pixel-Perfect-Shadows
http://www.catalinzima.com/2010/07/my-technique-for-the-shader-based-dynamic-2d-shadows/

猜你喜欢

转载自blog.csdn.net/stalendp/article/details/84243231