본문 바로가기
Shader

유니티 셰이더 그래프(Unity shadergraph) 확장된 커스텀 라이트와 그 문제점

by 대마왕J 2020. 1. 14.

역시 여기 

https://blogs.unity3d.com/kr/2019/07/31/custom-lighting-in-shader-graph-expanding-your-graphs-in-2019/

 

내용 기반입니다. 

이 앞글과도 연결되어 있고요. 

 

이번에는 커스텀 라이트 확장에 대해 알아보겠습니다. 

이전에 만든 커스텀 라이팅은 ... 

 

디렉션하고 칼라밖에 나오지 않았죠. 

이걸로 만들면 문제가... 

그림자를 받지 못한다는 것입니다. (그림자를 드리우는건 되죠. 아래 그림 참조. 선택된 공에 그림자가 드리워지지 않는걸 보세요) 

 

 

그럴때 보통 필요한 것이 '감쇄' (Attenuation) 인데요. 

이걸 받으려면 코드를 좀 확장해야 합니다. 

 

위에 말했던 

https://blogs.unity3d.com/kr/2019/07/31/custom-lighting-in-shader-graph-expanding-your-graphs-in-2019/

 

링크에 있는대로 해 보면, 

void MainLight_float(float3 WorldPos, out float3 Direction, out float3 Color, out float DistanceAtten, out float ShadowAtten)
{
#if SHADERGRAPH_PREVIEW
    Direction = float3(0.5, 0, 0);
    Color = 1;
    DistanceAtten = 1;
    ShadowAtten = 1;
#else
#if SHADOWS_SCREEN
    float4 clipPos = TransformWorldToHClip(WorldPos);
    float4 shadowCoord = ComputeScreenPos(clipPos);
#else
    float4 shadowCoord = TransformWorldToShadowCoord(WorldPos);
#endif
    Light mainLight = GetMainLight(shadowCoord);
    Direction = mainLight.direction;
    Color = mainLight.color;
    DistanceAtten = mainLight.distanceAttenuation;
    ShadowAtten = mainLight.shadowAttenuation;
#endif
}

void MainLight_half(float3 WorldPos, out half3 Direction, out half3 Color, out half DistanceAtten, out half ShadowAtten)
{
#if SHADERGRAPH_PREVIEW
    Direction = half3(0.5, 0, 0);
    Color = 1;
    DistanceAtten = 1;
    ShadowAtten = 1;
#else
#if SHADOWS_SCREEN
    half4 clipPos = TransformWorldToHClip(WorldPos);
    half4 shadowCoord = ComputeScreenPos(clipPos);
#else
    half4 shadowCoord = TransformWorldToShadowCoord(WorldPos);
#endif
    Light mainLight = GetMainLight(shadowCoord);
    Direction = mainLight.direction;
    Color = mainLight.color;
    DistanceAtten = mainLight.distanceAttenuation;
    ShadowAtten = mainLight.shadowAttenuation;
#endif
}

 

 

 

 

 

위 코드로 셰도우 연산을 걸어서 넣어주네요. 

DistanceAtten 과 ShadowAtten이 있네요 

 

DistanceAtten은 일반적으로 포인트 라이트에서 거리에 따라 어두워지는 기능인 것으로 예상되고 (...어.. 메인패스는 디렉셔널만 받지 않아..?) 

ShadowAtten 은 자기 자신이 그림자에 드리워지는 기능을 의미합니다. 

 

왜 아냐면 유니티는 옛날부터 그래왔으니까요 ( ...)

그래서 만들어 봤습니다 두둥

 

 

 

 

좀 복잡해졌죠. 함수 입력이 World Position 이 들어가고 출력은 4개가 들어가니까요. 코드 참조. 

 

 

 

뭐 그래서 잘 됐습니다. 이전에 만든 , 확장 하기 전 코드까지는 구현되었네요 

 

이제 Atten을 구현해 보면..

 

안      됨 

 

 

 

 

 

뭐야 안되잖아?

 

 

아니 .. 생각해 보면 언릿쪽에서는 원래 셰도우 패스 연산이 빠져있는 쪽이라서 음 뭐 그럴 듯 해라고 이해는 됩니다. 

언릿이 그런게 다 빠져있어서 가벼우니까 언릿이지. 

 

근데 커스텀을 만들어 놨으면 뭔가 작동하니까 만들어 놓은 거 아니겠냔 말이죠. 

언릿 코드 보면 캐스팅 셰도우 기능은 있던데 

 

뭐지 뭐지 뭐지

 

저게 값이 안들어오는건가 아니면 들어오는데 그냥 리시브 셰도우 패스가 없는건가?

 

그래서 언릿패스 말고 릿 패스로 테스트 

 

 

 

그러니까 됨 

 

 

 

 

 

 

 

 

야잌ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

 

PBR 연산에서 걍 알베도를 검게 막아 버리고 Emission 만으로 처리해 버리는 꼼수로 하면 된다니

이걸 보니까 '값은 들어오는데 언릿에서는 셰도우 패스가 없어서 처리를 안함' 이라는 말이잖아요 이거 ㅋㅋㅋㅋㅋ

선 끊어 보니까 맞음 ㅋㅋㅋㅋ

 

 

즉 저 커스텀 라이팅 확장코드는, 언릿이랑 연결하라고 만들어 놓은 놈이 아님.

저건 새로운 마스터 - 언릿인데 셰도우 패스가 제대로 구현된 - 가 있어야 쓸모가 있어 보입니다. 

 

 

 

ps. 게다가 저거 Distance Atten 도, 거리 연산이 필요한 포인트 라이트나 스팟 라이트 같은거에는 언릿에서는 작동도 안됨 ㅋㅋㅋ

아니 아예 URP의 메인 패스에서는 디렉셔널 라이트 연산밖에 안돼요. Additional Pass 에서 됨 ㅋㅋㅋㅋ

왜 만들어 둔거야 진짜 ㅋㅋㅋㅋ

 

 

 

 

나 혼자 이렇게 괴로워하고 있나 싶어서 구글링을 해봤더니 (외롭잖아) 

https://forum.unity.com/threads/shadow-and-distance-attenuation-do-not-work-in-urp-unlit-graph.803025/

똑같은 주제로 괴로워 하고 있는 분들을 발견했습니다 ㅋㅋㅋ

특히 마지막 글이 너무 사이다얔ㅋㅋㅋㅋㅋ

변칙적으로 릿 패스에 연결하면 작동된다는 말을 듣고 쓰신 

 

That is exactly what I'm doing and what I want to avoid. This is terrible hackish. No way this must be the designed way to do it in a "professional" engine.

 

그게 제가 하고 있는 일이며 피하고 싶은 일입니다. 이것은 끔찍한 해킹같은 겁니다. 이것이 "프로페셔널" 엔진에서 설계된 방식이 되어서는 안됩니다.

 

 

 

 

반응형

댓글