2010. október 23., szombat

SlimDX9 07 - Material Alpha Blending

Az elmúlt SlimDX leckékben megismerkedtünk a fények, anyagok és textúrák adta lehetőségekkel. Láthattuk, hogy milyen egyszerű az alkalmazásuk és, hogy milyen gyönyörű grafikai hatások valósíthatóak meg velük. Az anyagok, illetve textúrák hozzárendelésével a felületek is élethűbb hatást keltenek. De még meggyőzőbbé válik a kép, ha az anyagokat, textúrákat és fényeket együtt alkalmazzuk. Ehhez mos az előző leckékben bemutatott ismereteket ötvözzük egy új projektben. Lássunk is hozzá.
Mivel anyagokat és textúrákat is használunk, vertexünk és vertexformátumunk megfelelően kibővül:
   [StructLayout(LayoutKind.Sequential)]
struct Vertex
{
public Vector3 Position;
public Vector3 Normal;
public Vector2 Texel;

public static readonly int Stride = Marshal.SizeOf(typeof(Vertex));
public static readonly VertexFormat Format = VertexFormat.Position | VertexFormat.Normal | VertexFormat.Texture1;

public Vertex(float vx, float vy, float vz,
float nx, float ny, float nz, float u, float v)
{
Position = new Vector3(vx, vy, vz);
Normal = new Vector3(nx, ny, nz);
Texel = new Vector2(u, v);
}
}
A fenti vertexformátúm a vertex, a felületi normális és a textúra koordinátákat tárolja el. A kocka vertexeinek megadásakor minden tag inicializásáról gondoskodni kell:

data = new Vertex[]
{
// elülső oldal
new Vertex(-1.5f, +1.5f, -1.5f, 0, 0, -1, 0, 0),
new Vertex(+1.5f, +1.5f, -1.5f, 0, 0, -1, 1, 0),
new Vertex(-1.5f, -1.5f, -1.5f, 0, 0, -1, 0, 1),
new Vertex(-1.5f, -1.5f, -1.5f, 0, 0, -1, 0, 1),
new Vertex(+1.5f, +1.5f, -1.5f, 0, 0, -1, 1, 0),
new Vertex(+1.5f, -1.5f, -1.5f, 0, 0, -1, 1, 1),


Az alkalmazott anyagtulajdonságokat a SetupMaterial(), a textúrákat pedig a SetupTexture() metódusban állítjuk, ill. töltjük be. A fényforrás beállításáról a SetupLight() metódus gondoskodik. Ennek eredményeként a képernyőn, három forgó kockát láthatnánk, amelyek a megadott anyagtulajdonságoknak megfelelően verik vissza a fényt. Igen, ennyi az egész, de még nem érdemes megállni…

Anyag és alfa keverés

Az alfa keverésről már írtam az OpenGL leckesorozatban, az elv itt is ugyan az: a színeket RGBA formátumban kell megadni ahol is az (A) érték szolgál alfa-csatornaként. Az alfa-csatorna értéke azt mutatja, hogy a létrehozandó képpont színéhez milyen arányban járul hozzá a forrás pixelének színe. Szerencsére az alfa keveréshez kényelmes függvényeket biztosít számunkra a DirectX API. Első lépésként engedélyezni kell az alfa keverést:

device.SetRenderState(RenderState.AlphaBlendEnable, true);

Azt szeretnénk, hogy anyagunk színe érvényesüljön, ezért beállítjuk az anyagot mint a diffúz fényvisszaverődés forrását:

device.SetRenderState(RenderState.DiffuseMaterialSource, true);

Ezután beállítjuk az első textúramegjelenítés szakasz alfa műveletét, amely a TextureStage.AlphaArg1 értéket fogja használni. Esetünkben ez a diffúz komponens, tehát az anyag színe:

device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Diffuse);
device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.SelectArg1);

Végül az alfa keverés módszerét kell beállítani. A példában a következő képletet fogjuk megvalósítani:

szín = forrás_szín × forrás_alfa + cél_színe × (1 - forrás_alfa)

Ugyanez a SlimDX nyelvére fordítva:

device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);

Az anyag diffúz komponensének alfa értékét futás alatt folyamatosan fogjuk változtatni egy szinusz függvény segítségével a DrawCube() metódusban (lásd forráskód). A végeredmény pedig itt látható, az ablakban három forgó kockát csodálhatunk, amelyek fokozatosan elfakulnak, majd újra megjelennek.

Anyag, fény, textúra, és alfa keverés...

A teljes forrás itt érhető el:

DOWNLOAD

A bejegyzés megírásában nagy segítségemre voltak Nyisztor Károly DirectX-el kapcsolatos könyvei.

0 megjegyzés :

Megjegyzés küldése