유니티/URP-Shader

유니티 URP - Plane Reflection

민또배기 2022. 4. 19. 16:20
반응형

유니티 버전 : 2020.3.25f1(URP)

작업환경 : Mac (Monterey 12.3.1)

 

반사효과를 내고 싶어서 Metalic으로 값을 주니 빛만 반사되더라구요?

오브젝트를 반사되게 하고 싶었는데... 유니티에서 그런 기능을 만들어줘야 하더군요

 

원리는 이러합니다.

메인 카메라(Main Cam)와 메인 카메라를 기준으로 -Y 축으로 이동시킨 카메라(Reflect Cam)를 추가합니다. 이렇게 두대를 이용하여 동작시킵니다.

Reflect Cam은 Main Cam을 기준으로 z축 180회전 y축 기준 Flip시키면 됩니다.

 

일단 Shader Node를 이용해서 reflection기능을 작성합니다.

생성은 Create → Shader → Universal Render PipeLine → Lit Shader Graph 로 합니다.

Shader Node

Properties는 다음과 같이 추가합니다. 

 

이제 이 값을 이용해서 동작 시켜주는 스크립트를 작성합니다.

 

PlaneReflection.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteAlways]
public class PlaneReflection : MonoBehaviour
{
    public Camera mainCamera;
    public Camera reflectionCamera;
    public Transform reflectionPlane;
    public RenderTexture outputTexture;

    public bool copyCameraParameter;
    public float verticalOffset;
    bool isReady;

    Transform mainCamTransform;
    Transform reflectionCamTransform;

    
    // Update is called once per frame
    void FixedUpdate()
    {
        if (isReady) RenderReflection();
    }

    void RenderReflection()
    {
        Vector3 camDirectionWorldSpace = mainCamTransform.forward;
        Vector3 camUpWorldSpace = mainCamTransform.up;
        Vector3 camPositionWorldSpace = mainCamTransform.position;

        camPositionWorldSpace.y += verticalOffset;

        Vector3 camDirectionPlaneSpace = reflectionPlane.InverseTransformDirection(camDirectionWorldSpace);
        Vector3 camUpPlaneSpace = reflectionPlane.InverseTransformDirection(camUpWorldSpace);
        Vector3 camPositinoPlaneSpace = reflectionPlane.InverseTransformPoint(camPositionWorldSpace);

        camDirectionPlaneSpace.y *= -1;
        camUpPlaneSpace.y *= -1;
        camPositinoPlaneSpace.y *= -1;

        camDirectionWorldSpace = reflectionPlane.TransformDirection(camDirectionPlaneSpace);
        camUpWorldSpace = reflectionPlane.TransformDirection(camUpPlaneSpace);
        camPositionWorldSpace = reflectionPlane.TransformPoint(camPositinoPlaneSpace);

        reflectionCamTransform.position = camPositionWorldSpace;
        reflectionCamTransform.LookAt(camPositionWorldSpace + camDirectionWorldSpace, camUpWorldSpace);
    }

    private void OnValidate()
    {
        if (mainCamera != null)
        {
            mainCamTransform = mainCamera.transform;
            isReady = true;
        }
        else isReady = false;

        if (reflectionCamera != null)
        {
            reflectionCamTransform = reflectionCamera.transform;
            isReady = true;
        }
        else isReady = false;

        if(isReady && copyCameraParameter)
        {
            copyCameraParameter = !copyCameraParameter;
            reflectionCamera.CopyFrom(mainCamera);
            reflectionCamera.targetTexture = outputTexture;
        }
    }
}

 

결과물

Reflection-URP.unitypackage
5.78MB

반응형

'유니티 > URP-Shader' 카테고리의 다른 글

Unity(URP) UV_Scroll Shader  (0) 2022.05.16
유니티+블렌더 크리스탈 만들기  (0) 2022.05.03
유니티 URP OutLine Shader Graph  (0) 2022.04.15