1 / 51

# Assembly Shader Language - PowerPoint PPT Presentation

Assembly Shader Language. Chapter 9. What is ASM Shader?. GPU is Graphical Processing Unit of video card .

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

Chapter 9

• GPU is Graphical Processing Unit of video card.
• ASM Shader is assembly language programming in GPU, Use Shader can do a lot of thing about vertex and pixels. For example we can do dolphin mesh vertices interpolation directly in GPU.
• We just pass data and command to GPU and let GPU to finish the work.
• One obvious benefit is the Shader programming can greatly enhance the application speed.
• The other benefit is that Shader can improve the image quality of the applications.
• In following, we will show how to build connecting between application and GPU.

Pixel Shader is to manage color for every pixel in the rendered 3D object. Suppose that we have three texture pictures, then we can do the following different pixel operations by ASM pixel Shader

1. Show texture1 2. Show texture2, 3. Show texture3

• Mask texture1 by texture3 (Multiply two textures)
• Gray color
• Assign texture coordinates to color , because texture coords is 2 dimension, we only get red and green colors
• Tween of texture 1 and texture 3
• Reverse the texture one (negative image) .

All those can be done by very simple ASM Shader code

ASM Pixel Variables

ASM Pixel Shader has the following variables:

1. r0, r1, … are temporary variables. If r0 is used as the last calculation result, it is the color output.

• c0, c1, … are 4-dim constants, which can be defined either in ASM shade code or get values from application.
• Texture data type is tex. Texture colors will be t0, t1. The post-fix number depends the application call like

device.setTexture(0, texture0); // this is t0

device.setTexture(1, texture1); // this is t1

However, we must call

device.SetTextureStageState(1, TextureStageStates.TextureCoordinateIndex, 0);

To enable ASM Shader to get data of t1.

• Texture coordinate is texcoord t0
Some Assembly Operations
• mul Multiplicationmul z, x, y  z = x*y
• mov Assignmentmul z, x  z = x
• sub subtractionsub z, x, y  z = x-y
• m4x4 Matrix Multiplicationmul z, x, M  z = M*x
• dp3 3 dim dot productadd z, x, y  z = x o y

;color from texture 1

ps.1.0 ; this pixel shader version

tex t0

mov r0,t0

;color from texture 2

ps.1.0

tex t1

mov r0,t1

;color from texture 3

ps.1.0

tex t2

mov r0,t2

;multiply two textures

ps.1.0

tex t0

tex t1

mul r0, t0, t1

;color from texture1 inverse

ps.1.0

tex t0

mov r0, 1-t0

ps.1.0tex t0tex t2mov r1, 1-t0mul r0, r1, t2mov r0, 1-r0;

;get gray format

ps.1.0

def c0, 0.33, 0.33, 0.33, 0

tex t0

dp3 r0, t0, c0

ps.1.0

;transform texture coords tu, tv into color (r,g,b)

; r=tu, g=tv, b =0

texcoord t0

mov r0, t0

ps_1_1

tex t0

tex t1

lrp r0, c0, t0, t1

Keyboard input Control
• protected override void OnKeyDown(KeyEventArgs e)
• {
• }
• private void Render(){ . . . . . . . .
• device.SetTexture(1, texture1);device.SetTextureStageState(1, TextureStageStates.TextureCoordinateIndex, 0);
• device.SetTexture(2, texture2);device.SetTextureStageState(2, TextureStageStates.TextureCoordinateIndex, 0);
• double t= Math.Sin((float)Environment.TickCount/2000f);
• float alpha =(float)Math.Pow(t, 2);
• Vector4 v= new Vector4( alpha , alpha , alpha ,alpha );

• . . . . . . . }

Vertex Shader is to manage position for every point before drawing. For example, we can use vertex shader to do the same dolphin animation.

Because we need to pass multiple vertices data to Shader, we need use VertexElement to define VertexDeclararion object, which make possible to enable shader to know the vertex input data from application.

Structure VertexElement

public VertexElement(short stream,short offset, DeclarationType declType, DeclarationMethod declMethod, DeclarationUsage declUsage,byte usageIndex);

VertexElement DeclarationType

The following table are some DeclarationType samples

VertexElementDeclarationUsage

The following table are some DeclarationUsage samples

Method device.SetVertexShaderConstant(…) is to pass data to GPU Shader. It has the following formats

Note1: The first integer argument will determine the data name in GPU Shader Note 2: Any input data beginning with letter 'c'.

All matrices must be passed too

All matrices, including Viewpoint matrix, Projective matrix and any matrix that determines the position of 3D object must be passed to Shader too. However, any matrix must be transposed before calling SetVertexShaderConstant() function. We no longer need to call the followings:

device.Transform.View = MatrixView;

device.Transform.Projection = MatrixProjective;

device.Transform.World = MatrixPosition;

Actually they are disabled by Shader operations

Then in Render() function, we call

Note: We still need to call functions like:

device.SetStreamSource(…);device.Indices = dolphinIndexBuffer;device.DrawIndexedPrimitives(…)

• Define VertexElement array.
• Setup VertexDeclaration.
• Create all VertexBuffer that can recognized by Shader
• Crate all other data including matrices for passing.

Redesign Rotation Triangle

new VertexElement[] velements = new VertexElement[] {  new VertexElement(0, 0, DeclarationType.Float3,

DeclarationMethod.Default, DeclarationUsage.Position, 0),

new VertexElement(0, 12, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),      VertexElement.VertexDeclarationEnd };

decl = new VertexDeclaration(device, velements)

• private void SetViewProjectPosition(){
• Matrix matView = Matrix.LookAtLH( new Vector3( 0.0f, 2f, -5.0f ), new Vector3( 0.0f, 0.0f, 0.0f ), new Vector3( 0.0f, 1.0f, 0.0f ) ); Matrix matProj = Matrix.PerspectiveFovLH( (float)Math.PI / 4.0f, (float)this.Width /(float)this.Height, 1.0f, 1000.0f ); float t = (float)Environment.TickCount/500f *Math.PI; Matrix matRot= Matrix.RotationY(t); Matrix worldViewProj = matRot * matView* matProj ;
• Matrix mat = Matrix.TransposeMatrix(worldViewProj);
• }

Note: In shader, matrix mat will be c4

In Render
• private void Render(){
• SetViewProjectPosition() ;
• device.Clear(D3D.ClearFlags.Target|ClearFlags.ZBuffer, Color.Blue.ToArgb (), 1.0f,1);
• device.BeginScene();
• device.RenderState.CullMode = Cull.None ;
• device.VertexDeclaration = decl;
• device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
• device.EndScene();
• Device.Present();
• }
ASM code

;---------------------------------------------------------; Constants specified by the app; c4 = matWorldViewProjection;---------------------------------------------------------vs.1.1

dcl_position0 v0dcl_color0 v1

; rotation

mov r0, v0m4x4 oPos, r0, c4

; color

mov oD0, v1

Redesign Dolphin Animation

We have three given Dolphin meshes.

In the last chapter, we directly to do the mesh interpolation.

Now we want design Shader operation to do the exactly same Dolphin mesh interpolation.

Some member variables

Device device;

Matrix worldMatrix = Matrix.Identity;Matrix viewMatrix = Matrix.Identity; Matrix projectionMatrix = Matrix.Identity;

Material dolphinMtrl;VertexBuffer dolphinVertexBuffer1 = null;VertexBuffer dolphinVertexBuffer2 = null; VertexBuffer dolphinVertexBuffer3 = null;IndexBuffer dolphinIndexBuffer = null;

int numDolphinVertices = 0;int numDolphinFaces = 0;

VertexDeclaration dolphinVertexDeclaration = null; VertexShader dolphinVertexShader = null;Vector3 vLight = new Vector3(0, -1, 0);

Vertex Structure
• public struct Vertex // preparing for shader
• {
• public Vector3 p;
• public Vector3 n;
• public float tu, tv;
• public static readonly VertexFormats Format =
• VertexFormats.Position |
• VertexFormats.Normal |
• VertexFormats.Texture1;
• };

Set VertexDeclaration

• {
• VertexElement[] dolphinVertexDecl = new VertexElement[] {//the First stream is the first dolphin mesh
• newVertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
• newVertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0),
• new VertexElement(0, 24, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
• // the second stream is the 2nd dolphin mesh
• new VertexElement(1, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 1),

new VertexElement(1, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 1),

• new VertexElement(1, 24, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 1),
• // Third stream is the 3rd dolphin mesh
• new VertexElement(2, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 2),
• new VertexElement(2, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 2),
• new VertexElement(2, 24, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 2),
• VertexElement.VertexDeclarationEnd };
• dolphinVertexShader = new VertexDeclaration(device, dolphinVertexDecl);
• }

private void SetDolphinVertexBuffer(){

• Mesh dolphinMesh1, dolphinMesh2, dolphinMesh3;ExtendedMaterial [] exMtrl;try{
• dolphinMesh1 = Mesh.FromFile("dolphin1.x", MeshFlags.Managed, device, out exMtrl);
• dolphinMtrl = exMtrl[0].Material3D;
• dolphinMesh2 = Mesh.FromFile("dolphin2.x", MeshFlags.Managed, device);
• dolphinMesh3 = Mesh.FromFile("dolphin3.x", MeshFlags.Managed, device);
• }
• catch(Exception)
• { MessageBox.Show("Could not load X files"); return; }

numDolphinVertices = dolphinMesh1.NumberVertices ;numDolphinFaces = dolphinMesh1.NumberFaces ;

• // create 3 empty VertexBuffer
• dolphinVertexBuffer1 = new VertexBuffer(typeof(Vertex),numDolphinVertices, device, Usage.WriteOnly, 0, Pool.Managed);
• dolphinVertexBuffer2 = new VertexBuffer(typeof(Vertex),numDolphinVertices, device, Usage.WriteOnly, 0, Pool.Managed);
• dolphinVertexBuffer3 = new VertexBuffer(typeof(Vertex), numDolphinVertices, device, Usage.WriteOnly, 0, Pool.Managed);
• // create one empty IndexBuffer
• dolphinIndexBuffer = new IndexBuffer(typeof(short), numDolphinFaces * 3, device, Usage.WriteOnly, Pool.Managed);
• VertexBuffer pMeshSourceVB = null;IndexBuffer pMeshSourceIB = null;
• CustomVertex.PositionNormal[] src = null;
• Vertex[] dst = null;

// Copy vertices for mesh 01pMeshSourceVB = dolphinMesh1.VertexBuffer;

• dst = (Vertex[])dolphinVertexBuffer1.Lock(0, typeof(Vertex), 0, numDolphinVertices);
• src = (CustomVertex.PositionNormal[])pMeshSourceVB.Lock(0, typeof(CustomVertex.PositionNormal), 0, numDolphinVertices);
• for(int k=0; k<numDolphinVertices; k++){ dst[k].p = src[k].Position; dst[k].n = src[k].Normal;}dolphinVertexBuffer1.Unlock();pMeshSourceVB.Unlock();pMeshSourceVB.Dispose();
• // Copy vertices for mesh 02
• MeshSourceVB = dolphinMesh2.VertexBuffer;dst = (Vertex[])dolphinVertexBuffer2.Lock(0, typeof(Vertex), 0, numDolphinVertices);src = (CustomVertex.PositionNormal[])pMeshSourceVB.Lock(0, typeof(CustomVertex.PositionNormal), 0, numDolphinVertices);

for(int k=0; k<numDolphinVertices; k++){ dst[k].p = src[k].Position; dst[k].n = src[k].Normal;} dolphinVertexBuffer2.Unlock();pMeshSourceVB.Unlock();pMeshSourceVB.Dispose();

• // Copy vertices for mesh 03
• pMeshSourceVB = dolphinMesh3.VertexBuffer;dst = (Vertex[])dolphinVertexBuffer3.Lock(0, typeof(Vertex), 0, numDolphinVertices);
• src = (CustomVertex.PositionNormal[])pMeshSourceVB.Lock(0, typeof(CustomVertex.PositionNormal), 0, numDolphinVertices);
• for(int k=0; k<numDolphinVertices; k++){ dst[k].p = src[k].Position; dst[k].n = src[k].Normal;}

dolphinVertexBuffer3.Unlock();

• pMeshSourceVB.Unlock();
• pMeshSourceVB.Dispose();
• // Copy indices for the dolphin mesh
• pMeshSourceIB = dolphinMesh1.IndexBuffer;
• short[] indices = (short[]) pMeshSourceIB.Lock(0, typeof(short), 0, numDolphinFaces * 3);
• dolphinIndexBuffer.SetData(indices, 0, LockFlags.None);
• pMeshSourceIB.Unlock();pMeshSourceIB.Dispose();
• );
• }

private void SetVShaderParameters() // pass data to GPU{

• float t = (float)Environment.TickCount/3000f; float blendWeight = (float)Math.Sin(6*t); float weight1, weight2,weight3;
• if (blendWeight > 0.0f) {
• weight1 = (float)Math.Abs(blendWeight); weight2 = 1.0f - (float)Math.Abs(blendWeight); weight3 = 0.0f;}else{ weight1 = 0.0f; weight2 = 1.0f - (float)Math.Abs(blendWeight); weight3 = (float)Math.Abs(blendWeight);}Vector4 vWeight = newVector4(weight1, weight2, weight3, 0.0f);

Vector4 fLight = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);

• Vector4 fLightDolphinSpace = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
• float[] fDiffuse = { 1.00f, 1.00f, 1.00f, 1.00f };
• float[] fAmbient = { 0.25f, 0.25f, 0.25f, 0.25f };
• Matrix S = Matrix.Scaling(0.01f, 0.01f, 0.01f);
• Matrix RZ = Matrix.RotationZ(-(float)Math.Cos(6*t)/6);
• Matrix RY = Matrix.RotationY(t);Matrix T = Matrix.Translation(-5*(float)Math.Sin(t),
• (float)Math.Sin(6*t)/2, 10-10*(float)Math.Cos(t));
• Matrix matDolphin = S*RZ*RY*T;
• Matrix matDolphinInv = Matrix.Invert(matDolphin);
• fLightDolphinSpace = Vector4.Transform(fLight, matDolphinInv);
• fLightDolphinSpace.Normalize();

Matrix mat = matDolphin * viewMatrix * projectionMatrix;Matrix matTranspose= Matrix.TransposeMatrix(mat);Matrix matCamera = matDolphin * viewMatrix;Matrix matCameraTranspose = Matrix.TransposeMatrix(matCamera);Matrix matViewTranspose= Matrix.TransposeMatrix(viewMatrix);Matrix matProjTranspose= Matrix.TransposeMatrix(projectionMatrix); Vector4 vZero = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);Vector4 vOne = new Vector4(1.0f, 0.5f, 0.2f, 0.05f);

// Set the vertex shader constants

}

Constants specified by the last function

; c0 = ( 0, 0, 0, 0 ); c1 = ( 1, 0.5, 2, 4 ); c2 = ( weight1, weight2, weight3, 0 ); c4-c7 = matWorldViewProjection; c8-c11 = matWorldView; c19 = light direction (in model space); c21 = material diffuse color * light diffuse color; c22 = material ambient color; Actually they are memory address

Vertex components (as specifiedin the vertex DECL)

; v0 = Position; v3 = Normal; v6 = Texcoords

Initializing

• public void StartGame(){ . . . . . . .
• SetDolphinVertexBuffer();
• while(GameActive)
• {
• Render();
• Application.DoEvents();
• }
• }

• public void Render(){ . . . . . . .
• device.VertexDeclaration = dolphinVertexDeclaration;
• device.SetStreamSource(0, dolphinVertexBuffer1, 0);
• device.SetStreamSource(1, dolphinVertexBuffer2, 0);
• device.SetStreamSource(2, dolphinVertexBuffer3, 0);
• device.Indices = dolphinIndexBuffer;
• device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numDolphinVertices,0, this.numDolphinFaces); . . . . . . . ..
• }

They are called built-in registers, beginning with letter ‘o’

Input variables in Shader have names begin with letter ‘c’. Free variables in Shader have names begin with letter ‘r’. We also can declare variables begin with letter ‘v’ .

dcl_position0 v0dcl_position1 v1dcl_position2 v2dcl_normal1 v4dcl_normal2 v5dcl_texcoord0 v6

; Tween the 3 positions (v0,v1,v2) into one position

mul r0, v0, c2.xmul r1, v1, c2.ymul r2, v2, c2.zadd r3, r0, r1add r3, r3, r2

; Transform position to the clipping space

m4x4 oPos, r3, c4

mul r0, v3, c2.xmul r1, v4, c2.ymul r2, v5, c2.zadd r3, r0, r1add r3, r3, r2

; Do the lighting calculation

dp3 r1.x, r3, c19 ; r1 = normal dot lightmax r1.x, r1.x, c0.x ; if dot < 0 then dot = 0mul r0, r1.x, c21 ; Multiply with diffuseadd r0, r0, c22 ; Add in ambientmin oD0, r0, c1.x ; clamp if > 1

;Texture coordinates

; Gen tex coords from vertex xz position

mul oT0.xy, c1.y, r9.xz