assembly shader language n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Assembly Shader Language PowerPoint Presentation
Download Presentation
Assembly Shader Language

Loading in 2 Seconds...

play fullscreen
1 / 51

Assembly Shader Language - PowerPoint PPT Presentation


  • 217 Views
  • Uploaded on

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

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

PowerPoint Slideshow about 'Assembly Shader Language' - presley


An Image/Link below is provided (as is) to download presentation

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
what is asm shader
What is ASM Shader?
  • 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.
asm pixel shader
ASM Pixel Shader

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)
  • Another Mask
  • 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 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
Some Assembly Operations
  • mul Multiplicationmul z, x, y  z = x*y
  • add Additionadd 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
shader1 psh
Shader1.psh

;color from texture 1

ps.1.0 ; this pixel shader version

tex t0

mov r0,t0

shader2 psh
Shader2.psh

;color from texture 2

ps.1.0

tex t1

mov r0,t1

shader3 psh
Shader3.psh

;color from texture 3

ps.1.0

tex t2

mov r0,t2

shader4 psh
Shader4.psh

;multiply two textures

ps.1.0

tex t0

tex t1

mul r0, t0, t1

shader5 psh
Shader5.psh

;color from texture1 inverse

ps.1.0

tex t0

mov r0, 1-t0

shader6 psh
Shader6.psh

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

shader7 psh
Shader7.psh

;get gray format

ps.1.0

def c0, 0.33, 0.33, 0.33, 0

tex t0

dp3 r0, t0, c0

shader8 psh
Shader8.psh

ps.1.0

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

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

texcoord t0

mov r0, t0

shader9 psh c0 is from application
Shader9.psh: c0is from application

ps_1_1

tex t0

tex t1

lrp r0, c0, t0, t1

load psh file to shader object
Load psh file to Shader object

private PixelShader CreatePixelShader(string strFilename) {

GraphicsStream code = ShaderLoader.FromFile(strFilename, null, ShaderFlags.None); return new PixelShader(device, code); }

PixelShader shad1 = CreatePixelShader( "shad1.psh");PixelShader shad2 = CreatePixelShader( "shad2.psh"); . . . . . . .PixelShader shad8 = CreatePixelShader( "shad6.psh"); PixelShader shad9 = CreatePixelShader( "shad7.psh");

keyboard input control
Keyboard input Control
  • int shader_flag=0;
  • protected override void OnKeyDown(KeyEventArgs e)
  • {
    • Keys k = e.KeyCode ;if(k==Keys.D1)shader_flag=1;if(k==Keys.D2)shader_flag=2;if(k==Keys.D3)shader_flag=3;if(k==Keys.D4)shader_flag=4;if(k==Keys.D5)shader_flag=5;if(k==Keys.D6)shader_flag=6;if(k==Keys.D7)shader_flag=7;if(k==Keys.D8)shader_flag=8;if(k==Keys.D9)shader_flag=9;
  • }
set shader constents in render
Set Shader constents in Render
  • private void Render(){ . . . . . . . .
    • if(shader_flag>0)device.SetTexture(0, texture0);
    • 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 );
    • device.SetPixelShaderConstant(0, v) ;
slide18

if(shader_flag==1)device.PixelShader = shad2

    • if(shader_flag==2)device.PixelShader = shad2;
    • if(shader_flag==3)device.PixelShader = shad3
    • if(shader_flag==4)device.PixelShader = shad4;
    • if(shader_flag==5)device.PixelShader = shad5;
    • if(shader_flag==6)device.PixelShader = shad6;
    • if(shader_flag==7)device.PixelShader = shad7;
    • if(shader_flag==8)device.PixelShader = shad8;
    • if(shader_flag==9)device.PixelShader = shad9;meshCube.DrawSubset(0);
  • . . . . . . . }
asm vertex shader
ASM Vertex Shader

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
Structure VertexElement

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

vertexelement declarationtype
VertexElement DeclarationType

The following table are some DeclarationType samples

vertexelement declarationusage
VertexElementDeclarationUsage

The following table are some DeclarationUsage samples

setvertexshaderconstant
SetVertexShaderConstant

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 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

initialize shader operation
Initialize Shader Operation

Load Shader code from vertex shader file with extension *.vsh

GraphicsStream stream =ShaderLoader.FromFile( "DolphinTween.vsh", null, ShaderFlags.None);

VertexShader dolphinVertexShader = new VertexShader(device, stream)

Then in Render() function, we call

device.VertexDeclaration = dolphinVertexDeclaration;device.VertexShader = dolphinVertexShader; // pass codeSetVShaderParameters(); // pass data

Note: We still need to call functions like:

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

procedure of shader application
Procedure of Shader Application
  • Define VertexElement array.
  • Setup VertexDeclaration.
  • Load Shader code from vsh file, create shader object
  • Create all VertexBuffer that can recognized by Shader
  • Crate all other data including matrices for passing.
  • SetShaderConstants, pass data to Shader
  • Call device.VertexShader = Shader Object;
slide27

Redesign Rotation Triangle

VertexDeclaration decl;VertexShader vShader ;

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)

vShader = new VertexShader(device, ShaderLoader.FromFile( "rotation.vsh", null, ShaderFlags.None));

set vertex shader value
Set Vertex Shader Value
  • 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);
    • device.SetVertexShaderConstant(4, mat);
  • }

Note: In shader, matrix mat will be c4

in render
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.VertexShader =vShader;
    • device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
    • device.EndScene();
    • Device.Present();
  • }
asm code
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
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
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
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;
  • };
slide35

Set VertexDeclaration

  • private void SeVShaderDeclaration()
  • {
    • 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),
slide36

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);
  • }
slide37

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; }
slide38

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;
slide39

// 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);
slide40

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;}
slide41

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();
    • dolphinVertexShader = new VertexShader(device, ShaderLoader.FromFile( "DolphinTween.vsh", null, ShaderFlags.None)
    • );
  • }
slide42

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);
slide43

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();
slide44

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

device.SetVertexShaderConstant(0, vZero );device.SetVertexShaderConstant(1, vOne );device.SetVertexShaderConstant(2, vWeight);device.SetVertexShaderConstant(4, matTranspose ) ;device.SetVertexShaderConstant(8, matCameraTranspose); device.SetVertexShaderConstant(12, matViewTranspose );device.SetVertexShaderConstant(19, fLightDolphinSpace );device.SetVertexShaderConstant(20, fLight );device.SetVertexShaderConstant(21, fDiffuse);device.SetVertexShaderConstant(22, fAmbient);

}

slide45

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

slide46

Initializing

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

Calling Shader

  • public void Render(){ . . . . . . .
    • device.VertexDeclaration = dolphinVertexDeclaration;
    • device.VertexShader = dolphinVertexShader;
    • SetVShaderParameters() ;
    • 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); . . . . . . . ..
    • }
shader built in output variables
Shader Built-in Output Variables

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’ .

dolphin vertex shader file
Dolphin Vertex Shader file

vs.1.1 ; vertex shader version

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

slide50

; Lighting calculation;Tween the 3 normals (v3,v4,v5) into one normal

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