Shadery w Unity

26
Shadery w Unity

Transcript of Shadery w Unity

Page 1: Shadery w Unity

Shadery w Unity

Page 2: Shadery w Unity

Wstęp

Potok renderowania w Unity korzysta z

trzech podstawowych elementów:

Trójwymiarowe modele – Unity korzysta z

modeli w formacie *.fbx (wspierane są też

inne formaty ale są one konwertowane w tle

do *.fbx)

Materiały – jest to interfejs pozwalający

inicjalizować programy cieniowania

odpowiednimi danymi (teksturami i

właściwościami)

Programy cieniujące – skrypty przetwarzające

wierzchołki i fragmenty w celu określenia

koloru odpowiednich pikseli na ekranie

Page 3: Shadery w Unity

Dostępne jednostki cieniowania

Surface Shader

Wysokopoziomowy program cieniowania

zalecany przy efektach korzystających ze

świateł. Rozbijany jest później na serię

jednostek cieniujących wierzchołki oraz

fragmenty

Vertex&Fragment Shaders

Zgodnie z nazwą jednostki cieniowania

odpowiedzialne za przetwarzanie

wierzchołków i fragmentów

Dostępne są również nowsze jednostki

(geometry, hull i domain shader’y) ale ich nie

będziemy poruszać

Page 4: Shadery w Unity

Dostępne jednostki cieniowania cd.

Fixed Function Shaders

Przestarzałe rozwiązanie bazujące

na stałym potoku renderowania

Zbiór funkcji wykonujących

podstawowe operacje (np.

mieszanie kolorów, tekstur,

wykorzystanie podstawowych

modeli oświetlenia itp.)

Page 5: Shadery w Unity

ShaderLab – wstęp

Shader "MyShader"

{

Properties

{

//

}

SubShader

{

CGPROGRAM

//

ENDCG

}

SubShader

{

}

Fallback "Diffuse"

}

Językiem wykorzystywanym w Unity do tworzenia programów cieniowania jest

ShaderLab

Na początku pliku zdefiniowana jest

nazwa programu -> Shader „MyShader”

Ciało programu zawiera:

Sekcję z własnościami programu

cieniowania -> Properties

własności te można ustawiać z poziomu

edytora Unity

Page 6: Shadery w Unity

ShaderLab – wstęp cd.

Zbiór sekcji z różnymi wersjami programu

-> SubShader

sprawdzając od góry uruchamiana jest

pierwsza napotkana wersja, która może

zostać wykonana na dostępnej karcie

graficznej

jeżeli żadna wersja nie może zostać

wykonana, korzystając ze słowa

kluczowego Fallback możemy

wyznaczyć, inny (zastępczy) program

cieniowania

Kod programu (język GLSL/CG) znajduje

się pomiędzy dyrektywami CGPROGRAM

… ENDCG

Shader "MyShader"

{

Properties

{

//

}

SubShader

{

CGPROGRAM

//

ENDCG

}

SubShader

{

}

Fallback "Diffuse"

}

Page 7: Shadery w Unity

ShaderLab – sekcja Properties

Shader "MyShader"

{

Properties

{

_MyTexture ("My texture", 2D) = "white" {}

_MyNormalMap ("My normal map", 2D) = "bump” {}

// Grey

_MyInt ("My integer", Int) = 2

_MyFloat ("My float", Float) = 1.5

_MyRange ("My range", Range(0.0, 1.0)) = 0.5

_MyColor ("My colour", Color) = (1, 0, 0, 1)

// (R, G, B, A)

_MyVector ("My Vector4", Vector) = (0, 0, 0, 0)

// (x, y, z, w)

}

}

Właściwości definiujemy w formacie:

nazwa (etykieta, typ) = wartość_domyślna

Podstawowe typy danych:

2D – sampler2D (tekstura), domyślną

wartością może być np. „white”, „black”,

„gray”, „bump” (normal mapa)

Cube – samplerCube (6 tekstur tworzących

kostkę),

Int, Float (Range)

Color

Vector (zawsze czterowymiarowy)

Page 8: Shadery w Unity

ShaderLab – sekcja SubShader

SubShader

{

Tags { "RenderType"="Opaque” "Queue"="Geometry+1"

"ForceNoShadowCasting"="True" }

LOD 200

Offset -1, -1

CGPROGRAM

#pragma surface surf Lambert decal:blend

sampler2D _MainTex;

struct Input { float2 uv_MainTex; };

void surf (Input IN, inout SurfaceOutput o)

{

half4 c = tex2D (_MainTex, IN.uv_MainTex);

o.Albedo = c.rgb;

o.Alpha = c.a;

}

ENDCG

}

Sekcja SubShader ma zazwyczaj następującą strukturę:

Tagi i ustawienia programu cieniowania

Kod programu w języku GLSL/CG

(pomiędzy dyrektywami CGPROGRAM

… ENDCG)

Dyrektywy kompilacji

Deklaracje zmiennych globalnych

Deklaracje struktur danych wejściowych

i/lub wyjściowych

Kod jednostek cieniowania

Page 9: Shadery w Unity

ShaderLab – sekcja SubShaderTagi i ustawienia programu cieniowania

Dokumentacja opisuje 7 podstawowych tagów:

Dwa najważniejsze: Queue, RenderType

Queue - określa kolejność wyświetlania na ekranie.

Parametrem jest liczba. Istnieje kilka stałych takich

jak: Background, Geometry, AlphaTest, Transparent,

Overlay

RenderType – określa sposób wyświetlania wyniku. Z

najważniejszych typów wyróżnić można: Opaque –

nieprzezroczysty, Transparent – (pół)przezroczysty,

TransparentCutout – (pół)przezroczyste fragmenty są

obcinane

https://docs.unity3d.com/Manual/SL-SubShaderTags.html

Page 10: Shadery w Unity

ShaderLab – sekcja SubShaderTagi i ustawienia programu cieniowania cd.

Pozostałe: DisableBatching,

ForceNoShadowCasting, IngoreProjector,

CanUseSpriteAtlas, PreviewType

Ustawienia mogą dotyczyć między innymi:

Bufora głębi: Cull [Back|Front|Off], ZWrite

[On|Off], ZTest [Less|Greater|Equal|…], Offset

[Factor|Units],

Świateł: Lighting [On|Off]

Level of Details: LOD [liczba]

Page 11: Shadery w Unity

ShaderLab – sekcja SubShaderKod programu w języku GLSL/CG - Dyrektywy kompilacji

#include "UnityCG.cginc"

#pragma surface surfaceFunction lightModel

[optionalparams]

#pragma vertex name

#pragma fragment name

#pragma geometry name

#pragma hull name

#pragma domain name

#pragma target name

#pragma only_renderers space_separated_names

#pragma exclude_renderers space_separated_names

#pragma multi_compile …

#pragma enable_d3d11_debug_symbols

#pragma hardware_tier_variants renderer_name

Na podstawie tych dyrektyw karta graficzna

określa, która sekcja SubShader powinna

zostać wybrana

Pozwalają określić wymaganą wersję

OpenGL/DirectX

Umożliwiają ograniczenie użyteczności

materiału do określonych komponentów Unity

(Renderer’ów)

Dyrektywy pozwalają wczytywać pliki

biblioteczne

Za pomocą dyrektyw deklaruje się jednostki

cieniowania

Page 12: Shadery w Unity

ShaderLab – sekcja SubShaderKod programu w języku GLSL/CG - Deklaracje zmiennych globalnych

Properties

{

_MyTexture ("My texture", 2D) = "white" {}

_MyNormalMap ("My normal map", 2D) = "bump" {}

_MyInt ("My integer", Int) = 2

_MyFloat ("My float", Float) = 1.5

_MyRange ("My range", Range(0.0, 1.0)) = 0.5

_MyColor ("My colour", Color) = (1, 0, 0, 1)

_MyVector ("My Vector4", Vector) = (0, 0, 0, 0)

}

SubShader

{

CGPROGRAM

sampler2D _MyTexture, _MyNormalMap;

int _MyInt;

float _MyFloat, _MyRange;

half4 _MyColor;

float4 _MyVector;

ENDCG

}

Aby używać właściwości nie wystarczy zadeklarowanie ich w

sekcji Properties

Wymagana jest deklaracja

zmiennych globalnych do których

zostaną przypisane wartości

nazwy muszą się zgadzać z

nazwami w sekcji Properties

Typy mogą być bardziej

restrykcyjne np. ograniczenie

wektorów do dwóch lub trzech

wymiarów, zmniejszenie

dokładności float’a do half itp.

Page 13: Shadery w Unity

ShaderLab – sekcja SubShaderKod programu w języku GLSL/CG - Deklaracje struktur danych

#pragma surface surf Lambert

struct Input

{

float4 color : COLOR;

};

void surf (Input IN, inout SurfaceOutput o)

{

o.Albedo = 1; // 1 = (1,1,1,1) = white

}

Istnieje możliwość zdefiniowania struktur danych wejściowych i wyjściowych z

poszczególnych jednostek cieniujących

Surface Shader’y

(https://docs.unity3d.com/Manual/SL-SurfaceShaders.html)

Istnieją trzy struktury danych

wyjściowych:

SurfaceOutput (standard z Unity 4 -

materiały Diffuse lub Specular)

SurfaceOutputStandard i

SurfaceOutputStandard Specular

(standard z Unity 5 – materiały Standard)

Page 14: Shadery w Unity

ShaderLab – sekcja SubShaderKod programu w języku GLSL/CG - Deklaracje struktur danych cd.

#pragma surface surf Lambert

struct Input

{

float4 color : COLOR;

};

void surf (Input IN, inout SurfaceOutput o)

{

o.Albedo = 1; // 1 = (1,1,1,1) = white

}

Dane wejściowe dla Surface Shader’ów

należy zdefiniować. Mogą zawierać:

Koordynaty tekstury (zmienne

zaczynające się na uv_ lub uv2_)

Interpolowany kolor piksela (zmienna z

wiązaniem : COLOR)

pozycję na ekranie i w świecie

Wektory odbicia i normalne

Page 15: Shadery w Unity

ShaderLab – sekcja SubShaderKod programu w języku GLSL/CG - Deklaracje struktur danych cd.

#pragma vertex vert

#pragma fragment frag

struct v2f {

float2 uv : TEXCOORD0;

float4 pos : SV_POSITION;

};

v2f vert (float4 vertex : POSITION, float2 uv : TEXCOORD0)

{

v2f o;

o.pos = UnityObjectToClipPos(vertex);

o.uv = uv;

return o;

}

fixed4 frag (v2f i) : SV_Target

{

return fixed4(i.uv, 0, 0);

}

Vertex & Fragment Shader’y

Dla tych jednostek cieniujących trzeba

zdefiniować strukturę wejściową i wyjściową

(dla Vertex Shader’a mogą to być parametry

wywołania)

Przypisywanie wartości opiera się na

wiązaniach jak TEXCOORD0, SV_POSITION itp.

(listę dostępnych wiązań można znaleźć w

dokumentacji)

Vertex Shader zwraca strukturę, która jest

wejściem do Fragment Shader’a

Fragment Shader zwraca obliczony kolor

fragmentu (typ fixed4 powiązany z SV_Target)

Page 16: Shadery w Unity

ShaderLab – sekcja SubShader

Przykłady (Surface Shader)

Simple Diffuse – tylko światło rozposzone

Textured – model z teksturą

Bumped – dodana normal mapa

Rim – poświata dookoła obiektu

Sliced – wycięta część fragmentów

Cubemap – dodane odbicie (z cubemap’y)

Details – dodana druga tekstura z detalami

VertexData – wyświetlenie normalnych

Normals Extrusion – wyciągnięcie modelu wzdłuż normalnych

Snow – efekt pokrywy śnieżnej

Kod programu w języku GLSL/CG - Kod jednostek cieniowania

Page 17: Shadery w Unity

ShaderLab – sekcja SubShader

Przykłady (Fragment Shader)

VertexLit – tylko tekstura, bez świateł

SolidColor – jednolity kolor

UV – kolory koordynatów tekstury

Vpos – wycięcie szachownicy w modelu

Vface – pokolorowanie front i back face’ów

Vertex1d – przekształcenie współrzędnej w losowe kolory

WrlSpN – wyświetlenie normalnych (globalnych)

Triplanar – tekstura naniesiona z trzech kątów

Kod programu w języku GLSL/CG - Kod jednostek cieniowania cd.

Page 18: Shadery w Unity

ShaderLab – sekcja SubShader

Przykłady (Fragment Shader)

SkyRefl – odbicie nieba na powierzchni obiektu

ManyTex – wiele tekstur naniesionych na obiekt

ChBoard – wzór szachownicy wygenerowany na obiekcie

Diffuse – światło rozproszone

Ambient – światło otoczenia

ShadCast – rzucanie cienia

ShadRecv – wyświetlenie cieni innych obiektów

Kod programu w języku GLSL/CG - Kod jednostek cieniowania cd.

Page 19: Shadery w Unity

ShaderLab – sekcja SubShader

Przykłady

Falująca podłoga

Wyciąganie wierzchołków wzdłuż

normalnych zależnie od czasu

Dostępne zmienne:

_Time[4] = {t/20, t, t*2, t*3}

_SinTime[4] = {sin(t/8), sin(t/4), sin(t/2),

sin(t)}

gdzie t to aktualny czas

Zaawansowane – czas w jednostkach cieniujących

Page 20: Shadery w Unity

ShaderLab – sekcja SubShader

Niektórych efektów nie da się uzyskać za pomocą pojedynczej sekwencji jednostek cieniowania

Z tego powodu wprowadzony został mechanizm przejść (ang. Pass)

Każde kolejne przejście może korzystać z danych wyjściowych poprzedniego przejścia zapisanych w odpowiednich buforach

Przykładem wykorzystania jest użycie predefiniowanego przejścia GrabPass, które zwraca fragment obrazu zasłanianego przez nasz obiekt

Pozwala stworzyć takie materiały jak szkło czy woda

Zaawansowane – programy cieniujące wykorzystujące wiele przejść

Page 21: Shadery w Unity

Physically based rendering

Model oświetlenia oparty na

właściwościach fizycznych

materiałów

Kosztowniejszy od wcześniejszych

podejść opartych o światło

rozproszone (Diffuse) i odbicia

lustrzane (Specular)

Dający bardziej realistyczne efekty i

więcej możliwości

Unity dostarcza dwie wersje

materiałów: lustrzaną i metaliczną

Page 22: Shadery w Unity

Physically based rendering

Wersja metaliczna zawiera trzy parametry:

Kolor bazowy materiału

Poziom gładkości

Poziom metaliczności

Wersja metaliczna (metallic)

Page 23: Shadery w Unity

Physically based rendering

Wersja lustrzana zawiera trzy parametry:

Kolor bazowy materiału

Poziom gładkości

Kolor odbicia lustrzanego

Wersja lustrzana (specular)

Page 24: Shadery w Unity

Substance (by Allegorithmic)

Alternatywa do pisania

zaawansowanych programów

cieniujących ręcznie – Substance

Designer

Produkt firmy Allegorithmic

pozwalający na tworzenie

materiałów za pomocą łączenia

bloczków

Możliwość eksportu materiału do

silników gier takich jak Unity czy

Unreal Engine 4

Page 25: Shadery w Unity

Substance (by Allegorithmic)

Na podstawie parametrów

generowane są tekstury oraz

prostszy materiał, który z nich

korzysta

Parametry można modyfikować

w czasie działania aplikacji

(generacja nowej tekstury – może

być kosztowne)

Parametry definiuje się tworząc

„substancję” w Substance

Designer’ze

Przykład materiałów generowanych dynamicznie

Page 26: Shadery w Unity

Materiały

http://www.alanzucconi.com/2015/06/10/a-gentle-introduction-to-shaders-in-unity3d/

https://docs.unity3d.com/Manual/SL-Reference.html

https://docs.unity3d.com/Manual/GraphicsTutorials.html

http://http.developer.nvidia.com/Cg/

https://blogs.unity3d.com/2015/02/18/working-with-physically-based-shading-a-practical-approach/

https://unity3d.com/learn/tutorials/topics/graphics

https://www.allegorithmic.com/

https://github.com/Podmuch/ShadersOverview.git