성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
글쓰기
제목
이름
암호
전자우편
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 (9) - 투명 배경이 있는 텍스처 입히기</h1> <p> 지난 글에서,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Unity로 실습하는 Shader (1) - 컬러 반전 및 상하/좌우 뒤집기 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11608'>http://www.sysnet.pe.kr/2/0/11608</a> </pre> <br /> 실습한 나무 그림의,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Trees0091 ; <a target='tab' href='https://www.textures.com/download/trees0091/74537'>https://www.textures.com/download/trees0091/74537</a> </pre> <br /> texture를 3D GameObject 중 Plane에 입혀 보겠습니다. 그런데, 분명히 png 이미지로는 똑바로 선 나무 그림인데 기본 shader + material 상태에서 평면에 누워 있는 나무 이미지가 카메라가 바라보는 시점에 대해 거꾸로 되어 있습니다. <br /> <br /> <img alt='blend_shader_1.png' src='/SysWebRes/bbs/blend_shader_1.png' /><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;' > Why are my textures on planes flipped / reversed left-to-right? ; <a target='tab' href='https://answers.unity.com/questions/125855/why-are-my-textures-on-planes-flippedreversed-left.html'>https://answers.unity.com/questions/125855/why-are-my-textures-on-planes-flippedreversed-left.html</a> </pre> <br /> 그래서 material의 Texture 설정에서 Tiling 값의 Y를 -1로 바꿔야 합니다. 그럼 나무가 똑바로 서긴 하는데 자세히 보면 좌우가 바뀐 상태입니다. 따라서 X 값도 -1로 설정해 줘야 합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Tiling X == -1 Y == -1 </pre> <br /> 그러고 나면 다음과 같이 이미지가 png 파일 그대로 (카메라 방향에 맞게 의도한 대로) 나오게 됩니다.<br /> <br /> <img alt='blend_shader_2.png' src='/SysWebRes/bbs/blend_shader_2.png' /><br /> <br /> 자, 이제 나무를 입힌 평면을 카메라에 정면으로 세워야 하는데요, 이를 위해 x축을 기준으로 회전시켜야 합니다. 보통 생각으로는 90도 회전을 시키면 될 것 같은데, Unity의 경우 왼손 좌표계이므로 x축 회전은 양수(+) 값에 대해 다음과 같이 회전을 하게 됩니다.<br /> <br /> [그림 출처: <a target='tab' href='http://www.fundza.com/rib/example4/index.html'>http://www.fundza.com/rib/example4/index.html</a>]<br /> <img alt='blend_shader_3.png' src='/SysWebRes/bbs/blend_shader_3.png' /><br /> <br /> 따라서 Plane의 앞면이 카메라가 보이는 쪽으로 서 있으려면 -90도를 해야 합니다. 자, 그래서 결국 다음과 같이 겨우 나무 하나를 보이게 만들었습니다. ^^<br /> <br /> <img alt='blend_shader_4.png' src='/SysWebRes/bbs/blend_shader_4.png' /><br /> <br /> <hr style='width: 50%' /><br /> <br /> 여기서 문제(?)가 있는데요, 저 나무 그림(png)의 배경은 원래 투명(alpha == 0)했는데 Unity의 Plane 객체에 material로 입히면 저렇게 배경이 검은색으로 나온다는 점입니다. 여기서 shader의 기본 코드를 볼까요?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Shader "My/blendShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { <span style='color: blue; font-weight: bold'>Tags { "RenderType"="Opaque" }</span> LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; } <span style='color: blue; font-weight: bold'>fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); return col; }</span> ENDCG } } } </pre> <br /> pixel shader를 보면, 정상적으로 uv 좌표에 따라 texture로부터 fixed4 형식으로 alpha 값까지 해서 추출한 것이 맞습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > fixed4 frag (v2f i) : SV_Target { <span style='color: blue; font-weight: bold'>fixed4 col = tex2D(_MainTex, i.uv);</span> return col; } </pre> <br /> 실제로 나무의 배경은 fixed4(0, 0, 0, 0) 값들이 반환되고 있습니다. 만약 alpha 값이 먹혔다면 투명으로 나와야겠지만 그렇지 않았다면 (0,0,0) 색상이니 검은색으로 나오는 것이 맞습니다. 그리고 이렇게 불투명하게 그리게 된 데에는 shader의 RenderType이 "Opaque"로 설정되어 있기 때문입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Tags { "RenderType"="Opaque" } </pre> <br /> 투명 처리를 위해 이 값을 "Transparent"로 바꾸고, 아울러 렌더링 우선순위를 "Transparent"로 바꿔줍니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Tags { "RenderType"="Transparent" "Queue" = "Transparent" } </pre> <br /> 마지막으로, 배경과 어떻게 Alpha 채널이 섞이게 될지를 알려주는 Blend 옵션을 주는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Blend SrcAlpha OneMinusSrcAlpha </pre> <br /> 합이 1이 되는 아핀 조합으로 전형적인 선형 결합의 Blend 옵션입니다. 따라서, 투명 처리가 된 곳의 alpha == 0이므로,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > SrcAlpha OneMinusSrcAlpha 트리 texture == 0, 배경 == OneMinusSrcAlpha == 1 - 0 == 1 </pre> <br /> 다음과 같이 투명 처리가 근사하게 적용된 것을 볼 수 있습니다. ^^<br /> <br /> <img alt='blend_shader_5.png' src='/SysWebRes/bbs/blend_shader_5.png' /><br /> <br /> <hr style='width: 50%' /><br /> <br /> shader에 사용된 TRANSFORM_TEX는 (C:\Program Files\Unity\Editor\Data\CGIncludes\)UnityCG.cginc 파일에 다음과 같은 매크로로 정의되어 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // Transforms 2D UV by scale/bias property #define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw) </pre> <br /> 따라서 shader에 사용된 코드는 다음과 같이 확장됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.uv = v.uv * _MainTex_ST.xy + _MainTex_ST.zw; </pre> <br /> _MainTex_ST는 Unity의 Material에 대한 Inspector 창의 "Tiling"과 "Offset" 값을 담고 있습니다.<br /> <br /> <img alt='blend_shader_0.png' src='/SysWebRes/bbs/blend_shader_0.png' /><br /> <br /> 그렇기 때문에 "o.uv = TRANSFORM_TEX(v.uv, _MainTex);" 코드를 쓰지 않고 그냥 "o.uv = v.uv"와 같이 대입하면 Unity 에디터에서 설정한 "Tiling"과 "Offset"값이 적용되지 않습니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
9028
(왼쪽의 숫자를 입력해야 합니다.)