Microsoft MVP성태의 닷넷 이야기
Graphics: 7. Unity로 실습하는 Shader (5) - Flat Shading [링크 복사], [링크+제목 복사],
조회: 21692
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 13개 있습니다.)
Graphics: 2. Unity로 실습하는 Shader
; https://www.sysnet.pe.kr/2/0/11607

Graphics: 3. Unity로 실습하는 Shader (1) - 컬러 반전 및 상하/좌우 뒤집기
; https://www.sysnet.pe.kr/2/0/11608

Graphics: 4. Unity로 실습하는 Shader (2) - 고로 셰이딩(gouraud shading) + 퐁 모델(Phong model)
; https://www.sysnet.pe.kr/2/0/11609

Graphics: 5. Unity로 실습하는 Shader (3) - 고로 셰이딩(gouraud shading) + 퐁 모델(Phong model) + Texture
; https://www.sysnet.pe.kr/2/0/11610

Graphics: 6. Unity로 실습하는 Shader (4) - 퐁 셰이딩(phong shading)
; https://www.sysnet.pe.kr/2/0/11611

Graphics: 7. Unity로 실습하는 Shader (5) - Flat Shading
; https://www.sysnet.pe.kr/2/0/11613

Graphics: 8. Unity Shader - Texture의 UV 좌표에 대응하는 Pixel 좌표
; https://www.sysnet.pe.kr/2/0/11614

Graphics: 9. Unity Shader - 전역 변수의 초기화
; https://www.sysnet.pe.kr/2/0/11616

Graphics: 10. Unity로 실습하는 Shader (6) - Mosaic Shading
; https://www.sysnet.pe.kr/2/0/11619

Graphics: 11. Unity로 실습하는 Shader (7) - Blur (평균값, 가우스, 중간값) 필터
; https://www.sysnet.pe.kr/2/0/11620

Graphics: 12. Unity로 실습하는 Shader (8) - 다중 패스(Multi-Pass Shader)
; https://www.sysnet.pe.kr/2/0/11628

Graphics: 13. Unity로 실습하는 Shader (9) - 투명 배경이 있는 텍스처 입히기
; https://www.sysnet.pe.kr/2/0/11631

Graphics: 19. Unity로 실습하는 Shader (10) - 빌보드 구현
; https://www.sysnet.pe.kr/2/0/11641




Unity로 실습하는 Shader (5) - Flat Shading

플랫 셰이더(flat shader)란 것도 있었군요. ^^ 다양한 장면을 연출하다 보면 일부러 이런 효과를 주는 경우도 있을 것입니다.

Flat Shading
; https://catlikecoding.com/unity/tutorials/advanced-rendering/flat-and-wireframe-shading/

Unity flat shader?
; http://makegamessa.com/discussion/3788/unity-flat-shader

아래의 shader 코드는 빛에 따른 음영이 아닌, 상단과 하단의 색을 정해 주면 그에 따라 그레이디언트처럼 shading을 합니다.

Shader "My/flatShader"
{
    Properties
    {
        _BaseCol("Base colour", Color) = (1,1,1,1)
        _TopCol("Top colour", Color) = (1,1,1,1)
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag

    #include "UnityCG.cginc"

            float4 _TopCol, _BaseCol;

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldPos : TEXCOORD0;
            };

            v2f vert(appdata v)
            {
                v2f o;

                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);

                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                float3 x = ddx(i.worldPos);
                float3 y = ddy(i.worldPos);

                float3 norm = -normalize(cross(x, y));
                float l = saturate(dot(norm, float3(0, 1, 0)));
                fixed4 col = lerp(_BaseCol, _TopCol, l);

                return col;
            }
            ENDCG
        }
    }
}

여기서, pixel shader에서만 사용할 수 있는 ddxddy는 각각 World 좌표계를 기준으로 x, y 좌표에 대한 편미분 값(간단히 말해 기울기 값)을 반환합니다.

float3 x = ddx(i.worldPos);
float3 y = ddy(i.worldPos);

해당 기울기 값을 vector 취급해 외적을 한 후 정규화를 시키면 결국 x, y 기울기가 반영된 정규 벡터 값을 얻을 수 있습니다.

float3 norm = -normalize(cross(x, y));

그 값을 y 축에 대해 내적을 하면, 즉 y 축과의 코사인 각으로 값을 얻어내면 그 값이 곧 삼각형 폴리곤마다 갖게 되는 법선 벡터와 다를 바가 없습니다.

float l = saturate(dot(norm, float3(0, 1, 0)));

그리고 그 값을 기준으로 Model의 상/하위에 정해진 색상 구간으로 보간을 해주면,

fixed4 col = lerp(_BaseCol, _TopCol, l);

적당한 Flat 단위 별 색상이 입혀지게 되는 것입니다. 예를 들어, 상단을 흰색, 하단을 회색 계열로 하면 다음과 같이 렌더링됩니다.

flat_shader_1.png

텍스처를 입혀본 버전은, 상단 색상만 지정하도록 바꿨는데 역시 빛에 따른 음영을 넣지 않은 코드입니다.

Shader "My/flatTextureShader"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _TopCol("Top colour", Color) = (1,1,1,1)
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

            float4 _TopCol, _BaseCol;
            sampler2D _MainTex;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldPos : TEXCOORD0;
                float2 uv : TEXCOORD1;
            };

            v2f vert(appdata v)
            {
                v2f o;

                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);

                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                float3 x = ddx(i.worldPos);
                float3 y = ddy(i.worldPos);

                fixed4 textureColor = tex2D(_MainTex, i.uv);

                float3 norm = -normalize(cross(x, y));
                float l = saturate(dot(norm, float3(0, 1, 0)));
                fixed4 col = lerp(textureColor, _TopCol, l);

                return col;
            }
            ENDCG
        }
    }
}

상단만 흰색으로 지정하니 다음과 같이 렌더링되었습니다.

flat_shader_2.png




그 외에 다음의 글이 도움이 될 것입니다.

CG: Specify a variable not to be interpolated between vertex and fragment shader
; https://stackoverflow.com/questions/13876763/cg-specify-a-variable-not-to-be-interpolated-between-vertex-and-fragment-shader

참고로, 처음 소개했던 "Flat Shading" 글에서는 ddx, ddy를 이용한 방법이 아닌, geometry shader를 이용한 것으로 바꿨다고 합니다. 역시나, 가능한 shader만으로 자유로운 표현을 하려면 geometry의 힘을 종종 빌려야만 할 것 같습니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 7/18/2018]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... [196]  197 
NoWriterDateCnt.TitleFile(s)
43정성태12/23/200318435기타: 3. XP/2003 개인 방화벽 설정파일 다운로드1
40정성태7/23/200321925COM 개체 관련: 10. IE BHO 개체를 개발할 때, 인터넷 익스플로러가 아닌 탐색기에서 활성화 되는 문제 해결 [1]
41김성현7/24/200320761    답변글 COM 개체 관련: 10.1. [답변]: IE BHO 개체를 개발할 때, 인터넷 익스플로러가 아닌 탐색기에서 활성화 되는 문제 해결
42정성태7/29/200318701        답변글 COM 개체 관련: 10.2. feedback 을 받기 위해서 답변 기능을 가능하게 해두었습니다.
39정성태7/17/200324453VS.NET IDE: 5. 원격 제어 3가지 방법
38정성태7/17/200320993.NET Framework: 8. IIS 서버 재설치와 ASP.NET 서비스의 문제점
36정성태7/17/200321667.NET Framework: 7. 시행착오 - WebService 참조 추가 오류
35정성태7/17/200322222.NET Framework: 6. Win2000에서의 .NET COM+ 자동 등록 오류 발생 해결
34정성태7/17/200320896VS.NET IDE: 4. VC++ 원격 디버깅파일 다운로드1
33정성태7/17/200321055VS.NET IDE: 3. Win2000 NAT 서비스
32정성태7/17/200322278COM 개체 관련: 9. _bstr_t, CComBSTR, string 클래스 사용 [1]
31정성태7/17/200319324COM 개체 관련: 8. IDL 구문에서 구조체를 pack 하는 방법
30정성태7/17/200336570VC++: 7. [STL] vector 사용법 및 reference 사용예 [1]파일 다운로드1
28정성태7/17/200320977스크립트: 3. Programming Microsoft Internet Explorer 5 - CHM 파일
29정성태7/17/200320482    답변글 스크립트: 3.1. Programming Microsoft Internet Explorer 5 - 소스코드
27정성태7/17/200319441COM 개체 관련: 7. HTML Control에서 DELETE, 화살표 키 등이 안 먹는 문제
26정성태7/17/200320590COM 개체 관련: 6. WebBrowser 콘트롤에서 프레임을 구하는 소스
25정성태7/17/200318201COM 개체 관련: 5. C++ Attributes - Make COM Programming a Breeze with New Feature in Visual Studio .NET [2]파일 다운로드1
24정성태7/17/200321823.NET Framework: 5. (MHT 변환해서 가져온 글) .NET 의 COM+ 서비스 사용파일 다운로드1
23정성태7/17/200325518.NET Framework: 4. webservice.htc - HTML Script에서도 웹서비스 엑세스 [2]파일 다운로드1
22정성태7/17/200320061.NET Framework: 3. .NET Framework SDK 퀵 스타트 자습서
21정성태7/17/200319117.NET Framework: 2. 김현승님의 "ASP.NET & .NET EnterpriseServices & Remoting 코드 템플릿"
20정성태2/15/200526164VS.NET IDE: 2. Platform SDK 설치
19정성태7/17/200322124.NET Framework: 1. JScript.NET 강좌 사이트[영문]
18정성태7/17/200319504COM 개체 관련: 4. Exchanging Data Over the Internet Using XML [1]파일 다운로드1
17정성태7/17/200327457VC++: 6. Win32 API Hook - 소스는 "공개소스"에있습니다. [2]
... [196]  197