Shader2D阴影

Posted stalendp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shader2D阴影相关的知识,希望对你有一定的参考价值。

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:

1)方法1

// refer to http://www.catalinzima.com/2010/07/my-technique-for-the-shader-based-dynamic-2d-shadows/
Shader "HeroShader/FogOfWar"

	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) * 0.65: 1;
		return float4(1, 1, 1, 1) * distance;
	

	float4 frag1_Distort (v2f i) : SV_Target 
		float2 uv0 = i.uv * 2 - 1;
		float2 uv1 = float2(i.uv.x, (abs(uv0.x) * uv0.y + 1) * 0.5);
		return float4(tex2D(_MainTex, uv1).r, tex2D(_MainTex, uv1.yx).r, 1, 1);
		
	
	float4 frag3_Show (v2f i) : SV_Target 
		float2 uv0 = i.uv * 2 - 1;
		float2 uv1 = abs(uv0);
		float rt = 0;
		if(uv1.x > uv1.y) 
			rt = tex2D(_MainTex, float2(i.uv.x, (uv0.y / uv1.x + 1) * 0.5)).r;
		 else 
			rt = tex2D(_MainTex, float2(i.uv.y, (uv0.x / uv1.y + 1) * 0.5)).g;
		
		return  step(length(uv0) * 0.65, rt);
	

	float4 frag2_MapReduce (v2f i) : SV_Target 
		float4 c1 = tex2D(_MainTex, float2(i.uv.x - _MainTex_TexelSize.x, i.uv.y));
		float4 c2 = tex2D(_MainTex, float2(i.uv.x, i.uv.y));
		return min(c1, c2);
	

	float4 frag4_Copy (v2f i) : SV_Target 
		return tex2D(_MainTex, i.uv);
	

	ENDCG

	SubShader 
		ZWrite off
	 	Fog  Mode off 
		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
		
	

2)方法2

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/

以上是关于Shader2D阴影的主要内容,如果未能解决你的问题,请参考以下文章

[Shader2D]马赛克

Unity Shader2D动态云彩

Shader2D: 一些2D效果的Shader实现

Shader2D: 一些2D效果的Shader实现

Shader2D: 一些2D效果的Shader实现

✠OpenGL-8-阴影