일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 메모리 누수
- 프로그래밍 기초
- Rim Light
- VR
- Windows Build
- OculusMotionVectorPass
- Three(Two) Tone Shading
- AppSW
- C언어
- Cartoon Rendering
- Private Bytes
- 개인 바이트
- 게임 수학
- Toon Shader
- 가상 바이트
- ColorGradingLutPass
- Specular
- Virtual Byte
- 작업 집합
- ASW(Application SpaceWarp)
- URP
- URP로 변경
- working set
- 3d
- 벡터
- Cell Shader
- Cell Look
- Today
- Total
WinCNT
Fog가 적용되는 Skybox의 셰이더 만들어보자! 본문
서론
배경 아티스트 분께서 Skybox에 Fog를 표현하고 싶다고 요청한 적이 있다
배경 오브젝트에는 Fog가 걸리지만 그 뒤의 Skybox에는 Fog가 생기지 않아서 위화감이 생긴다는 이유였다
당시의 필자는 Fog를 그 존재밖에 몰라서 대충 왜 그런지에 대해서 뇌피셜로 얘기하며 대응되는 셰이더를 만들겠다는 말을 남기고 호다닥 그 자리에서 도망쳤었다
다행히 뇌피셜로 떠든 게 대부분 사실이었다
우선은 Fog가 어떻게 적용되는지 알아보자
Default의 스카이박스는 물론이고 내장된 다른 Skybox 셰이더도 유니티에서 바로 볼 순 없다
그렇다고 아예 방법이 없는 것은 아니지!
예전에도 한 번 작성한 적이 있지만 유니티의 빌트인 셰이더는 위의 사이트에서 다운받을 수 있다
이번 타깃은 Skybox-Cubed.shader란 녀석이다
간단하게 프래그먼트 셰이더만 발췌했다
fixed4 frag (v2f i) : SV_Target
{
half4 tex = texCUBE (_Tex, i.texcoord);
half3 c = DecodeHDR (tex, _Tex_HDR);
c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb;
c *= _Exposure;
return half4(c, 1);
}
역시 MixFog와 같은 Fog에 관한 처리가 없는 것을 알 수 있었다
그럼 뭐다? 만들어야지…
없는 걸 알았으니 다음은 Fog가 적용된 Skybox 셰이더를 만들 수 밖에…
일단 베이스가 되는 셰이더 코드가 있으니 만드는 건 어렵지 않다
베이스가 되는 셰이더 코드에 ComputeFogFactor와 MixFog를 적용하는 정도이다
그리고 URP 환경에서 CGPROGRAM를 보는 것도 기분이 나쁘므로 겸사겸사 바꿔줬다
Tags
SubShader
{
Tags
{
"Queue"="Geometry+225"
"RenderType"="Background"
"PreviewType"="Skybox"
}
}
RenderQueue는 불투명 오브젝트의 가장 마지막 순서인 Geometry(2000)+225 로 설정했다
보통은 Background(1000)으로 설정하겠지만, 어떻게든 Over Draw를 줄여보겠다는 발악(…)
문제 생기면 그냥 머테리얼 쪽에서 조정하면 될 뿐이니 디폴트는 일단 이렇게 설정했다
버텍스 셰이더
float3 RotateAroundYInDegrees (float3 vertex, float degrees)
{
float alpha = degrees * PI / 180.0;
float sina, cosa;
sincos(alpha, sina, cosa);
float2x2 m = float2x2(cosa, -sina, sina, cosa);
return float3(mul(m, vertex.xz), vertex.y).xzy;
}
v2f vert (appdata_t v)
{
v2f o;
ZERO_INITIALIZE(v2f, o);
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
float3 rotated = RotateAroundYInDegrees(v.vertex.xyz, _Rotation);
o.vertex = TransformObjectToHClip(rotated);
o.texcoord = v.vertex.xyz;
o.fog_coord = ComputeFogFactor(o.vertex.z);
return o;
}
기존의 처리에 큰 변경 없이 ComputeFogFactor를 추가했다
프래그먼 셰이더
half4 frag (v2f i) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(i);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
half4 tex = texCUBE (_Tex, i.texcoord);
half3 c = DecodeHDREnvironment(tex, _Tex_HDR);
c = c * _Tint.rgb * half4(4.59479380, 4.59479380, 4.59479380, 2.0).rgb; // unity_ColorSpaceDouble.rgb의 값
c *= _Exposure;
c = MixFog(c, i.fog_coord);
return half4(c, 1);
}
마찬가지로 기존의 처리에 MixFog만 추가한 느낌이다
URP 환경에 맞는 함수나 값으로 바꾸기 위해 이리저리 찾긴 했다
결과
우선 Lighting의 Skybox Material를 날려주고 Fog를 설정하자
적당히 머테리얼을 만들어주고 그걸 적용한 Sphere를 배치해주자
그럼 Fog가 적용된 Skybox가 보인다
사족
사실 Lighting의 Skybox Material에 이번에 만든 셰이더가 적용된 머티리얼을 배치하고 싶었으나 스크린의 중앙 부분에서 노이즈가 발생했었다
그런데 나중에 다시 해보니 문제가 발생하지 않았다…
일단 문제가 발생하지 않는다면 Lighting의 Skybox Material를 배치하는 방식을 채택하는 것이 더 나을 것이라 생각된다
마무리
순조롭게 마무리할 수 있었던 태스크였다
역시 Built-in 코드는 여러모로 쓸모가 많다
참고 사이트
Resolved - skybox that displays a flat image
'Unity > URP or Shader 관련' 카테고리의 다른 글
URP에서 간단하게 Stencil Buffer를 사용해서 Magic Card 만들어보기! (0) | 2024.03.13 |
---|---|
URP에서 Additional Lights(Point Light, Spot Light) 적용해보기! (0) | 2024.03.06 |
버텍스 ID 3개로 풀 스크린 쿼드를 대체할 수 있다고!! (0) | 2024.02.27 |
URP에서 팔레트 스왑(Palette Swap) 기능 구현하기 (0) | 2024.02.19 |
텍스처 샘플링의 부하 측정해보기(Oculus Quest2) (0) | 2024.02.07 |