Folytatva az előzőekben megkezdett HLSL ismertetőt, ebben a részben a texturák használatával még látványosabb lesz mindaz amit a képernyőn meg kívánunk jeleníteni.
Továbbra is az FxComposer használatával, egy új üres effect-re lesz szükség.
Egy tetszőleges kép megjelenítéséhez az alábbiakra van szükség:
- model
- kép
- UV koordináták
- Sampler
A model továbbra is az előző részben beillesztett négyzet marad.
A kép tetszőleges lehet, akár saját vagy akár az internetről letöltött
Az UV koordinátákat jelen esetben a program adja a modellhez
A sampler definiáláshoz az alábbi kódsorok szükségeltetnek:
texture diffuseMap < string UIName = "Diffuse Texture"; >; sampler2D diffuseMapSampler = sampler_state { Texture = <diffuseMap>; };
Első lépésben egy texture kerül bevezetésre. Ez látható a properties panelen "Diffuse Texture" néven.
A sampler2D definiál minden egyéb paramétert a shader számára, hogy az adott texturát milyen módon kell megjeleníteni.(pl hogyan kell sokszorosítani, stb)
Egyenlőre egyetlen hivatkozás bőven elég, amely meghatározza, hogy az adott sampler melyik képhez tartozik: Texture = <diffuseMap>;
Ahol a diffuseMap az előbb létrehozott texture neve
Fontos megjegyezni, hogy ahány texture kerül bevezetésre, pontosan annyi sampler kell.
A kép megjelenítéséhez szükség van UV koordinátákra, ezért a vertexshader bemenete megváltozik.
struct app2vertex { float4 position : POSITION; float2 texCoord : TEXCOORD0; };
A vertexsahder minden esetben elvárja a vertex pozícióját: float4 position : POSITION;
A textura koordináták a struktura texCoord elemén keresztül érhetőek el:
float2 texCoord : TEXCOORD0;
A TEXCOORD0 SEMANTICS utasítja az FXComposert, hogy a model első UV koordinátáit adja át.
Amennyiben egy modellhez több UV koordináta is tartozik, úgy azokat a sorszámok növelésével lehet elérni. (TEXCOORD1, TEXCOORD2...)
Mivel az UV koordinátákra a pixelshader-ben is szükség lesz, ezért annak a bemenetét is változtatni kell.
struct vertex2pixel { float4 position : POSITION; float2 texCoord : TEXCOORD0; };
Noha jelen esetben a két struktúra megegyezik, ez a legritkább esetben fordul csak elő.
Általánosságban elmondható, hogy mindig vagy egy struktúra amely a programtól a vertexshader felé tartalmaz bemenetet (app2vertex) és van egy struktúra amely a vertexshadertól a pixelshader felé tartalmazza a szükséges adatokat (vertex2pixel)
Mivel a pixelshader a vertexshadertól várja a már előkészített paramétereket, ezért logikus, hogy a vertexshader kimenete a vertex2pixel struktúra.
Bemenete pedig az app2vertex struktúra.A végső vertexshader az alábbi:
vertex2pixel mainVS(app2vertex In) {
vertex2pixel Out; Out.position = mul(In.position, WorldViewProj);
Out.texCoord = In.texCoord; return Out; }
A pozíció a már megismert módon kiszámításra kerül.
A textura UV koordináta pedig minden változtatás nélkül továbbadásra kerül a pixelshader felé.
Mivel a vertexshader kimenete egy vertex2pixel struktúra, ebből következőleg a pixelshader bemenetének is muszáj annak lennie.
float4 mainPS(vertex2pixel In) : COLOR { float4 diffuseTexture = tex2D(diffuseMapSampler, In.texCoord); return diffuseTexture; }
A tex2D függvény készíti el a végső képet és 2 paramétert vár.
Az első a sampler neve, a második a modellhez tartozó UV koordináta, amely immáron a vertexshader kimeneteként jön mint paraméter: vertex2pixel In
A végső shader az alábbi:
/*****************************************************/ // ** AUTO GENERATED /*****************************************************/ float4x4 WorldViewProj : WorldViewProjection; /*****************************************************/ // ** TEXTURES /*****************************************************/ texture diffuseMap < string UIName = "Diffuse Texture"; >; sampler2D diffuseMapSampler = sampler_state { Texture = <diffuseMap>; }; /*****************************************************/ // ** IO STRUCTURES /*****************************************************/ // input from application struct app2vertex { float4 position : POSITION; float2 texCoord : TEXCOORD0; }; // output to pixelshader struct vertex2pixel { float4 position : POSITION; float2 texCoord : TEXCOORD0; }; /*****************************************************/ // ** PROGRAMS /*****************************************************/ vertex2pixel mainVS(app2vertex In) { vertex2pixel Out; Out.position = mul(In.position, WorldViewProj); Out.texCoord = In.texCoord; return Out; } float4 mainPS(vertex2pixel In) : COLOR { float4 diffuseTexture = tex2D(diffuseMapSampler, In.texCoord); return diffuseTexture; } /*****************************************************/ // ** // ** TECNIQUES // ** /*****************************************************/ technique technique0 { pass p0 { CullMode = none; VertexShader = compile vs_3_0 mainVS(); PixelShader = compile ps_3_0 mainPS(); } }
Nincsenek megjegyzések:
Megjegyzés küldése