8 – 04 Occlusion (오클루젼) (Unity Shader)
Occlusion (오클루젼)은 Ambient Occlusion (엠비언트 오클루젼) 이라고 부르며, 구석진 부분의 추가적인 음영을 표현하는 기능입니다.
일반적으로 세상에서 그림자가 드리워진 부분도 사방에서 오는 환경광 정도를 받고 있는 것이 일반적입니다.
하지만, 매우 구석져 있거나 복잡한 물체들로 가려져서 환경광도 닫지 못하는 부분은 더욱 더 어두워지는 데
이 부분은 Ambient Occlusion (엠비언트 오클루젼) 환경차폐라고 부릅니다.
https://docs.unity3d.com/Manual/SL-SurfaceShaders.html
직접 확인해보기 위해서 아래 에셋을 사용했습니다. (무료)
https://assetstore.unity.com/packages/3d/characters/humanoids/barbarian-warrior-75519 <- TestAsset
사용했던 바바리안 몸체는 잠시 비활성화 하고 도끼를 활성화 했습니다.
쉐이더 코드는 바바리안 바디에 적용했던 코드를 사용했습니다.
Shader "Custom/AxeOC" { Properties { _MainTex("Albedo (RGB)", 2D) = "white" {} _BumpMap("Normal Map", 2D) = "white" {} // NormalMap _Test("TestFloat",Range(0.5, 3)) = 1 } SubShader { Tags { "RenderType" = "Opaque" } LOD 200 CGPROGRAM #pragma surface surf Standard #pragma target 3.0 sampler2D _MainTex; sampler2D _BumpMap; // NormalMap float _Test; struct Input { float2 uv_MainTex; float2 uv_BumpMap; // NormalMap }; void surf(Input IN, inout SurfaceOutputStandard o) { float4 c = tex2D(_MainTex, IN.uv_MainTex); float3 d = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); o.Normal = float3(d.x * _Test, d.y * _Test, d.z); // _Test에 따라서 수치 변화 2 2배 0.5 0.5배 o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
Occlusion 추가
Shader "Custom/AxeOC" { Properties { _MainTex("Albedo (RGB)", 2D) = "white" {} _BumpMap("Normal Map", 2D) = "white" {} _Test("TestFloat",Range(0.5, 3)) = 1 _Occlusion("Occlusion", 2D) = "white" {} // Occlusion } SubShader { Tags { "RenderType" = "Opaque" } LOD 200 CGPROGRAM #pragma surface surf Standard #pragma target 3.0 sampler2D _MainTex; sampler2D _BumpMap; sampler2D _Occlusion; float _Test; struct Input { float2 uv_MainTex; float2 uv_BumpMap; // 주의 uv_Occlusion 포함 X }; void surf(Input IN, inout SurfaceOutputStandard o) { float4 c = tex2D(_MainTex, IN.uv_MainTex); o.Occlusion = tex2D(_Occlusion, IN.uv_MainTex); // Occlusion // _MainTex와 동일한 UV 값을 받습니다. float3 d = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); o.Normal = float3(d.x * _Test, d.y * _Test, d.z); o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
Occlusion 적용 전
Occlusion 적용 후
Normal Map 의 강도를 조절하면 더 확실하게 알 수 있습니다.
지금 사용한 코드에서는 Occlusion은 half (SurfaceOutput -float4)를 받습니다. (r 채널만 사용합니다.)
Occlusion 기능을 위해서 rgb 채널을 사용하는 텍스쳐를 사용하는 것은 낭비입니다.
_MainTex의 a 채널에 Occlusion 맵을 넣고 사용한다면 텍스쳐를 절약 할 수 있습니다.