서피스 아웃풋 (SurfaceOutput)
SurfaceOutput 구조체 안에는 머테리얼의 최종 모습을 결정하기 위해 사용되는 여러가지 프로퍼티를 포함
1 2 3 4 5 6 7 8 9 | struct SurfaceOutput { fixed3 Albedo; // diffuse color fixed3 Normal; // tangent space normal, if written fixed3 Emission; half Specular; // specular power in 0..1 range fixed Gloss; // specular intensity fixed Alpha; // alpha for transparencies }; | cs |
Albedo : 기본색상
Normal : 반사각을 결정하는 면의 방향
Emission : 오브젝트가 스스로 생성하는 빛의 양
Specular : 머테리얼이 빛을 반사하는 정도 (0~1)
Gloss : 스펙큘러 반사가 퍼지는 정도(세기)
Alpha : 머테리얼의 투명한 정도
서피스 인풋 (SurfaceInput)
Input에는 일반적으로 셰이더에 의해 요구되는 텍스쳐 좌표가 있음.
텍스쳐 좌표의 이름은 uv뒤에 텍스쳐 이름이 오는 형태로 해야함.
Input 안에 아래를 입력할 수 있음.
float3 viewDir - 뷰 방향을 포함합니다. 시차 효과, 림 라이팅 등의 계산에 사용
float4 screenPos - 반사 효과의 스크린스페이스 위치 또는 스크린스페이스 효과를 포함합니다.
float3 worldPos - 월드 공간상의 위치를 포함합니다.
float3 worldRefl - Surface Shaders이 o.Normal에 기입하지 않는 경우 월드 반사 벡터를 포함
float3 worldNormal - Surface Shaders이 o.Normal에 기입하지 않는 경우 월드 법선 벡터를 포함
float3 worldRefl; INTERNAL_DATA - Surface Shaders이 o.Normal에 쓸 경우 월드 반사 벡터를 포함합니다.
픽셀 당 법선 맵에 기초하여, 반사 벡터를 얻으려면 WorldReflectionVector(IN, o.Normal)를 사용합니다.
float3 worldNormal; INTERNAL_DATA - _Surface Shaders가 o.Normal에 쓰는 경우 _ 월드 반사 벡터를 포함합니다.
픽셀 당 법선맵에 기초하며, 법선 벡터를 얻으려면 WorldNormalVector (IN, o.Normal)를 사용합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | Shader "Example/Diffuse Distance" { Properties { _MainTex ("Texture", 2D) = "white" {} _Center ("Center", Vector) = (0,0,0,0) _Radius ("Radius", Float) = 0.5 } SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input { float2 uv_MainTex; float3 worldPos; }; sampler2D _MainTex; float3 _Center; float _Radius; void surf (Input IN, inout SurfaceOutput o) { float d = distance(_Center, IN.worldPos); float dN = 1 - saturate(d / _Radius); if (dN > 0.25 && dN < 0.3) o.Albedo = half3(1,1,1); else o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; } ENDCG } Fallback "Diffuse" } | cs |
22번째 줄에서 인스펙터에서 받은 _Center값과 그려질 픽셀(IN.worldPos)의 거리를 계산
23번째 줄에서 그것을 0~1 사이의 값으로 클램프함. _Center에 가까울수록 1, _Radius에 가까울수록 0
이후 거리가 일정 범위 안이면 Albedo를 흰색으로 만듬
서피스 함수
색 변경하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Shader "Example/Diffuse Simple" { SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input { float4 color : COLOR; }; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = 1; } ENDCG } Fallback "Diffuse" } | cs |
#pragma surface surf Lambert는 surface함수 이름은 surf이고 Lambert(디퓨즈) 라이트 모델을 사용한다는 의미
10번째줄 o.Albedo = 1에서 아웃풋의 색상을 흰색으로 변경함.
텍스쳐 적용하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | Shader "Example/Diffuse Distance" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input { float2 uv_MainTex; }; sampler2D _MainTex; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; } ENDCG } Fallback "Diffuse" } | cs |
Input에서 tex2D() 함수를 통해 _MainTex에서 uv_MainTex 좌표의 색상 정보를 가져와서 적용한다.
노멀맵 적용하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | Shader "Example/Diffuse Distance" { Properties { _MainTex ("Texture", 2D) = "white" {} _BumpMap ("Bumpmap", 2D) = "bump" {} } SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input { float2 uv_MainTex; float2 uv_BumpMap; }; sampler2D _MainTex; sampler2D _BumpMap; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); } ENDCG } Fallback "Diffuse" } | cs |
텍스쳐 적용과 마찬가지로 노멀맵을 받아와서 o.Normal에 UnpackNormal로 텍스쳐를 적용
기타 서피스 셰이더의 사용 예시는 공식문서를 참고
https://docs.unity3d.com/kr/530/Manual/SL-SurfaceShaderExamples.html
'프로그래밍 공부 > Shader' 카테고리의 다른 글
유니티 셰이더 기초 - Vertex and Fragment Programs / Surface Shader (종류) (0) | 2018.07.17 |
---|---|
유니티 셰이더 기초 - ShaderLab / Fixed Funtion Shader 2 (1) | 2018.07.17 |
유니티 셰이더 기초 - ShaderLab / Fixed Funtion Shader 1 (0) | 2018.07.17 |
쉐이더란 무엇일까 (0) | 2018.07.17 |
셰이더 기초강좌 링크 (0) | 2018.07.16 |