[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果

前言

        最开始想用镜子原理实现下图效果,不过显然没有如愿[Unity] ShaderGraph实现完美倒影 or 平面镜反射效果-优快云博客。不过稍微转变一下思路,在镜子的基础上,翻转相机镜头,就可以实现如下效果。

使用版本为: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);
    }
}

         最终效果如下图所示

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超龄魔法少女

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值