[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果
前言
最开始想用镜子原理实现下图效果,不过显然没有如愿[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果-CSDN博客。不过稍微转变一下思路,在镜子的基础上,翻转相机镜头,就可以实现如下效果。
使用版本为:2021.3.6f1
更详细的实现逻辑及步骤参考CODE'n Random的视频:
How to make a Planar Reflection in Unity URP - Source Code Available - YouTube
目录
前言
一、赋值贴图
二、Camera与Texture
三、Virtual Camera控制
一、赋值贴图
新建一个无光源的Unlit Shader Graph
声明一个Texture 2D,并连接至Base Color。因为这个效果的核心实现原理,就是通过相机映射Texture来完成的。
将Screen Position连接至UV,是为了接收屏幕坐标。注意两节点当中要加一个Tilling And Offet并将Y轴改为-1,这样才是倒影,不然就变成两辆车叠起来了。
选中Fragment将类型改为Transparent,新增一个Float(Alpha)并赋予Alpha。这个是用来控制镜面反射清晰度的(或者说是反射贴图的透明度)。
连连看的部分到这里就结束了,完整图如下SoEasy~
需要注意,这个材质球在赋值给Plane时,需要叠加在原材质上面,而非替换。
二、Camera与Texture
新建一个Render Texture并赋值给场景中作为镜子的Plane。
在Plane下面新建一个Camera
,并把刚刚新建的Render Texture赋值给Camera的Output Texture
。这边的逻辑与前言提到的镜子原理是一样的。
新建脚本用于控制相机位置,如下所示,保存后挂载给Plane。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Projection : MonoBehaviour
{
private Vector2 Resolution;
[SerializeField] private Camera ReflectionCamera;
[SerializeField] private RenderTexture ReflectionRenderTexture;
[SerializeField] private int ReflectionResloution;
private void LateUpdate()
{
ReflectionCamera.fieldOfView = Camera.main.fieldOfView;
ReflectionCamera.transform.position = new Vector3(Camera.main.transform.position.x, -Camera.main.transform.position.y + transform.position.y, Camera.main.transform.position.z);
ReflectionCamera.transform.rotation = Quaternion.Euler(-Camera.main.transform.eulerAngles.x, Camera.main.transform.eulerAngles.y, 0f);
Resolution = new Vector2(Camera.main.pixelWidth, Camera.main.pixelHeight);
ReflectionRenderTexture.Release();
}
}
Plane下的Canera赋值给ReflectionCamera,Render Texture赋值给Reflection RenderTexture。运行并移动Main Camera,注意两个相机的位置已处于对称状态。
三、Virtual Camera控制
场景中新建一个虚拟相机和一个GameObject空对象。
把GameObject赋值给虚拟相机的Follow,将Body设为3rd Person Follow,且数值全部归零。这个GameObject空对象即是用来观察投影的视角,CameraDistance是视角大小,随意便好。
为了更好的测试,可以给控制相机加上旋转代码,如下所示。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraLook : MonoBehaviour
{
private Vector2 CameraRotation;
[SerializeField] private float Sensitivity;
private void Awake()
{
CameraRotation = new Vector3(150, 10);
}
private void Update()
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
CameraRotation.x += Input.GetAxis("Mouse X") * Sensitivity;
CameraRotation.y -= Input.GetAxis("Mouse Y") * Sensitivity;
CameraRotation.y = Mathf.Clamp(CameraRotation.y, -60, 60);
transform.rotation = Quaternion.Euler(CameraRotation.y, CameraRotation.x,0);
}
}
最终效果如下图所示

![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/dd1819d466e040ea9c1ea7961308742f.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/fff5977d3c3a459b815cbc23e07eda42.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/4252320b38ce4f4e820d9ac095ce7505.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/27d616cc579e43e38ba350af6dc3cfee.gif)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/845cd293eee24e868f11ab380a8a8022.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/95a09ce336684fbfb772632541a39ce2.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/9192070f0f884dd1bb32ba6ad4d65f0d.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/edf92e24dfcb466d9466b34a7615da15.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/10d29da1ea0b485e858e48401170236c.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/08fec7745bb2483aa3f6ee7520ef6025.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/671db8345d5d47af9bb354282885d8b8.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/087985073b204481ab3575becf2ccc6d.gif)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/cfcda990330640978fe1dcff2817ac33.png)
![[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果](https://img-blog.csdnimg.cn/direct/7bd86e85fbb345098a7177e879eb1468.png)