HLSL programozás Szécsi László
RESOURCES PIPELINE STAGES RENDER STATES Vertex buffer Instance buffer Constant buffers and textures Index buffer Constant buffers and textures Output buffer Constant buffers and textures Render target Render textures target textures Depth-stencil texture Input Assembler I. input streaming vertex data, instance data Vertex Shader processed vertex data Input Assembler II. primitive setup primitive data Geometry Shader primitive strip data Rasterizer face culling depth bias adjustment clipping homogenous division viewport transformation output filtering fragments with interpolated data Fragment Shader fragment color and depth Output merger stencil test depth test blending Input layout Shader program Uniform parameters Primitive type Shader program Uniform parameters Cull mode Depth bias Viewport Fill mode Filtering Shader program Uniform parameters Depth-stencil state Blending state
Vertex shader és környezete Vertex buffer pos normal color tex POSITION, NORMAL, COLOR0, TEXTCOORD0, *MVP *MV *MVIT Illumináció Vertex shader Állapot Transzformációk Fényforrások Anyag POSITION, COLOR1, COLOR0, TEXTCOORD0, háromszögre Vágás: -w<x<w, -w<y<w, -w<z<w, 0<color<1 Homogén osztás: X=X/w, Y=Y/w, Z=Z/w POSITION, COLOR0, COLOR1, TEXTCOORD0, új háromszögre
Alap vertex shader float4x4 modelviewprojmatrix; struct StandardInput { float4 pos : POSITION; float4 color : COLOR0; float2 tex : TEXCOORD0; }; struct StandardOutput { float4 hpos : POSITION; float3 color : COLOR0; float2 tex : TEXCOORD0; }; StandardOutput standardvs(standardinput input) { StandardOutput output = StandardOutput(0); output.hpos = mul(input.pos, modelviewprojmatrix); output.tex = input.tex; output.color = input.color; return output; } uniform paraméterek
Pixel shader és környezete POSITION, COLOR0, TEXTCOORD0, háromszögekre Háromszög kitöltés és lineáris interpoláció POSITION, COLOR0, TEXTCOORD0 pixelekre Pixel shader Textúrázás: text2d(u,v)*color0 + color1 POSITION, COLOR Pixel műveletek blending, z-bufferelés Állapot Textúra azonosító és paraméterek Textúra memória Rasztertár
Alap pixel shader uniform textúra paraméter formailag ugyanaz, mint ami a vertex shader outputja volt, de 3 vertex között interpolált értékek vannak benne sampler2d colorsampler; float4 standardps( StandardOutput input) : COLOR { float4 color = tex2d(colorsampler, input.tex) * input.color; return color; }
Effect file szerkesztés VS FX composer syntax highlighting azonnali fordítás és hibajelzés eredmény látható uniform paraméterek kézzel állíthatók fxc.exe megnézni a gépi kódot
Effect file globális változók, textúra samplerek HLSL függvények technique definíciók pass definíciók render state vertex shader pixel shader
Shader fordítás technique standard{ pass p0{ ZEnable = TRUE; VertexShader = compile vs_2_0 standardvs(); PixelShader = compile ps_2_0 standardps(); } } cél profil
Profilok Shader Model 1: vs_1_0, ps_1_0 ps_1_4 pár utasítás, regisztertologatás,... Shader Model 2: vs_2_0, ps_2_0 256 utasítás, swizzle, 16 textúra Shader Model 3 : vs_3_0, ps_3_0 vertex texture, dynamic flow control (if) 512 utasítás, dependent read Shader Model 4: vs_4_0, gs_4_0, ps_4_0 végtelen minden, stream, texture object...
Shader Model 3 utasításból nem fogunk kifogyni textúra vertex shaderben is: tex2dlod for: static flow control! előre kell tudni hányszor hajtjuk végre nem lehet benne semmilyen indexelés különben kigörgeti while: dynamic flow control if return feltételes ágból tilos
Vektorműveletek minden regiszter, ALU 4 float széles float, float2, float3 nem gyorsabb mint float4 változó definíció, mint C++-ban float4 color inicializálás értékadás numerikus konstruktorral csak float van float4 color = float4(1, 1, 0.3, 1); color = float4(0.1, 0, 0.3, 1);
Swizzle float4 color = float4(1, 1, 0.3, 1); color.x = 0.5; float2 twochannels = color.rg; float4 pos; pos.xyz = float3(1, 0, 0); pos.w = 1;
Műveletek az összes elemre vonatkoznak float3 v1 = float3(1, 5, 0.3); float3 v2 = float3(0, 0, -0.3); bool3 b1 = v1 < v2; if( all(b1) ) v1 = v2; v1 *= 2; //összes elem * 2 v1 *= v2; //elemenként HLSL intrinsic float scalarprod = dot(v1, v2); float3 crossprod = cross(v1, v2); crossprod = normalize(crossprod);
Vektorok különbsége e-x = [e x -x x e y -x y e z -x z ] szempozíció e e-x nézeti irány (nem normalizált) x árnyalt felületi pont pozíciója
Vektorok hossza v = (v x *v x + v y *v y + v z *v z ) v v
Normalizált nézeti irány e-x = [e x -x x e y -x y e z -x z ] szempozíció e V: nézeti irány (normalizált) V= (e-x)/ e-x x árnyalt felületi pont pozíciója
Két vektor skalárszorzata (dot product) skalár (egy szám) a b = a x b x + a y b y + a z b z a a b = a b cos θ b θ
Mire jó a skalárszorzat? 1. v-nek n irányú része derékszögű háromszög n = 1 v n = v cos Θ = v n cos Θ = v n v v többi v n = n v n skalárszorzat θ n v n n egységnyi hosszú kell legyen
Például: falról visszapattanó labda, tökéletes visszaverődés iránya V = V párhuzamos + V merőleges V: bejövő sebesség V out = V párhuzamos - V merőleges V merőleges = -N(V (-N)) V párhuzamos = V - V merőleges V out = V - 2N(V N) V V párhuzamos Fal N: fal normálvektora N V merőleges V out kimenő sebesség
Mire jó a skalárszorzat? 2. a és b közötti szög cosinusa a = b = 1 cos Θ = a b cos Θ = a b a θ b a és b egységnyi hosszú kell legyen
Például: diffúz felület árnyalása I out = I in k d cosθ I out = I in k d L N k d : diffúz BRDF paraméter I in : bejövő radiancia Θ: fény beesési szöge L: fényirány (normalizált) L θ N: árnyalt felület normálvektora (normalizált) Fal N I out kimenő radiancia (nem függ a nézeti iránytól, mert diffúz)
Két vektor vektoriális szorzata (keresztszorzat, cross product) a b = [a y b z -a z b y a z b x -a x b z a x b y -a y b x ] a b = a b sinθ a b a merőleges a-ra és b-re a a b = 0 b a b = 0 b θ
Mire jó a keresztszorzat? Ha valami vektorra kell egy merőleges keresztszorozzuk pl. a felfele vektorral (pl. [0, 0, 1]) Két vektorra is merőleges a két vektor keresztszorzata ha nem 1 hosszúak vagy nem derékszögben állnak ne felejtsünk el normalizálni Példa: paraméteres felület normálvektora egy pontban
Példa: felület normálvektora felület paraméteres egyenlete legyen: x(u,v) = u y(u,v) = v z(u,v) = sin(2u + 3v ) Mi a normálvektora a u=v=0 pontban? x(u,v) / u = 1 y(u,v) / u = 0 z(u,v) / u = cos(2u + 3v) 2 = 2 x(u,v) / v = 0 y(u,v) / v = 1 z(u,v) / v = cos(2u + 3v) 3 = 3 N = B T = [0-2 0-3 1-0] = [-2-3 1] T érintő (tangens) B érintő (binormál) normalizálás: / sqrt(14)