블로그 주인장에게 커피값을 후원할 수 있습니다!
가짜로 실내를 만들때 쓰는 셰이더.
언리얼에서는 로보리콜에서 예제를 볼 수 있고,
스파이더맨 PS4 게임에서도 볼 수 있는 건물 표현 방식입니다. 그 외에도 오버워치라던가 여러 군데에서 씀.
실내에 직접 모델링을 할 수도 있지만 아무래도 그게 좀 많아지면 이게 훨씬 더 가벼운 방법
참고할 수 있는 부분은
심시티나 스파이더맨에서도 사용함
http://www.andrewwillmott.com/talks/from-aaa-to-indie
유니티 포럼에서 이 내용에 대해 토의
https://forum.unity.com/threads/interior-mapping.424676/#post-2751518
알란주코니의 모음
https://www.alanzucconi.com/2018/09/10/shader-showcase-9/
등이 되겠습니다.
핵심적인 내용은 이전 게시물인 AABB 레이 충돌공식에서 썼으므로 (Thanks to @Hybrid) 여기에는 코드만.
큐브맵을 이용해야 합니다
큐브맵은 6 direction 쪽이 좋아요
주의사항은 normal을 직접 탄젠트 좌표로 입력하거나 텍스쳐를 받아야 한다는 것.
안 그렇게 하면 서피스 셰이더 코드 내의 연산이 월드 좌표계로 연산되기 때문입니다.
굳이 o.Normal로 구현시켜 줘야 탄젠트 좌표계로 움직어요.
현재 위의 그림에서 벽은 구현만 해놓고 켜놓질 않았습니다만,
1
2
3
4
5
|
o.Normal = float3(0, 0, 1); //using normal for tangent calculation
o.Albedo = tex.rgb;
o.Smoothness = 1 - tex.a ;
o.Emission = room.rgb * (1- tex.a);
o.Alpha = 1;
|
cs |
이렇게도 됩니다.
풀 코드는 다음과 같습니다.
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
Shader "FakeInterior"
{
Properties
{
[NoScaleOffset]_MainTex("MainTex",2D) = "white"{}
_Color ("Color", Color) = (1,1,1,1)
_RoomCube("Albedo (RGB)",CUBE) = "" {}
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
sampler2D _MainTex;
samplerCUBE _RoomCube;
float4 _RoomCube_ST;
fixed4 _Color;
struct Input
{
float2 uv_MainTex;
float3 viewDir;
INTERNAL_DATA
};
// psuedo random
float2 rand2(float co) {
return frac(sin(co * float2(12.9898, 78.233)) * 43758.5453);
}
void surf(Input IN, inout SurfaceOutputStandard o)
{
//room UV and index UV
float2 roomUV = frac(IN.uv_MainTex*_RoomCube_ST.xy );
float2 roomIndexUV = floor(IN.uv_MainTex*_RoomCube_ST.xy )+1;
// randomize the room
float2 n = (rand2(roomIndexUV.x + roomIndexUV.y * (roomIndexUV.x + 1)) * _RoomCube_ST.xy);
roomIndexUV += n;
roomIndexUV = frac(roomIndexUV) ;
//raytrance box from tangent view dir . aabb
float3 viewD = normalize(-IN.viewDir);
float3 pos = float3(roomUV * 2.0 - 1.0, 1.1 - roomIndexUV.x );
float3 id = 1.0 / (viewD+0.00001);
float3 k = abs(id) - pos * id;
float kMin = min(min(k.x, k.y),k.z);
pos += kMin * viewD;
//Random Room Left and Right riversal
pos.x = roomIndexUV > 0.5 ? pos.x : -pos.x;
//room Tex
fixed4 room = texCUBE(_RoomCube, pos.xyz);
//room random color
room.rgb *= clamp(roomIndexUV.yyx, 0.2, 1);
//window and outwall texture
float4 tex = tex2D(_MainTex, roomUV);
o.Normal = float3(0, 0, 1); //using normal for tangent calculation
o.Albedo = tex.rgb;
o.Smoothness = 1 - tex.a ;
o.Emission = room.rgb * (1- tex.a);
o.Alpha = 1;
}
ENDCG
}
FallBack "Diffuse"
}
|
cs |
'Shader ' 카테고리의 다른 글
Camera Depth Texture : 카메라 뎁스 텍스쳐 (4) | 2019.02.01 |
---|---|
셰이더로 동그라미 그리기 (0) | 2019.01.28 |
AABB(Axis Aligned Bounding Box) 방식의 레이 충돌공식 (0) | 2019.01.24 |
고양이 입체 영상을 만들자! Parallax shader (0) | 2019.01.22 |
melting shader (0) | 2019.01.21 |
댓글