Skip to content

Unity Shader

JungSu Kim edited this page Jan 26, 2016 · 4 revisions

Reference

Tools

What is Shader?

  • 컴퓨터에게 어떻게 특별하거나 유니크하게 사물(something)을 그릴지 알려(tell)주는 프로그램
  • A definition in layman's terms might be given as "a program that tells a computer how to draw something in a specific and unique way". from Wikipedia

유니티 쉐이더 구조(Unity Shader Structure)

유니티 멀티플랫폼 아키텍쳐(Unity Multi Platform Architecture)

  • 유니티는 멀티플랫폼 엔진이기 때문에 CPU, GPU 모두 멀티 플랫폼에서 동작하기 위한 구조를 가지고 있음
  • 쉐이더의 경우 ShaderLab이라는 추상 스크립트 언어를 사용하여 멀티 플랫폼에서 동작하는 쉐이더 코드를 작업할 수 있음

쉐이더 스크립트 Shader Script(ShaderLab)

  • Abstract shader script layer for multiplatform system

  • Multi-Device

    • Supports old mobile hardwares (DX 7/8)
    • Supports modern mobile hardwares (DX9, Shader Model 2)
    • Supports PC and Console hardwares (Shader Model 3)
    • Supports Extreme PC hardwares (DX11, Shader Model 5)
  • Multi-Library

    • OpenGL
    • OpenGL E/S
    • DirectX
  • Multi-Language

    • GLSL
    • Cg
    • HLSL
  • 기본 구조

Shader "Custom/Simple" {
    Properties
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
 
    SubShader
    {
        Tags { "Queue" = "Geometry + 1" }
        Pass
        {
            SetTexture [_MainTex] { combine texture }
        }
    }
 
    FallBack "Diffuse"
}
  • Shader Lab Syntax - Properties

  • 유니티 인스펙터에서 쉐이더에 전달할 다양한 값을 사용자가 편리하게 설정할 수 있도록 만든 인터페이스

    • Float textbox
    • Float Range Slides
    • Vector4 textboxes
    • Color Picker
    • 2D Texture (POT)
    • 2D Texture (NPOT)
    • Cube Texture
  • Shader Lab Syntax - SubShader

  • 유니티는 하나의 쉐이더에서 다양한 하드웨어를 지원하기 위해 서브쉐이더라는 구문을 제공함

  • 가장 위에 정의된 쉐이더부터 실행되며, 하드웨어와 호환이 안되면 다음 서브쉐이더가 실행됨

  • 모든 쉐이더 구동에 실패하면 폴백(FallBack)에 정의된 쉐이더가 대신 실행됨

SubShader
{
    // First Priority Shader Code
    ( Designed for high-level PC )
}
 
SubShader
{
    // Second Priority Shader Code
    ( Designed for mid-level PC )
}
 
SubShader
{
    // Third Priority Shader Code
    ( Designed for low-level PC )
}
 
// Alternative Shader Code
FallBack "VertextLit"
  • SubShader Format - Tag

  • 서브쉐이더의 구조를 크게 렌더링의 실행 순서와 설정을 지정하는 태그(Tag) 구문과 렌더링을 표현하는 패스(Pass)로 나누어 짐

  • 유니티는 0부터 5000번까지 렌더링 순서를 지정하게 되는데 숫자가 아닌 이름을 기반으로 이 순서를 지정하게 됨

    • Background = 1000
    • Geometry = 2000
    • AlphaTest = 2450
    • Transparent = 3000
    • Overlay = 4000
    • 예를들어 Tags { "Queue" = "Geometry+1" }은 Geometry(2000)에 1을 더한 2001을 의미함
  • SubShader Format - Pass

  • 지오메트리(Geometry)의 렌더링 방법을 지정하는 구문

  • 패스 구문은 여러개를 사용하여 이전 패스에서 나온 결과물을 기반으로 계속 추가적인 표현을 할 수 있음

  • 패스 구문을 통해 물체의 렌더링이 수행되는데, 이 렌더링은 여러분들이 카메라에서 지정한 렌더링 방법을 통해서 수행됨

  • 이러한 렌더링 방법을 유니티에서는 이를 렌더링 패스(Rendering Path)라고 함

    • Pass Tag : 렌더링 설정을 지정
    • Render State : GPU의 렌더 스테이트를 설정
    • 실제 쉐이더 코드 조각

유니티 렌더링 파이프라인(Unity Rendering Pipeline)

버텍스 릿(Vertex Lit)

  • 오래된 하드웨어에서 동작하도록 설계됨(Designed for old hardware)
  • Direct X 7/8 compatible
  • Final pixel is calculated by interpolation between vertices
  • 장점
    • Simple and Fast
    • No overhead in CPU side
    • Useful to lightmapping in mobile
  • 단점
    • Cookie, Lightprobe, Shadow are not available
    • Number of light has limit
    • Can't express pre-pixel expression. ex) Normal mapping
  • 버텍스 릿은 하드웨어 혹은 에디터 설정에 따라 3가지 중 하나의 과정이 진행됨
  • 어떤 과정이 사용될지는 유니티가 자동으로 알아서 설정해 줌
    • Vertex Pass
    • Just simple vertex lit mode
    • No lightmap support
    • VertexLM Pass
    • For old smartphone
    • Encodes lightmap by Double LDR
    • VertexLMRGBM Pass
    • For modern smartphone
    • Encodes lightmap by RGBM

포워드(Forward)

  • 가장 일반적인 렌더링 방법(Common rendering pipeline)
  • DirectX 9
  • Per-pixel calculation
  • 장점
    • Lightprobe, cookie, shadow are available
    • Can render object by independent lighting model
  • 단점
    • Lighting computation increases linearly by number of lights
    • Only directional light support shadow
    • Unity supports additional shader keyword (fullforwardshadows)
  • 포워드 방식의 가장 중요한 점은 중요한 빛과 중요하지 않은 빛을 구분하는 일임
  • 이는 라이트 컴포넌트 설정에서 직접 지정을 할 수 있는데, 중요한 빛은 가장 인텐시티(Intensity)가 높은 디렉셔널 라이트(Directional Light) 임
  • 그로기 라이트 컴포넌트에서 Render Mode가 Important로 설정된 빛임
  • 중요한 빛은 품질설정에서 Pixel Light Count에 설정된 수만큼 지정할 수 있으며, 나머지는 안 중요한 빛이 됨
  • 포워드 방식은 빛의 개수에 따라 계산량이 증가하기 때문에, 이를 설정하는 것은 최적화에 큰 영향을 줌
  • 품질 설정의 픽셀 라이트 카운트(Pixel Light Count) 설정이 중요한 빛의 수를 지정하는 일인데, 유니티는 중요한 빛은 공들여서 렌더링하고, 안 중요한 빛은 정말 대충 렌더링 함
    • Light Setting in Forward Pipeline
    • Important Light
    • The largest intensity directional light
    • Uses in per-pixel calculation
    • Pixel Light Count
    • Not Important Light
    • Next 4 lights use for per-vertex calculation
    • Rest lights are approximated by SH(Spherical Harmonics)

디퍼드 렌더링(Deferred Lighting)

  • 최신 렌더링 방법(Modern rendering pipeline)
  • 장점
    • No number of light limit
    • Useful to complex scene rendering at once
  • 단점
    • Mobile doesn't support this currently
    • Supports only Blinn-Phong lighting model
    • Doesn't support transparent object
    • Only forward supports transparent objects

유니티 쉐이더 프로그래밍(Unity Shader Programming)

고정 함수 프로그램(Fixed Function Program)

  • 버텍스 릿 렌더링 방식에 적합한 프로그램 방법(Mataches vertex lit rendering pipeline)
    • Shader model 1.x
    • Provides special keywords for rendering operation
  • 고급 언어를 통해서 프로그래밍이 불가능 함
  • 심플하지만 빠르지 때문에, 모바일에서는 퀄리티에만 문제가 없다면 성능을 위해 사용을 고려해보는 것도 좋음

버텍스/프래그먼트 프로그램(Vertex / Fragment Program)

  • 일반적으로 많이 사용하는 쉐이더 프로그래밍(Command shader programming)
    • Unity provides keywords for coding snippet area
    • CGPROGRAM, GLSLPROGRAM
  • 유니티는 두 가지 언어를 모두 지원하지만, 멀티플랫폼 쉐이더를 만들려도 한다면 Cg를 사용해야 함
  • 쉐이더랩 문법으로 쉐이더 코드를 Cg로 만들어주면, 최종 HLSL 쉐이더 코드가 만들어이제 되고, 내부 변환기에 의해서 HLSL코드를 GLSL로 자동으로 변환됨
  • 이렇게 변환된 GLSL 코드는 유니티 GLSL 옵티마이저를 통해 최적화되어 최종 쉐이더 코드가 완성됨
  • 따라서 Cg로 짠 쉐이더 코드가 OpenGL에서 동작하는게 가능해 짐

서피스 쉐이더 프로그램(Surface Shader Program)

  • 복잡한 쉐이더 코드를 심플하게 하기 위한 프로그램
    • Simplified version of vertex/fragment program by unit way.
    • Automatically converts vertex/fragment code for various situations.
  • 서피스 쉐이더가 단순한 이유는 엔진에서 자동으로 버텍스/프래그먼트 쉐이더 코드로 변환해주기 때문임
  • Cg나 HLSL 쉐이더 코드를 이용해서 코드를 작성하면 됨
    • Surface Shader Program => Generate by Unity Engine => Vertex/Fragment Program
  • 기본구조
    • Surface Shader Program = Surface Code + Light Code

서피스 쉐이더 작성(Writing Surface Shaders)

작업순서(Work Flow)

  1. Create > Shader > Standard Surface Shader / Unlit Shader / Image Effect Shader / Compute Shader
  2. Write code in surf function
  3. Attach material

서피스 출력 구조(Surface Output Structure)

SurfaceOutput (<= Unity4)
SurfaceOutputStandard or SurfaceOutputStandardSpecular (>= Unity5)
Surface Output
// SurfaceOutput (>= Unity4)
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
};
 
// SurfaceOutputStandard (>= Unity5)
struct SurfaceOutputStandard
{
    fixed3 Albedo;      // base (diffuse or specular) color
    fixed3 Normal;      // tangent space normal, if written
    half3 Emission;
    half Metallic;      // 0=non-metal, 1=metal
    half Smoothness;    // 0=rough, 1=smooth
    half Occlusion;     // occlusion (default 1)
    fixed Alpha;        // alpha for transparencies
};
 
// SurfaceOutputStandardSpecular (>= Unity5)
struct SurfaceOutputStandardSpecular
{
    fixed3 Albedo;      // diffuse color
    fixed3 Specular;    // specular color
    fixed3 Normal;      // tangent space normal, if written
    half3 Emission;
    half Smoothness;    // 0=rough, 1=smooth
    half Occlusion;     // occlusion (default 1)
    fixed Alpha;        // alpha for transparencies
};

서피스 쉐이더 컴파일 방법지정(Surface Shader compile directives)

  • Surface shader is placed inside CGPROGRAM ~~ ENDCG block
  • It must be placed inside SubShader block, not inside Pass. Surface shader will compile into multiple passes itself
  • It uses #pragma surface ... directive to indicate it's a surface shader
  • #progma surface surfaceFunction lightModel [optional|params]

필수 파라미터(Required parameters)

  • surfaceFunction
  • lightModel

옵션 파라미터(Optional parameters)

  • Transparency and alpha testing

    • alpha or alpha:auto
    • alpha:fade
    • alpha:premul
    • alphatest:VariableName
    • keepalpha
    • decal:add
    • decal:blend
  • Custom modifier functions

    • vertex:VertexFunction
    • finalcolor:ColorFunction
  • Shadows and Tessellation

    • addshadow
    • fullforwardshadows
    • tessellation:TessFunction
  • Code generation options

    • exclude_path:deferred, exclude_path:forward, exclude_path:prepass
    • noshadow
    • noambient
    • novertexlights
    • nolightmap
    • nodynlightmap
    • nodirlightmap
    • nofog
    • nometa
    • noforwardadd
  • Miscellaneous options

    • softvegetation
    • interpolateview
    • halfsview
    • approxview
    • dualforward

서피스 쉐이더 입력 구조(Surface Shader input structure)

  • float3 viewDir
  • float4 with COLOR semantic
  • float4 screenPos
  • float3 worldPos
  • float3 worldRefl
  • float3 worldNormal
  • float3 worldRefl; INTERNAL_DATA
  • float3 worldNormal; INTERNAL_DATA

Surface Shader Examples

머테리얼과 쉐이더(Material and Shader)

Blue Car : Car Texture + Custom/Bodywork Shader + Blue car Material Red Car : Car Texture + Custom/Bodywork Shader + Red car Material Wheel : Car Texture + Standard Shader + Wheel Material

스탠다드 쉐이더(Standard Shader)

  • 유니티5에서는 스탠다드 쉐이더라고 불리는 새로운 타입의 내장 쉐이더를 도입함(Unity 5 introduces a new type of built-in shader called the Standard Shader.)
  • 스탠다드 쉐이더에는 물리적 기반 쉐이더라는 훨씬 더 고급스러운 조명 모델을 통합함(The Standard Shader also incorporates a much more advanced lighting model called PBS(Physically Based Shading).)
  • 물리기반 쉐이딩(Physically Based Shading via PBS)
    • Energy conservation
    • HDR(High Dynamic Range)

컨텍스트와 컨텐트(The Context and the Content)

  • When thinking about lighting in Unity 5, it is handy to divide concepts into what we call the Context, which is information on the lighting that exists in the scene (coming from the skybox, lights and shadows, GI, etc) and the Content, which is usually authored directly by you and describes what is in the environment (materials, geometries, animation, etc).
  • Most times the distinction will be obvious, but not always.
  • For instance, a skybox is graphical Content, that can control some of the lighting Context of your scene.

컨텍스트(The Context)

The Default Lighting Context Skyboxes Global Illumination 컨텐트(The Content) The Material Editor

메탈릭 vs 스펙큘러 워크플로우(Metalic vs Specular Workflow)

  • 스탠다드 쉐이더를 사용하여 메터리얼을 생성할 때 Standard와 Standard (Specular Setup) 두가지중에서 적절한것을 선택할 수 있다(When creating a material using the Standard shader you will have the choice of using one of two flavours, “Standard” and “Standard (Specular setup)”.)

  • Standard: The shader exposes a “metallic” value that states whether the material is metallic or not. In the case of a metallic material, the Albedo color will control the color of your specular reflection and most light will be reflected as specular reflections. Non metallic materials will have specular reflections that are the same color as the incoming light and will barely reflect when looking at the surface face-on.

  • Standard (Specular setup): Choose this shader for the classic approach. A Specular color is used to control the color and strength of specular reflections in the material. This makes it possible to have a specular reflection of a different color than the diffuse reflection for instance.

머테리얼 파라미터(Material Parameters)

머테리얼 차트(Material Charts)

메탈릭 설정을 위한 차트(Reference Chart for Metallic settings)

  • Standard 쉐이더의 Metallic

스펙큘러 설정을 위한 차트(Reference Chart for Specular settings)

  • Standard (Specular setup) 쉐이더의 Specular

스크립트를 통해서 머테리얼 속성정보를 접근하거나 수정하는 방법(Accessing and Modifying Material parameters vis script)

빌트인 쉐이더(Built-in Shaders)

  • http://egloos.zum.com/chulin28ho/v/5526644

  • Mobile / Background 쉐이더

    • 라이팅 영향도 받지 않고 단지 텍스쳐만 출력하는 초 간단한 쉐이더입니다. ZWrite도 하지 않음
    • 즉 이것은 말그대로 원거리 배경용 쉐이더.
    • 스카이박스는 아니고 멀리 보이는 원경 한 장짜리 이미지 같은 경우에 쓸 수 있는 쉐이더입니다. 0.5g
  • Mobile / Bumped Specular

    • 보이는 그대로, 모바일용으로 만든 스페큘러가 포함된 노말맵 사용 쉐이더입니다.
    • 좀 더 간략화 된 특징을 가지고 있는데,
      • 메인 칼라나 스페큘러 칼라를 지정할 수 없습니다.
      • 스페큘러에서 사용하는 라이트 방향은 버텍스에서 대충 받아서 옵니다.
      • 노말맵의 타일링이나 옵셋은 베이스 텍스쳐의 설정값을 따릅니다.
      • 디퍼드 라이팅을 지원하지 않습니다. 라이트맵도 지원하지 않습니다.
      • 디렉셔널 라이트 1개만 지원되고, 나머지 라이트들은 버텍스 라이트나 구면조화 라이트로 작동합니다.
    • 일반적인 범프/스페큘러보다는 좀 가볍게 되어 있긴 합니다만, 그래도 노말맵 연산이 되므로 모바일에서 함부로 사용해서는 곤란합니다. 3g
  • Mobile / Bumped Specular (1 Directional Light) 위의 범프 스페큘러 쉐이더와 동일하지만, 단 한가지만 다릅니다.

  • 디렉셔널 라이트 1개만 지원되고, 나머지 라이트는 무시됩니다. 즉 위의 쉐이더보다 아주 약간 가볍다고 할 수 있습니다. 2.7g
  • Mobile / Particles / Additive 이전에 사용하던 일반적인 Add 쉐이더와 거의 같으며, 다른점은 다음과 같습니다.
  • Tint Color가 없습니다.
  • 스무스 파티클 옵션이 없습니다.
  • 알파테스트가 없습니다 (전에는 있었나?)
  • 칼라마스크가 없습니다. 사실상 그 외는 동일하게 제작되어 있습니다. 좀 더 가벼워진 버전이라고 할 수 있습니다. 1.5g
  • Mobile / Particles / Alpha Blended 이전에 사용하던 알파 블렌딩 쉐이더와 동일하며, 다른점은 위의 Add 쉐이더와 같습니다.

  • Mobile / Particles / Multiply 이전에 사용하던 멀티 쉐이더와 동일하며, 다른점은 아래와 같습니다.

  • 스무스 파티클 옵션이 없습니다.
  • 알파테스트가 없습니다
  • 칼라마스크가 없습니다. 역시 이전에 사용하던 쉐이더와 동일하되 약간씩 가볍게 제작된 것 외에 차이가 없습니다 .
  • Mobile / Particles / VertexLit Blended 이전에 사용하던 버텍스라이트 블렌디드 쉐이더와 동일하며, 다른점은 아래와 같습니다.
  • 알파테스트가 없습니다.
  • 칼라마스크가 없습니다. 이하 상동
  • Mobile / Skybox 이전에 사용하던 스카이박스 쉐이더처럼 6면의 텍스쳐를 집어 넣습니다. 그렇지만 단지 Tint Color 만이 제거되어 있습니다. 사실상 거의 같지만 아주 살짝 가벼운 정도입니다. 대부분, 기능들을 꼭 제거할만큼 효과가 커 보이지 않습니다.

  • Mobile / VertexLit 기본적인 버텍스 칼라 쉐이더에서 일부 기능이 삭제된 쉐이더입니다.

  • per material 칼라가 삭제되어 있습니다.
  • 스페큘러가 없습니다.
  • emission이 없습니다. 그 외는 동일합니다. 사실상 모바일 쉐이더라고 해서 특별하게 만들어 진 것은 없으며, 단지 기능이 몇 개씩 삭제된 정도입니다. 즉 일반 게임용 쉐이더도 '가벼운 쉐이더 라면' 모바일에서도 대부분 똑같이 돌아가며, 사용에 제약이 없습니다. 이펙트 쉐이더들도 모바일용으로 컨버팅해 놓도록 해야겠네요...

하드웨어 그래픽 호환성과 에뮬레이션(Graphics Hardware Capabilities and Emulation)

추가적으로 확인할 것들

Clone this wiki locally