unity 2d摄像机类型_Unity使用RenderTexture实现实时阴影绘制

博客介绍了在Unity中实现实时阴影的方式,包括脚底放阴影图片、用摄像机的RenderRexture绘制显示、使用Projector组件。重点讲解了在3D场景中用RenderTexture实现实时阴影绘制的方法,如多用一个摄像机将主角内容呈现到面片上,还提及了相关设置和脚本绑定,以及解决剑阴影显示问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

v2-85f8dac7bca6f5f929e8e2969e7de8a8_1440w.jpg?source=172ae18b

前言

一般实时阴影主要还在出现在角色、怪物的脚底为了然场景表现的更加逼真,实现起来主要会用到这三种方式:脚底放个阴影图片跟着主角动,通过摄像机的RenderRexture绘制显示,直接使用Unity的Projector组件。在2D场景中,为了方便,游戏中通常会直截了当的放一快灰色背景,实现的效果虽然少了几分逼真性,但也足够用。

但是如果想要在3D场景绘制脚底阴影,直接放阴影图就不合适了,为了让阴影效果更加逼真,下面就给大家介绍下使用RenderTexture的方式实现实时阴影绘制的效果吧。

基本思路其实就是多用了一个摄像机,将照相机把你需要照到的主角的内容呈现到一张单独的面片上,这个面片就摆在人较低作为它的阴影。看起来像简单版的一个小地图:只有主角的小地图。

场景中所需要的对象如图,对于map节点显示RenderTexteure的地方只要空的材质球就行了,要呈现摄像机照射的内容。直接用Plane对象或Quad对象都可以的。

v2-a8d319b812672a6a5b0793a4b1027604_b.jpg

此外,为了让阴影真实点,显示阴影的面片一般是灰色透明的,我们还要单独设置下,不然默认摄像机照出来的角色就是我们真实看到的世界:

v2-248a4e612de287b8580d02ef527b3c20_b.jpg

紧接着还需要一个脚本告诉摄像机把内容写到我们的map面片上。

在场景中的display节点身上绑定脚本ShadowScript:

public class ShadowScript : MonoBehaviour {
public GameObject display; //角色形象
private GameObject ShadowCamera;
private GameObject map;
private RenderTexture mTex = null; //即为显示阴影的RenderTexutre
public int AntiAliasing = 4;
Transform child;
// Use this for initialization
void Start () {
child = this.transform.FindChild(“qiangu1”);
map = child.FindChild(“child/map”).gameObject;
ShadowCamera = child.FindChild(“child/camera”).gameObject;
if (!display)
display = this.transform.parent.gameObject;
mTex = new RenderTexture(2000, 2000, 0);
mTex.name = “Shadow” + GetInstanceID();
Camera mCamera = ShadowCamera.GetComponent<Camera>();
mCamera.cullingMask = GetLayerMask(display.gameObject.layer);
mCamera.targetTexture = mTex;
}
public LayerMask GetLayerMask(int layer)
{
LayerMask mask = 0;
mask |= 1 << layer;
return mask;
}
// Update is called once per frame
void Update ()
{
if(display!=null)
{
mTex.anisoLevel = AntiAliasing;
}
map.renderer.maternTexture = mTex;
}
}

很简单吧?跑起来直接就可以看到实时的阴影效果了!

自己给小骨模型做了一个御剑的动画!然而一时找不到好看的剑模型,我只好找了张jpg的剑扣一个出来,也是大费周折,不过可以看出来阴影效果比较好,因为阴影作为一个独立的GameObject直接少了很多调层级的麻烦,现在是只显示主角阴影的效果。

v2-fc0ea5e502e178660d3fa4324b46509f_b.gif

但是当我把剑贴图所在的面片layer调整的也和主角模型一样的时候,发现居然还是看不到剑的阴影。

这个时候还对专门针对map(显示阴影的面片)材质写一个Shader,就不能用默认的Transparent/Diffuse了,并且最终剑这种透明贴图的还需要使用Unlit/Transparent,新添加的Shader详细代码如下:

///作为带Alpha通道的模型贴图的shader
Shader “MyShader/AlphaSkinShader”
{
Properties
{
_Color(“Main Color”,Color)=(1,1,1,1)
_MainTex (“Base (RGB)”, 2D) = “white” {}
_Cutoff(“Base Alpha cutoff”,Range(0,0.9))=0.2
}
SubShader
{
Tags { “Queue”=“Transparent” }
LOD 200
Lighting Off
ZWrite Off
Cull off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include “UnityCG.cginc”
struct appdata_t
{
float4 vertex:POSITION;
float4 color:COLOR;
float2 texcoord:TEXCOORD;
};
struct v2f
{
float4 vertex:SV_POSITION;
float4 color:COLOR;
float2 texcoord:TEXCOORD;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Cutoff;
v2f vert(appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP,v.vertex);
o.color=v.color;
o.texcoord=TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
float4 _Color;
half4 frag(v2f i):SV_Target
{
half4 col = tex2D(_MainTex,i.texcoord);
if(col.a<_Cutoff)
{
clip(col.a-_Cutoff);
}
else
{
col.rgb=col.rgb*float3(0,0,0);
col.rgb=col.rgb+_Color;
col.a=_Color.a;
}
return col;
}
ENDCG
}
}
FallBack “Diffuse”
}

修改之后靓丽的运行效果:

v2-399ceac9dc9b9b1489d62467171db78c_b.gif
### 实现2D阴影效果的方法 在Unity实现2D阴影效果可以通过多种方法达成,具体取决于所需的真实度以及性能考虑。对于较为简单的需求,在角色或对象下方放置静态的阴影图像并随其移动是一种快速简便的方式[^2]。 然而,如果追求更真实的光影互动,则需构建专门针对2D环境设计的光照系统。此过程涉及创建自定义着色器(shader),利用`RenderTexture`来捕捉场景中的遮挡信息,并将其应用于接收面以模拟阴影投射的效果[^1]。 #### 使用RenderTexture实现实时阴影绘制 一种常见做法是在光源位置设置专用摄像机用于渲染深度纹理(RenderTexture)。该摄像机视角应覆盖所有可能产生投影的对象及其对应的受光表面。接着,通过编写特定的Shader代码处理这些深度数据,从而计算出哪些区域应当被暗化表示处于阴影之中[^4]。 ```csharp // C# Script to setup RenderTexture and apply it as a shadow map. using UnityEngine; public class ShadowCaster : MonoBehaviour { public Camera depthCamera; private void Start() { // Ensure the camera is set up correctly for rendering shadows into texture depthCamera.targetTexture = new RenderTexture(512, 512, 0); GetComponent<Renderer>().material.SetTexture("_ShadowMap", depthCamera.targetTexture); } } ``` #### 自定义Shader编程 为了使上述方案生效,还需要准备相应的材质(Material)和着色器程序。这里展示了一个简化版的例子,其中包含了如何读取来自`RenderTexture`的信息并在最终颜色输出前调整亮度: ```hlsl Shader "Custom/2DShadow" { Properties { _MainTex ("Sprite Texture", 2D) = "white" {} _ShadowMap("Shadow Map (RGB)", 2D) = "black" {} } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag sampler2D _MainTex; float4 _MainTex_ST; struct appdata_t { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 pos : SV_POSITION; }; v2f vert(appdata_t IN) { v2f OUT; OUT.pos = UnityObjectToClipPos(IN.vertex); OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex); return OUT; } fixed4 frag(v2f i) : COLOR { fixed4 col = tex2D(_MainTex, i.uv); // Sample from shadow map here... return col * lerp(1.0, 0.5, step(tex2D(_ShadowMap,i.uv).r, 0.5)); } ENDCG } } } ``` 这段HLSL代码片段展示了如何基于传入的UV坐标采样主贴图(`_MainTex`)的同时也访问预先准备好的阴影映射(`_ShadowMap`),并通过比较操作决定像素是否位于阴影区内[^3][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值