赞
踩
最开始想用镜子原理实现下图效果,不过显然没有如愿[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果-CSDN博客。不过稍微转变一下思路,在镜子的基础上,翻转相机镜头,就可以实现如下效果。
使用版本为:2021.3.6f1
[原始效果]
[投影效果]
更详细的实现逻辑及步骤参考CODE'n Random的视频:
How to make a Planar Reflection in Unity URP - Source Code Available - YouTube
目录
新建一个无光源的Unlit Shader Graph
声明一个Texture 2D,并连接至Base Color。因为这个效果的核心实现原理,就是通过相机映射Texture来完成的。
将Screen Position连接至UV,是为了接收屏幕坐标。注意两节点当中要加一个Tilling And Offet并将Y轴改为-1,这样才是倒影,不然就变成两辆车叠起来了。
选中Fragment将类型改为Transparent,新增一个Float(Alpha)并赋予Alpha。这个是用来控制镜面反射清晰度的(或者说是反射贴图的透明度)。
连连看的部分到这里就结束了,完整图如下SoEasy~
需要注意,这个材质球在赋值给Plane时,需要叠加在原材质上面,而非替换。
新建一个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,注意两个相机的位置已处于对称状态。
场景中新建一个虚拟相机和一个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);
- }
- }

最终效果如下图所示
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。