반응형

간단한 서피스 커스텀 셰이더를 만들었는데 알파 값을 0으로 아무리 해도 알파가 안빠지는 현상이 계속됐다.

여러가지 테스트를 해보니 SurfaceOutputCustom 에 Normal 과 Emission 값을 넣어주지 않으면 알파 값이 계속 빠지지 않는 것이다..

#pragme에 keepalpha 문을 넣어주는 것은 당연하고..

 

서피스 셰이더 제작후 알파값이 빠지지 않으면 아래의 세 구문을 꼭 넣어주자.

 

Blend One OneMinusDstAlpha

 

#pragma surface surf keepalpha

 

struct SurfaceOutputCustom
{
      fixed3 Albedo;
      fixed3 Normal;
      fixed3 Emission;
      fixed Alpha;
};

 

반응형
반응형

유니티 서피스 셰이더를 UnLit으로 사용할 때 캐릭터가 하얗게 타는 현상이 발생했다.

Scene안에 라이트가 두개 이상 있을경우 UnLit 서피스 셰이더임에도 캐릭터가 하얗게 타는 것이다..(프라그 셰이더는 발생하지 않음)

해당 문제를 해결하기 위해서는 noforwardadd를 꼭 써줘야 한다.

 

 

#pragma surface surf NoLighting noambient noforwardadd

 

그런데 이렇게 하고나서도 또 타는 현상이 발생했는데, 이 역시 라이트가 두개 있을때 두 라이트가 같은 Layer Culling을 사용하면서

그 사용된 Culling Object가 또 하얗게 타는 것이다... 레이어를 수정해서 해결하긴 했는데.. 뭔가 이상하고 찜찜한 기분..

 

 

아래는 라이트에 영향받지 않는 저 사양 서피스 셰이더 코드이다. 딱 림컬러까지만 처리~

 

 

    SubShader
    {
        LOD 200
        Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
        Lighting off

            CGPROGRAM
            
            #pragma surface surf NoLighting noambient noforwardadd

            //================================================================
            // VARIABLES
            
            fixed4 _Color;
            sampler2D _MainTex;
  
            uniform fixed _IsRim;
            uniform fixed4 _RimColor;
            uniform fixed _RimPower;
   

            struct Input
            {
                half2 uv_MainTex;
                half3 viewDir;
            };
            

            half4 LightingNoLighting (SurfaceOutput s, half3 lightDir, half atten)
            {
               return half4(s.Albedo, s.Alpha);
            }
            
            
            //================================================================
            // SURFACE FUNCTION
            
            void surf (Input IN, inout SurfaceOutput o)
            {
                fixed4 mainTex = tex2D(_MainTex, IN.uv_MainTex);
                fixed rim = (1.0 - saturate(dot(normalize(IN.viewDir), o.Normal)));

                o.Albedo = mainTex.rgb; * Color.rgb;

                o.Alpha = mainTex.a * _Color.a;

                o.Emission = _RimColor.rgb * pow(rim, 1.5 - _RimPower) * _IsRim;

            }
            
            ENDCG

    }

반응형
반응형

기존에 제작한 은면제거 방식은 벡터의 내적이라는 수학 공식을 활용하여 카메라와 대치되는 각을 계산하여 면을 제거하는 방식이었습니다.

하지만 이 방식은 몇가지 단점이 존재합니다.


1. 각도를 계산해서 하다보니 카메라에 안잡히는 면도 각도조건만 맞으면 남아있게 된다.

2. 면이 깔끔하게 지워지지 않는다. 가령 면은 지워졌는데, 버텍스가 남는다던지..

 

등등.. 여러번 시뮬레이션을 돌려보면 금방 알 수 있는 단점들이 존재합니다.

하지만, 이번에 제작한 Hidden Surface 방식은 렌더링 된 G-Buffer의 값을 얻어와 지오메트리의 렌더링된 면을 메모리에 기억하여 삭제하는 방식이라 더 깔끔하게 면들을 정리해줍니다.

단, 계산시간이 오래 걸릴수 있다는 단점이 있습니다. 이 부분도 차후에 개선할수있도록 해보겠습니다.


이 스크립트의 구동방식을 간단히 살펴보면

1. 먼저 대상이 될 오브젝트의 면들을 전부 디테치 한 후 메모리에 저장한후 각 면마다 오브젝트를 생성해 줍니다.

-여기서 먼저 대상이 될 원본 오브젝트를 하이드 시켜 줍니다.(G-Buffer값 구할때 방해되는 요소)


 



2. 디테치된 면들의 렌더링 된 채널값에서 G-Buffer(지오메트리버퍼) 값을 구해온다.

G-Buffer의 개념 - http://en.wikipedia.org/wiki/Deferred_shading


3. 렌더링 버퍼의 값을 구해서 원본 모델링에 저장이 됐으면 이제 각 면들은 필요없어 졌으니 전부 지워버린다.


4. 원본 면의 페이스 정보들을 비트어레이에 담고 G-Buffer에 담긴 값들만 False로 선언해준다.

5. 이제 원본 오브젝트의 비트어레이에 담긴 면들을 삭제하라는 명령을 실행하면 false로 제외된 값들을 빼고 삭제를 하게 된다.



벡터의 내적 방식과 Hidden Surface 방식의 비교 샷


백페이스 방식- 면이 지저분하게 정리된다.  


 

 히든 서페이스 방식 - 면이 깔끔하게 정리된다.

 

 

이번 과제를 통해 알게 된 내용

1. G-Buffer의 개념과 렌더링에 대한 기초

2. 원본에 있는 면을 뜯어내서 메모리에 저장시킬 수 있는 기능

3. finditem을 이용하여 비트어레이의 값을 조절할수 있는 기능

반응형

+ Recent posts