참고 : https://forum.unity.com/threads/shadow-catcher-or-matte-shadow-shader.414418/


홀로렌즈는 MR 컨텐츠를 즐기기 위한 장비이다.


현실 공간에 가상의 오브젝트를 띄우는데, 그림자가 보이지 않는다면 이질감을 주게 된다.


위의 참고 글을 보면 다음과 같은 소스 코드가 있다.



Shader "Unlit/VertColorWithShadow"
{
    Properties
    {
        _MainColor("Main Color", COLOR) = (0,0,0,1)
        _ShadowColor("Shadow Color", COLOR) = (1,0,0,1)
    }
 
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
 
        Pass
        {
            Tags {"LightMode" = "ForwardBase"}
 
            CGPROGRAM
            #pragma multi_compile_fwdbase
            #pragma vertex vert
            #pragma fragment frag
 
            #include "UnityCG.cginc"
            #include "AutoLight.cginc"
 
            float4 _MainColor;
            float4 _ShadowColor;
 
            struct appdata
            {
                float4 vertex : POSITION;
            };
 
            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 mainColor : COLOR;
                LIGHTING_COORDS(1,2)
            };
         
            v2f vert (appdata v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.mainColor = _MainColor;
 
                TRANSFER_VERTEX_TO_FRAGMENT(o);
 
                return o;
            }
         
            fixed4 frag (v2f i) : SV_Target
            {
                fixed atten = 1.0 - LIGHT_ATTENUATION(i);
                fixed3 shadowColor = atten * _ShadowColor.rgb;
                fixed4 finalColor = i.mainColor + fixed4(shadowColor, 1.0);
 
                return finalColor;
            }
            ENDCG
        }
 
        // Pass to render object as a shadow caster
        Pass
        {
            Name "ShadowCaster"
            Tags { "LightMode" = "ShadowCaster" }
     
            ZWrite On ZTest LEqual Cull Off
 
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_shadowcaster
            #include "UnityCG.cginc"
 
            struct v2f {
                V2F_SHADOW_CASTER;
            };
 
            v2f vert( appdata_base v )
            {
                v2f o;
                TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
                return o;
            }
 
            float4 frag( v2f i ) : SV_Target
            {
                return float4(1.0, 1.0, 1.0, 1.0);
            }
            ENDCG
        }
    }
}

위의 Shader 코드를 Unity에서 작성한다.


Material을 새로 만들고 Shader를 집어넣는다.


Shadow Color를 적절하게 조절해준다.


Spatial Mapping Manager의 Surface Material에 위의 Material을 넣어준다.


그러면 홀로렌즈로 볼 때는 그림자가 정상적으로 나오는 것을 볼 수 있다.


하지만 디바이스 포탈을 통해 캡처나 녹화를 하면 다음과 같이 나온다.



공간이 어둡게 된 부분은 Spatial Mapping이 된 부분이고 밝은 부분은 Mapping이 되지 않은 부분이다.


홀로렌즈 시연을 할 때, 디바이스 포탈이나 스펙데이터 뷰를 사용한 녹화가 필요한데 이런 현상이 일어나면 곤란하다.


위의 코드 일부를 수정하면 간단하게 해결된다.

            fixed4 frag (v2f i) : SV_Target
            {
                fixed atten = 1.0 - LIGHT_ATTENUATION(i);
		if(atten > 0)
		{
 	               fixed3 shadowColor = atten * _ShadowColor.rgb;
        	       fixed4 finalColor = i.mainColor + fixed4(shadowColor, 1.0);
 
 	               return finalColor;
		}
		else
			return float4(0, 0, 0, 0);
            }





그림자 색감을 좀 더 부드럽고 퍼지는 느낌을 주고 싶지만 아직은 홀로렌즈의 성능이 낮아서 불가능하다.



Spatial Mapping에 있는 기능 때문인건지 InputManager의 기능인 것인지는 모르겠지만


OnInputClicked가 실행되면 Spatial Mapping의 Material이 켜지거나 꺼진다.


이를 해결하는 다양한 방법이 있겟지만 다음과 같은 방법을 이용하여 해결하였다.



SpatialMappingManager의 해당 부분을 drawVisualMeshes = value; 부분을 주석처리 하면 된다.


내부를 건드려서 좋은 방법은 아닌 것 같지만 일단 다음과 같이 진행하였다.

+ Recent posts