版权声明:本文为博主原创文章,未经博主允许不得转载。 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/