본문 바로가기

유니티/쉐이더

[Unity Shader] 쉐이더 코드 설명 : Properties, SurfaceOutputstandard

쉐이더 코드

예시로 설명할 쉐이더 코드입니다.

스탠다드 서피스 쉐이더로 만들었습니다.


Properties

쉐이더 인터페이스를 만들어줍니다.

인스펙터 창에 표시됩니다. 끝에 ;를 붙이지 않습니다.

- 순서대로 변수명, display name, 형식, 초기값 입니다.

- 변수명: 밑줄이 필수는 아니지만 입력받았다는 의미로 자주 쓰입니다.

- display name: 인스펙터창에 표시 될 이름입니다.

- 형식: 어떤 종료의 인터페이스를 만들지에 대한 내용입니다.

- 초기값: 쉐이더가 처음 만들어질 때 초기값입니다.

인터페이스 종류

오른쪽처럼 코드를 작성하면 인스펙터 창에 왼쪽처럼 표시됩니다.


SubShader

Tags

RenderType 태그

씬을 렌더링하기 위한 정보를 얻으려고 사용되는 리플레이스드 쉐이더(Replaced Shader)를 위한 설정입니다.

씬을 렌더링하기 위해 필수적입니다. 쉐이더의 속성에 따른 정확한 Tag를 넣어줘야합니다.

 

종류

  • Opaque: 대부분의 불투명 쉐이더에서 사용됩니다.
  • Transparent: 대부분의 알파 블렌딩 쉐이더에서 사용됩니다.
  • TransparentCutOut: 알파테스팅 쉐이더에서 사용됩니다.
  • Background: 스카이박스 쉐이더에서 사용됩니다.
  • Overlay: GUI 텍스쳐, 후광(Halo), 플레어 쉐이더(Flare Shader)에서 사용됩니다.
  • TreeOpaque: 터레인에 사용되는 나무엔진의 줄기 부분에 사용됩니다.
  • TreeTransparentCutout: 터레인에 사용되는 나무 엔진의 나뭇잎 부분에 사용됩니다.
  • TreeBillboard: 터레인에 사용되는 나무 엔진의 빌보드에 사용됩니다.
  • Grass: 터레인에 사용되는 나무 엔진의 풀에 사용됩니다.
  • GrassBillboard: 터레인에 사용되는 나무 엔진의 풀의 빌보드에 사용됩니다.

Queue(렌더 큐) 태그

렌더링 순서에 대한 태그입니다.

큐를 사용해 오브젝트를 그리는 순서를 결정할 수 있습니다.

일반적으로 불투명 - 투명 순이지만, 지정된 렌더링 큐는 조금 더 있습니다.

 

종류

  • Background: 다른 것들보다 먼저 렌더링 됩니다. 배경으로 있어야 할 것들을 위해 사용됩니다.
  • Geometry(defalt): 대부분의 불투명 오브젝트가 사용합니다. 큐를 적지 않으면 이것으로 지정됩니다.
  • AlphaTest: 알파 테스트 지오메트리에 사용합니다. 
  • Transparent: Geometry와 AlphaTest 후에 뒤부터 순서대로 렌더링 됩니다.
    알파 블렌딩하는 것은 여기에 있어야 합니다.
  • Overlay: 오버레이 효과를 위해 사용됩니다. 마지막으로 렌더링하는 것은 여기에 있어야 합니다.

LOD

쉐이더 LOD는 거리에 따라 최적화 되는 것과는 조금 다릅니다.

환경설정에 따라 저사양 옵션에서 낮은 사양의 쉐이더가 돌아가도록 조절할 수 있습니다.

고사양 설정
저사양 설정

기본적으로 유니티에 들어있는 내장 쉐이더에서 설정된 LOD를 기준으로 작성하면 좋습니다.

  • 100 - VertexLit 종류
  • 150 - Decal, Reflective VertexLit
  • 200(기본) - Diffuse
  • 250 - Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit
  • 300 - BUmped, Specular
  • 400 - Bumped Specular
  • 500 - Parallax
  • 600 - Parallax Specular

CGPROGRAM - ENDCG

이 부분은 유니티 자체 스크립트가 아닌 CG언어를 이용해서 쉐이더를 짜는 부분입니다.

유니티 서피스 쉐이더는 스크립트와 쉐이더 언어를 섞어서 사용합니다.


#pragma surface surf Standard fullforwardshadows

서피스 쉐이더에 대한 정보를 적어둡니다.

https://docs.unity3d.com/kr/530/Manual/SL-SurfaceShaders.html

#pragma surface surfaceFunction lightModel [optionalparams]

  • surface: Surface Shaders라는 것을 알려줍니다.
  • surfaceFunction: 함수 이름입니다.
  • lightModel: 사용하는 라이팅 모델을 적어줍니다. 직접 모델을 작성할 수도 있습니다.
  • optionparams: 옵션 파라메터입니다. 알파, 그림자 등을 설정합니다.

lightModel 종류

  • Lambert
  • BlinnPhong
  • Standard
  • StandardSpecular

옵션 파라미터

알파 옵션

  • alpha or alpha:auto: 일반적인 조명 함수에서는 알파블렌딩,
                               물리 기반 조명 함수에서는 프리멀티드 블렌딩으로 작동합니다.
  • alpha:blend: 알파 블렌딩을 가동시킵니다.
  • alpha:fade: 전통적인 반투명(알파 블렌딩)을 가동시킵니다.
  • alpha:premul: 프리멀티드 블렌딩을 가동합니다.
  • (추가로 alphatest:VariableName, keepalpha, decal:add, decal:blend 등이 있습니다.)

버텍스 데이터 / 파이널 컬러 조절

  • vertex:VertexFunction: 커스텀 버텍스 수정 기능.
  • finalcolor:ColorFunction: 사용자 정의의 최종 색상 수정자.
  • finalgbuffer:ColorFunction: G 버퍼 내용을 수정하기 위한 커스텀 디퍼드 패스.
  • finalprepass:ColorFunction: Deferred 렌더링을 위한 커스텀 프리패스 베이스 패스.

그림자와 터셀레이션

  • addshadow: 쉐도우 캐스터 패스를 추가합니다.
  • fullforwardshadows: 포워드 렌더링 패스에서 모든 조명에서 그림자가 생기게 할 때 사용합니다.
  • tessellate:TessFunction: DX11 GPU 테셀레이션을 사용합니다. 자세한 내용 -> Surface Shader Tessellation

코드 생성 옵션

기본적으로 서피스 쉐이더가 생성되면, 모든 경우의 라이팅/그림자/라이트맵에 대응하기 위해 자동적으로 준비해놓고 있습니다. 이런 옵션들이 필요없으면 아래 옵션들로 삭제하거나 최적화할 수 있습니다.

  • noshadow: 모든 그림자 받기(shadow receiving)를 비활성화합니다.
  • noambient: 앰비언트(Ambient) 라이팅 또는  라이트 프로브(Light Probe)를 적용하지 않습니다.
  • novertexlights: Forward 렌더링에서 라이트 프로브, 버텍스 라이트를 적용하지 않습니다.
  • nolightmap: 모든 라이트맵 지원을 비활성화합니다.
  • nodynlightmap: 실시간 동적 전역 조명(runtime dynamic global illumination) 지원을 비활성화합니다.
  • nodirlightmap: 디렉셔널 라이트맵 지원을 비활성화합니다.
  • nofog: 유니티 내장 포그 기능을 지원하지 않습니다.
  • nometa: 메타 패스를 만들지 않습니다.
  • noforwardadd: 포워드 렌더링 추가 패스를 비활성화 합니다.

#pragma target

어떤 버전의 쉐이더 모델로 컴파일할지 지정합니다.

  • #pragma target 2.0 - 기본 세팅입니다. 아무것도 쓰지 않으면 2.0으로 설정됩니다.

자세한 설명

https://docs.unity3d.com/kr/2018.4/Manual/SL-ShaderCompileTargets.html

 

셰이더 컴파일 타겟 레벨 - Unity 매뉴얼

표면 셰이더 또는 일반 셰이더 프로그램으로 작성할 때 HLSL 소스를 다른 “셰이더 모델”로 컴파일할 수 있습니다. 더 최신 GPU 기능을 사용하려면 더 높은 버전의 셰이더 컴파일 타겟을 사용해

docs.unity3d.com


외부 입력 변수 사용

Properties에서 만든 변수를 사용하려면 CGPROGRAM - ENDCG 사이에 선언을 해줘야 합니다.

Properties에 적어둔 인터페이스에 맞게 float, float4, sampler2D를 받아줍니다.

floathalf, fixed로 바꿔 쓸 수 있습니다.

 

데이터 타입

  • float: 가장 높은 정밀도로 32비트를 사용합니다. (월드 스페이스 포지션, 스칼라 계산 등에서 사용됩니다.)
  • half: 16비트를 사용합니다. (짧은 벡터, 디렉션 HDR컬러 등에 사용)
  • fixed: 11비트를 사용합니다. (일반적인 컬러, 간단한 계산을 위해 사용)
  • int: 루프 카운터나 행렬의 인수 등에서 사용됩니다.

Struct Input

엔진으로부터 받아와야 할 데이터들이 있습니다.

텍스쳐의 UV좌표를 가져오기 위해 "uv"뒤에 텍스처 이름이 오는 형태로 만들어줍니다.

그 외에 다음 값을 입력 구조에 입력할 수 있습니다.

  • float3 viewDir - 뷰 방향입니다. 시차 효과, 림 라이팅 등에서 사용됩니다.
  • float4 color:COLOR - 보간된 버텍스 컬러입니다.
  • float4 screenPos - 스크린 스페이스 위치입니다.
  • float3 worldPos - 월드 공간상의 위치입니다.
  • float3 worldRefl - 서피스 쉐이더에서 o.Normal이 작성되지 않은 경우, 월드 리플렉션 벡터를 포함합니다.
  • float3 worldNormal - 서피스 쉐이더에서 o.Normal이 작성되지 않은 경우 월드 노멀 벡터를 포함합니다.

void surf

Input IN

위에 적어둔 Input 구조체에서 값을 가져옵니다.

 

SurfaceOutputStandard o

구조체 안에 알맞은 값을 넣어주면 결과가 나오게 됩니다.

이 구조체는 다음과 같이 정의되어 있습니다.

  • fixed3 Albedo
  • fixed3 Normal
  • fixed3 Emission
  • half Metallic
  • half Smoothness
  • half Occlusion
  • half Alpha