【Shader】2D陰影
阿新 • • 發佈:2018-11-19
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/