48
Artist를 위한 Unity3D Surface Shader 이상윤 http://illu.tistory.com

Unity Surface Shader for Artist 01

Embed Size (px)

Citation preview

Artist를 위한 Unity3D Surface Shader

이상윤 http://illu.tistory.com

01. Shader 기본 이론과 Unity3D

Shader?

Shader Study의 목적

Shader 코드의작성 및 활용/응용

3D Graphics 기본 이론의 이해

프로젝트 진행에 대한 이해

협조할 사항에 대해 명확한 이해

기초 Unity Shader 작성

셰이더, 쉐이더…

화면에 어떻게 그릴것인지 정의된 코드(프로그래밍된 코드로 볼수도 있음)

색의 농담, 색조, 명암 효과'등을 주다라는 뜻을 가진 shade에서 접미사 –er을 덧붙여 shader.

결국 화면에 배열된 픽셀들이 어떤 색으로 그려질지를 정의한 코드(RGBA 값을 섞어서 각 픽셀에 따라 어

떤 색이 들어갈지를 결정하게 된다)

Shader 언어의 종류

- HLSL(High Level Shader Language) : DX(DirectX)기반의 Shader 언어

- GLSL(OpenGL Shader Language) : OpenGL 기반의 Shader 언어

- Cg : Nvidia에서 만들어진 Shader 언어

- OpenGL ES(OpenGL Embedded System) : 모바일 포맷을 위한 OpenGL의 변형(즉 GLSL을 기반으로 모바일 셰

이더를 작성하게 된다)

셰이더 프로그래밍 입문.

그래픽 프로그래머 김포프님 책

으로 많이 보는 서적.

기초부터 매우 자세하게 개념적

으로 정리해 설명이 되어있다. 일

단 싸다(정가 22,000원)

Cg로 배우는 셰이더 프로그래밍

Nvidia에서 나온 Cg Shader

Tutorial 번역서(nvidia 홈페이지

에 내용 다 나와있음)

더 쌈(정가 18,000원)

GPU Rendering pipeline

Local Position World Position View PositionBack space

Cull

Lighting Clipping Projection

RasterizeTexture mapping

Vertex Shader

Vertex shader와 pixel Shader

Pixel ShaderResterize

Shader에 사용되는 공간 – Local space

김용일의 초보 셰이더 강좌 - http://cafe.naver.com/cookingani/4838

Local Space, Object Space, 물체

공간 다 같은 의미로 사용

오브젝트 별로 가지고 있는 자기만

의 공간

World space

김용일의 초보 셰이더 강좌 - http://cafe.naver.com/cookingani/4838

월드 축을 기준으로 계산하는 공간.

각각 개별의 공간을 가지는 것이 아

닌 월드 공간 기준으로 값을 가지게

된다.

View space

김용일의 초보 셰이더 강좌 - http://cafe.naver.com/cookingani/4838

뷰공간 혹은 카메라 공간

물체를 보기위해 기준이 되는 시각

(카메라)을 기준으로 계산한 좌표

Projection space

김용일의 초보 셰이더 강좌 - http://cafe.naver.com/cookingani/4838

투영공간 혹은 프로젝션 공간

눈이라면 망막에 그려지는, PC라면

화면(모니터)에 그려지는 공간

Tangent space

탄젠트 공간 혹은 접선 공간

표면의 점(정점X, 텍셀O)을 정의 하

는 3차원 좌표계.

수직으로 뻗은 선이 노멀, 접선(기울

기 값)은 바이 노멀, 접선과 노멀값을

외적한 값을 탄젠트 노멀.(벡터의 외

적은 벡터)

노멀 매핑 계산에서 사용.혹시 추가적인 내용이 궁금하다면.. : http://blog.naver.com/sorkelf/40157218010

공간 변환은 행렬로…

사놓고 보통 집합이랑 행렬까지는 보자나요…

오브젝트 행렬변환

float4x4 gWorldMatrix;

float4x4 gViewMatrix;

float4x4 gProjectionMatrix;

Output.mPosition = mul(Input.mPosition, gWorldMatrix);

Output.mPosition = mul(Input.mPosition, gViewMatrix);

Output.mPosition = mul(Input.mPosition, gProjectionMatrix);

-HLSL 행렬변환 코드

void C4E1v_transform(float4 position : POSiTION,

out float4 oPosition : POSITION,

uniform float4x4 modelViewProj)

{

oPosition = mul(modelViewProj, position);

}

- Cg 행렬변환 코드

Unity ShaderLab

Fixed/Function Shader

- 가볍고 빠르다. 오래된 하드웨어와 호환이 좋음

- 키워드 구성으로 사용이 단순

- 제약이 많음

Vertex and Fragment Shader

- CG 기반 셰이더 언어.

- 버텍스, 픽셀 셰이더 제어

- 셰이더 관련 다양한 매크로 및 함수 제공

- 기존의 셰이더 언어체계와 가장 유사

- GLSL 셰이더도 사용가능.

필요할 경우에만 GLSL로 작성하라고 가이드 함.

Surface Shader

- Matrix 변환 없음.(행렬 안해도 됨…!!! 아싸~!)

- 전처리가 대부분 되어있기 때문에 코드가 짧고 살펴

보기 편하다.

- 스크립트 기반이므로 구조만 파악하면 수정 및 작성

이 수월하다.

공부 안된다고 쓰지 말라고 하는 분들이 많음…

구현에 제약이 생기므로 결국은 fragement 구조로 짜는 경우가 생김.

프로그래밍 언어

저수준 언어어셈블리 : 하드웨어 직접 제어 가능.

고수준 언어

포트란, Java, C, C++, C# : 사람 언어와 가까워짐. 컴파일을 거쳐 실행

기계어 : 0,1 만 존재.. CPU랑 대화 가능…

Compile

HLSL/CgShader Code

FullHLSL/Cg Code

ConvertedGLSL Code

Optimized GLSLShader Code

Final GLSLShader Code

1st Optimization 2nd Optimization

Unity Shader 시스템. 이득우 http://www.slideshare.net/MrDustinLee/unity-shader-system-korean-note

Surface Shader Fragment Shader

Unity Surface Shader

들어가기 전에..

셰이더도 기본적인 사칙 연산을 따릅니다.

3 + 2 = ?

3 + 2 x 3 = ?

(3 + 2) x 3 = ?

3 + 2 x 3 + 2 = ?

(3 + 2) x (3 + 2) = ?

더하기, 곱하기보다 빼기가 느리며, 나누기는 20배 정도 느립니다.(요즘도?)

add : 더하기 ( + )

Texture A + texture B

multiply : 곱배기하기 ( * )

(Texture A * texture B) * 3

subtract : 빼기 ( - )

(Texture A * texture B) * 15 – texture C

divide : 나누기 ( / )

1 / 5 = 0.2

Surface Shader 기본 구조

http://docs.unity3d.com/kr/current/Manual/SL-SurfaceShaderExamples.html

하나 하나 뜯어봅시다~!

폴더/이름 구조

폴더/이름을 정하는 항목.

Shader “폴더 이름 / Shader 이름”

같은 폴더/이름이 존재할 경우 둘중 하나

는 안나옴.

이름을 바꾸어 봅시다.

Unity에서 잘 나오는지 확인해 봅니다.

Properties

Material 창에 표시되는 항목. 변수를 정

의하고 타입을 정하게 됩니다.

_MainTex 는 “Texture”라고 표시되고

2D 텍스쳐를 사용함. 기본값은 white.

라고 써있음

Name(“display name”, 2D) = “name” {) : 2D texture 이미지를 입력 받음

_MainTex (“base texture”, 2D ) = “white” {}

_SpecPower(“Specular Power”, Range(0, 1) ) = 0.5

_Rimcolor(“Rim color”, color) = ( 1, 1, 1, 1 )

_Reflect(“Cubemap”, CUBE) = “” {}

Tag와 Compiler 선언부

SubSahader부터 셰이더코드가 시작됩

니다.

Tag {“RenderType” = “Opaque”}

우선 불투명 셰이더로 정의 합니다.

CGPROGRAM ~~ ENDCG 로 작성됩니다

Or GLSLPROGRAM ~~ ENDGLSL

#pragma 뒤에 컴파일 옵션과 조명 이

름을 선언합니다. >> 뒤에 다시 다룹니다.

struct Input : 출력 구조체 선언부

Properties에 정의된 변수의 타입과

출력에 사용할 구조를 정의

struct Input에는

float2 uv_MainTex - _MainTex 속성의 텍스쳐는 uv 1번 채널을 사용하여 그림

float2 uv2_MainTex – uv2번 채널 사용(Unity는 UV 채널을 두개밖에 지원하지 않는다)

float3 viewDir – 뷰 방향을 포함. 시차효과, 림 라이트 등의 계산에 사용

float3 worldPos – 월드 공간상의 위치를 포함

float3 worldRefl – Surface Shader의 o.Normal을 기입하지 않는 경우 월드 반사 벡터를 포함

float4 color:COLOR – vertex Color를 사용함

float : 32bit의 매우 정밀한 부동 소수점

half : 16bit의 중간 정밀도의 부동 소수점, 6 ~ -6만 사이의 값

fixed : 11bit의 낮은 정밀도의 부동 소수점, 2.0 ~ -2.0 사이의 값

1/256 정확도의 자릿수(8비트)

결국 정확도의 차이.

Android, IOS등 플랫폼과 디바이스에 따라 계산되는 범위와 표현량에 차이가 있다.

정밀도(precision)

SurfaceOutput 출력부

http://docs.unity3d.com/kr/current/Manual/SL-SurfaceShaderExamples.html

void 반환되는 함수가 없는 함수.

Input IN, << struct Input에서 정의된

것을 가져다가 inout SurfaceOutput

o 을 통해 출력한다 라는 이야기임.

Fallback : Shader가 로드에 실패했

을경우 대체 셰이더를 지정하는것과

그림자를 그리는 것에 사용된다.

Surface shader의 출력하는 표준 구조

struct SurfaceOutput

{

fixed3 Albedo; // diffuse color

fixed3 Normal; // tangent space normal, if written

fixed3 Emission; // Emissive Effect. Add the color

half Specular; // specular power in 0..1 range

fixed Gloss; // specular intensity

fixed Alpha; // alpha for transparencies

};

_SpecColor도(specular color) Properties에 정의(특수 예약어) >> 얘도 다음기회에…

SurfaceOutput은 Lighting.cgnic파일에 선언되어있음.(그러니까 또 하면 안됨)

Lambert 역시 미리 선언되어있는 조명 방식임 자세한건 다음 기회에…

StandardSurfaceOutput도 다음 기회에…

#pragma surface surf illuUnlit

fixed4 LightingilluUnlit (illuSurfaceOutput s, half3 lightDir, half atten) {

return fixed4( s.Albedo ,1);

}

sampler2D _MainTex;

struct illuSurfaceOutput {

fixed3 Albedo;fixed Alpha;

};

struct Input {

half2 uv_MainTex;};

void surf (Input IN, inout illuSurfaceOutput o) {

fixed3 d = tex2D (_MainTex, IN.uv_MainTex).rgb;

o.Albedo = d.rgb;

Ctrl + C

Ctrl + V

Shader 작성에서 유의사항

대소문자 구분.

띄어쓰기

끝에는 항상 >> ;

Shader 오류 발생시

Console창에 에러 메시지가 출력.

이를 확인해 찾으면 대부분의 문제점

은 발견이 가능.

통칭 보라도리..(많이 보시게 될 화면)

DX과 OpenGL의 차이

3채널과 4채널을 혼합해 계산할 경우

OpenGL에서는 이상없이 컴파일 되는

경우가 있으나 DirectX에서는 컴파일

불가.

언리얼의 비쥬얼 스크립트에서는 처

음부터 계산이 불가능하게 막혀있음

과제. 1 색상을 지정해 구체를 만들어 봅시다.

Shader 이름을 정해봅시다.

Red (1,0,0,1)

Green (0,1,0,1)

Blue (0,0,1,1)

Yellow ?

Shader "Study/RedColor" {

Properties {}

SubShader {

Tags { "RenderType"="Opaque" }

CGPROGRAM#pragma surface surf Lambert

struct Input {

float4 color:COLOR;

};

void surf (Input IN, inout SurfaceOutput o) {

o.Albedo = float4(1,1,0,1);

}ENDCG}FallBack "Diffuse"

}

과제. 2 색상을 직접 지정할수 있는 shader를 만들어 봅시다

Hint

_Tintcolor

fixed4 _Tintcolor;

o.Albedo = …………….;

수고하셨습니다.