일단 결과물부터


* 찬조출연. 앵듀네 크리미 



일단 이걸 이해하려면 패럴렉스 셰이더부터 이해해야 하는데요

기본 공식은 이거고 

http://egloos.zum.com/chulin28ho/v/3749030

 

언리얼에서는 Bump offset이라는 노드로 존재하고 있습니다.
http://api.unrealengine.com/KOR/Engine/Rendering/Materials/HowTo/BumpOffset/


유니티의 엠플리파이트 셰이더에서는 

패럴렉스 옵셋 parallax offset 이라는 이름으로 존재하고 있고요 





캐네디언이 된 풍풍풍이의 글도 좋구요 

https://m.blog.naver.com/PostView.nhn?blogId=sorkelf&logNo=40125344612&proxyReferer=https%3A%2F%2Fwww.google.com%2F



알란 아저씨의 글도 좋습니다. 

https://www.alanzucconi.com/2019/01/01/parallax-shader/



우선 자료가 필요합니다. 

자료는 고양이 사진과 깊이 사진. 


깊이 사진은 제가 걍 그린 겁니다. 캬캬캬캬 

뎁스를 출력할 수 있는 카메라나 렌더러가 있다면 더 정확하겠지요. 뭐 이걸로도 충분. 



패럴렉스는 어차피 시차 보정. 즉 UV 눈속임이지 뭔가 대단한게 아닙니다. 공식도 쉽고 가벼운 편이예요 

효과도 좀 애매한 점이 없지 않고요 

너무 크면 티가 납니다. 요새 페이스북 3D 카메라인가 뭔가 있던데 그거랑 똑같아요 



핵심은 

float4 offsetTex = tex2D(_HeightTex, IN.uv_MainTex);

float2 offset = (IN.viewDir.xy / IN.viewDir.z) *(1-offsetTex.r) *_Depth;


이 두 줄입니다. 


기본 원리는 '기울였을때 UV를 내 방향으로 이동시킨다' 예요. 그러면 깊이가 있는 것처럼 느껴지거든요 


아래 그림 보세요. 

저게저게 깊이가 있는게 아니예요. 기울였을때 UV가 내 쪽으로 이동하는거 보이잖아요 

그래서 IN.viewDir.xy 입니다. [각주:1]




그래서 이렇게 이동한만큼의 위치를    fixed4 c = tex2D (_MainTex, IN.uv_MainTex- offset) * _Color;

로 UV에다가 이동시켜주면 됩니다 


풀코드입니다. 대단히 짧아요 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Shader "Custom/height"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Normal("Normal", 2D) = "bump" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _HeightTex("Height", 2D) = "white" {}
        _Depth("Depth",float)= 0.2
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
 
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows
 
        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0
 
        sampler2D _MainTex;
        sampler2D _HeightTex;
        sampler2D _Normal;
        half _Glossiness;
        half _Metallic;
        float _Depth;
        fixed4 _Color;
 
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_Normal;
            float3 viewDir;
        };
 
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            
            o.Normal = UnpackNormal(tex2D(_Normal, IN.uv_Normal));
            
            float4 offsetTex = tex2D(_HeightTex, IN.uv_MainTex);
            float2 offset = (IN.viewDir.xy / IN.viewDir.z) *(1-offsetTex.r) *_Depth;
            
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex- offset) * _Color;
 
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 
cs


  1. 이게 주의해야 할게, UnpackNormal로 노말맵을 받을때만 이렇게 되고, 이게 없으면 다른 축입니다. 노말맵이 있으면 서피스 부분이 탄젠트 좌표로 돌아가고 없으면 월드 좌표로 돌아가서 뷰 디렉션도 바뀝니다. -IN.viewDir.xy 로 해주세요 주의. [본문으로]

'Shader' 카테고리의 다른 글

Fake Interior Shader  (0) 2019.01.27
AABB(Axis Aligned Bounding Box) 방식의 레이 충돌공식  (0) 2019.01.24
고양이 입체 영상을 만들자! Parallax shader  (0) 2019.01.22
melting shader  (0) 2019.01.21
melt shader 기본형 만들기  (2) 2019.01.19
SSS Shader for Unity  (0) 2019.01.19