language:shader:unity:surface-shader-basic
차이
문서의 선택한 두 판 사이의 차이를 보여줍니다.
다음 판 | 이전 판 | ||
language:shader:unity:surface-shader-basic [2014/05/15 19:14] – 만듦 kieuns | language:shader:unity:surface-shader-basic [2024/04/23 22:45] (현재) – 바깥 편집 127.0.0.1 | ||
---|---|---|---|
줄 1: | 줄 1: | ||
+ | 베이직이라는데 매뉴얼에서 건질게 별로 없어 보이네. | ||
+ | [[https:// | ||
+ | |||
+ | 아무튼, | ||
+ | |||
+ | * Vertex/ | ||
+ | * 다른 스크립트 랭귀지를 제공하는 것도 아니고 | ||
+ | * 반복적인 코드 작업을 대신 해주는 정도라는데(뭔소리? | ||
+ | * 실제 작업은 **Cg/ | ||
+ | |||
+ | ====== 작동 ====== | ||
+ | |||
+ | * surface function을 작성 | ||
+ | * 계산 결과물을 저장할 SurfaceOutput 에 값을 채워줌 | ||
+ | |||
+ | SurfaceShader에서 input, | ||
+ | |||
+ | ===== 컴파일 지시자 ===== | ||
+ | |||
+ | SurfaceShader 부분은, **CGPROGRAM .. ENDCG** 부분에 추가 | ||
+ | |||
+ | * 이 구문은, SubShader에 들어가야 한다. Pass 부분에 넣지 않는다. \\ 멀티 패스가 필요한 경우, 자동으로 만들어짐 | ||
+ | * **%%#pragma surface ..%%** 지시문으로 SurfaceShader 부분을 가리킨다. | ||
+ | |||
+ | < | ||
+ | ShaderLab " | ||
+ | SubShader { | ||
+ | CGPROGRAM | ||
+ | ENDCG | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | **%%#pragma surface ..%%** 부분은, | ||
+ | |||
+ | < | ||
+ | #pragma surface < | ||
+ | </ | ||
+ | |||
+ | * surfaceFunction : 어느 함수가 셰이더 코드를 갖고 있는지 알려줘야 한다. < | ||
+ | void surf (Input IN, inout SurfaceOutput o)</ | ||
+ | * 라이트 모델도 적어야 한다. | ||
+ | * Lambert(diffuse), | ||
+ | |||
+ | ===== Input structure ===== | ||
+ | |||
+ | **Input** 구조체는 기본 텍스쳐UV를 넣는다. 이름은 꼭 **uv**여야한다. 두번째 텍스쳐가 있는 경우에는 **uv2** | ||
+ | |||
+ | 추가로 Input에 넣을 수 있는 값들 | ||
+ | |||
+ | * (float3) viewDir : 뷰디렉션 | ||
+ | * (float4) with COLOR : 정점 컬러 | ||
+ | * (float4) screenPos : 화면상의 위치 | ||
+ | * (float3) worldPos : 월드스페이스상의 위치 | ||
+ | * (float3) worldRefl | ||
+ | * (float3) worldRefl; INTERNAL_DATA | ||
+ | * (float3) worldNormal; | ||
+ | |||
+ | ===== SurfaceOutput ===== | ||
+ | |||
+ | 표준 SurfaceOuptut | ||
+ | |||
+ | < | ||
+ | struct SurfaceOutput { | ||
+ | half3 Albedo; | ||
+ | half3 Normal; | ||
+ | half3 Emission; // 메시표면의 방출되는 빛. 외부에 영향을 주지 못한다. | ||
+ | half Specular; | ||
+ | half Gloss; | ||
+ | half Alpha; | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | * half (== float) | ||
+ | ====== 예 ====== | ||
+ | |||
+ | ===== One Color Diffuse ===== | ||
+ | |||
+ | SurfaceShader에 대한 기본 뼈대 | ||
+ | |||
+ | * 반투명 오브젝트 | ||
+ | * 표면 색상을 전부 흰색으로 칠한다. | ||
+ | * 라이팅연산 결과를 사용하기 때문에 빛에 따라 색의 명암이 달라진다. | ||
+ | * in : 색상 정보만 얻어다 사용 | ||
+ | * out에 대한 구조체는 기본 값을 사용 | ||
+ | |||
+ | < | ||
+ | //표면 색상을 전부 흰색으로 칠한다. | ||
+ | Shader " | ||
+ | SubShader { | ||
+ | // 반투명 오브젝트 | ||
+ | Tags { " | ||
+ | | ||
+ | CGPROGRAM | ||
+ | #pragma surface surf Lambert | ||
+ | | ||
+ | //in : 색상 정보만 얻어다 사용 | ||
+ | struct Input { | ||
+ | float4 color : COLOR; | ||
+ | }; | ||
+ | void surf (Input IN, inout SurfaceOutput o) { | ||
+ | o.Albedo = 1; | ||
+ | } | ||
+ | ENDCG | ||
+ | } | ||
+ | Fallback " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Textured Diffuse, 텍스쳐를 사용한 Diffuse ===== | ||
+ | |||
+ | * 텍스쳐 프로퍼티 추가 | ||
+ | * Input 구조체에 텍스쳐 UV를 넘겨 받기 위한 구조체로 설정 | ||
+ | * **uv_**로 시작되는 부분 주목 | ||
+ | * 출력값에는 rgb값을 Albedo에 입력 | ||
+ | |||
+ | < | ||
+ | Shader " | ||
+ | Properties { | ||
+ | // 텍스쳐 프로퍼티 추가 | ||
+ | _MainTex (" | ||
+ | } | ||
+ | | ||
+ | SubShader { | ||
+ | Tags { " | ||
+ | CGPROGRAM | ||
+ | #pragma surface surf Lambert | ||
+ | | ||
+ | // 텍스쳐 UI를 받는다. uv_로 시작되는 부분에 주목. | ||
+ | struct Input { | ||
+ | float2 uv_MainTex; | ||
+ | }; | ||
+ | | ||
+ | sampler2D _MainTex; | ||
+ | | ||
+ | void surf (Input IN, inout SurfaceOutput o) { | ||
+ | // Albedo에 색상값을 넣는다. | ||
+ | o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; | ||
+ | } | ||
+ | ENDCG | ||
+ | } | ||
+ | Fallback " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Texture Bump Diffuse ===== | ||
+ | |||
+ | Bump 맵을 받아서, surfaceFunction에서 사용하는 방법 확이 | ||
+ | |||
+ | < | ||
+ | Shader " | ||
+ | Properties { | ||
+ | _MainTex (" | ||
+ | // 범프맵 텍스쳐 프로퍼티 추가 | ||
+ | _BumpMap (" | ||
+ | } | ||
+ | SubShader { | ||
+ | Tags { " | ||
+ | CGPROGRAM | ||
+ | #pragma surface surf Lambert | ||
+ | struct Input { | ||
+ | float2 uv_MainTex; | ||
+ | float2 uv_BumpMap; // Bump맵 UV 좌표를 입력 값으로 받는다 | ||
+ | }; | ||
+ | | ||
+ | sampler2D _MainTex; | ||
+ | sampler2D _BumpMap; // 범프맵을 저장할 텍스쳐 샘플(변수) | ||
+ | | ||
+ | void surf (Input IN, inout SurfaceOutput o) { | ||
+ | o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; | ||
+ | // 범프맵을 적용한다. | ||
+ | o.Normal = UnpackNormal( tex2D(_BumpMap, | ||
+ | } | ||
+ | ENDCG | ||
+ | } | ||
+ | Fallback " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Rim Lighting 적용 ===== | ||
+ | |||
+ | * 림라이트 : {{language: | ||
+ | |||
+ | < | ||
+ | | ||
+ | Properties { | ||
+ | _MainTex (" | ||
+ | // 림라이트 프로퍼티 | ||
+ | _RimColor (" | ||
+ | _RimPower (" | ||
+ | } | ||
+ | SubShader { | ||
+ | Tags { " | ||
+ | CGPROGRAM | ||
+ | #pragma surface surf Lambert | ||
+ | struct Input { | ||
+ | float2 uv_MainTex; float2 uv_BumpMap; | ||
+ | // 림라이트 계산을 위한 뷰Dir | ||
+ | float3 viewDir; | ||
+ | }; | ||
+ | |||
+ | sampler2D _MainTex; sampler2D _BumpMap; | ||
+ | // 림라이트 프로퍼티 변수 | ||
+ | float4 _RimColor; | ||
+ | float _RimPower; | ||
+ | |||
+ | void surf (Input IN, inout SurfaceOutput o) { | ||
+ | o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; | ||
+ | o.Normal = UnpackNormal( tex2D(_BumpMap, | ||
+ | |||
+ | // 림라이트 연산!! | ||
+ | half rim = 1.0 - saturate( dot( normalize(IN.viewDir), | ||
+ | o.Emission = _RimColor.rgb * pow(rim, _RimPower); | ||
+ | } | ||
+ | ENDCG | ||
+ | } | ||
+ | Fallback " | ||
+ | } | ||
+ | </ |