성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Java - How to use the Foreign Funct...
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>Unity로 실습하는 Shader (5) - Flat Shading</h1> <p> 플랫 셰이더(flat shader)란 것도 있었군요. ^^ 다양한 장면을 연출하다 보면 일부러 이런 효과를 주는 경우도 있을 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Flat Shading ; <a target='tab' href='https://catlikecoding.com/unity/tutorials/advanced-rendering/flat-and-wireframe-shading/'>https://catlikecoding.com/unity/tutorials/advanced-rendering/flat-and-wireframe-shading/</a> Unity flat shader? ; <a target='tab' href='http://makegamessa.com/discussion/3788/unity-flat-shader'>http://makegamessa.com/discussion/3788/unity-flat-shader</a> </pre> <br /> 아래의 shader 코드는 빛에 따른 음영이 아닌, 상단과 하단의 색을 정해 주면 그에 따라 그레이디언트처럼 shading을 합니다.<br /> <br /> <pre style='height: 400px; margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 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 } } } </pre> <br /> 여기서, pixel shader에서만 사용할 수 있는 <a target='tab' href='https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-ddx'>ddx</a>와 <a target='tab' href='https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-ddy'>ddy</a>는 각각 World 좌표계를 기준으로 x, y 좌표에 대한 편미분 값(간단히 말해 기울기 값)을 반환합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > float3 x = ddx(i.worldPos); float3 y = ddy(i.worldPos); </pre> <br /> 해당 기울기 값을 vector 취급해 외적을 한 후 정규화를 시키면 결국 x, y 기울기가 반영된 정규 벡터 값을 얻을 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > float3 norm = -normalize(cross(x, y)); </pre> <br /> 그 값을 y 축에 대해 내적을 하면, 즉 y 축과의 코사인 각으로 값을 얻어내면 그 값이 곧 삼각형 폴리곤마다 갖게 되는 법선 벡터와 다를 바가 없습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > float l = saturate(dot(norm, float3(0, 1, 0))); </pre> <br /> 그리고 그 값을 기준으로 Model의 상/하위에 정해진 색상 구간으로 보간을 해주면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > fixed4 col = lerp(_BaseCol, _TopCol, l); </pre> <br /> 적당한 Flat 단위 별 색상이 입혀지게 되는 것입니다. 예를 들어, 상단을 흰색, 하단을 회색 계열로 하면 다음과 같이 렌더링됩니다.<br /> <br /> <img alt='flat_shader_1.png' src='/SysWebRes/bbs/flat_shader_1.png' /><br /> <br /> 텍스처를 입혀본 버전은, 상단 색상만 지정하도록 바꿨는데 역시 빛에 따른 음영을 넣지 않은 코드입니다.<br /> <br /> <pre style='height: 400px; margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 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 } } } </pre> <br /> 상단만 흰색으로 지정하니 다음과 같이 렌더링되었습니다.<br /> <br /> <img alt='flat_shader_2.png' src='/SysWebRes/bbs/flat_shader_2.png' /><br /> <br /> <hr style='width: 50%' /><br /> <br /> 그 외에 다음의 글이 도움이 될 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > CG: Specify a variable not to be interpolated between vertex and fragment shader ; <a target='tab' href='https://stackoverflow.com/questions/13876763/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</a> </pre> <br /> 참고로, 처음 소개했던 "<a target='tab' href='https://catlikecoding.com/unity/tutorials/advanced-rendering/flat-and-wireframe-shading/'>Flat Shading</a>" 글에서는 ddx, ddy를 이용한 방법이 아닌, geometry shader를 이용한 것으로 바꿨다고 합니다. 역시나, 가능한 shader만으로 자유로운 표현을 하려면 geometry의 힘을 종종 빌려야만 할 것 같습니다. ^^<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
3964
(왼쪽의 숫자를 입력해야 합니다.)