1 High Level Shader Language (HLSL) Chapter 11. 2 What is HLSL? The previous vertex and pixel shader programming is to use assembly language to write.

Slides:



Advertisements
Similar presentations
Vertex Shader Tricks New Ways to Use the Vertex Shader to Improve Performance Bill Bilodeau Developer Technology Engineer, AMD.
Advertisements

Perspective aperture ygyg yryr n zgzg y s = y g (n/z g ) ysys y s = y r (n/z r ) zrzr.
1 3D Vector & Matrix Chapter 2. 2 Vector Definition: Vector is a line segment that has the direction. The length of the line segment is called the magnitude.
Bump Mapping CSE 781 Roger Crawfis.
Week 8 - Friday.  What did we talk about last time?  Radiometry  Photometry  Colorimetry  Lighting with shader code  Ambient  Directional (diffuse.
Understanding the graphics pipeline Lecture 2 Original Slides by: Suresh Venkatasubramanian Updates by Joseph Kider.
Using effects within a SpriteBatch or as a post render effect
The Programmable Graphics Hardware Pipeline Doug James Asst. Professor CS & Robotics.
Morphing and Animation GPU Graphics Gary J. Katz University of Pennsylvania CIS 665 Adapted from articles taken from ShaderX 3, 4 and 5 And GPU Gems 1.
Image Filtering Advanced Image Filtering Advanced Image filtering with GDI and DX HW accelerations.
Introduction to Shader Programming
Cg: C for Graphics Jon Moon Based on slides by Eugene Lee.
Vertex & Pixel Shaders CPS124 – Computer Graphics Ferdinand Schober.
Computer Science – Game DesignUC Santa Cruz Adapted from Jim Whitehead’s slides Shaders Feb 18, 2011 Creative Commons Attribution 3.0 (Except copyrighted.
1 Cube & Sphere Chapter 5. 2 Draw Cube Cube has 8 vertices as the picture shows. Each vertex has color of Red, Blue, Green or Yellow. We need to draw.
GAM532 DPS932 – Week 1 Rendering Pipeline and Shaders.
Week 3 - Wednesday.  What did we talk about last time?  Project 1  Graphics processing unit  Programmable shading.
CSE 872 Dr. Charles B. Owen Advanced Computer Graphics1 Illumination and Shading Lights Diffuse and Specular Illumination BasicEffect Setting and Animating.
1 Texture Chapter 6. 2 What is Texture? Texture is a D3D interface that can map a partial of a picture to a 3D space by using Texture coordinates. The.
1 X file & Mesh Chapter 8. 2 What is X file? 1.X file is a file that is used to store D3D program's data. 2.Any X file has extension *.x. 3.X file could.
REAL-TIME VOLUME GRAPHICS Christof Rezk Salama Computer Graphics and Multimedia Group, University of Siegen, Germany Eurographics 2006 Real-Time Volume.
Week 3 - Friday.  What did we talk about last time?  Vertex shaders  Geometry shaders  Pixel shaders.
Introduction to Nikola Mihaylov, Sep 1, 2008.
GPU Programming Robert Hero Quick Overview (The Old Way) Graphics cards process Triangles Graphics cards process Triangles Quads.
1 Ring, Circle, Cone Chapter 4. 2 Triangle rotating We have a triangle in the following position We want to rotate it around line y =  2. For this purpose,
Geometric Objects and Transformations. Coordinate systems rial.html.
Graphics Graphics Korea University cgvr.korea.ac.kr 1 Using Vertex Shader in DirectX 8.1 강 신 진
Chris Kerkhoff Matthew Sullivan 10/16/2009.  Shaders are simple programs that describe the traits of either a vertex or a pixel.  Shaders replace a.
A Crash Course in HLSL Matt Christian.
Week 3 - Monday.  What did we talk about last time?  Graphics rendering pipeline  Rasterizer Stage.
Computer graphics & visualization The programmable (D3D 10) Pipeline.
1 Dr. Scott Schaefer Programmable Shaders. 2/30 Graphics Cards Performance Nvidia Geforce 6800 GTX 1  6.4 billion pixels/sec Nvidia Geforce 7900 GTX.
Introduction to XNA Graphics Programming Asst. Prof. Rujchai Ung-arunyawee COE, KKU.
1 Viewing & Projective Window Chapter 3. 2 D3D virtual viewpoint Definition: virtual viewpoint is like a camera that was positioned in some where and.
Computer Graphics The Rendering Pipeline - Review CO2409 Computer Graphics Week 15.
GAM532 DPS932 – Week 2 Vertex Shaders. The Shader Pipeline Vertex Processing Primitive Assembly / Processing Rasterization Fragment Process Pixel Output.
1 Manage Mesh Data Chapter 8. 2 How to manage Mesh data The most important two objects of mesh are VertexBuffer and IndexBuffer, which can obtained by.
3D Programming and DirectX API. Content Mathematics Mathematics Prepare to Write a 3D program Prepare to Write a 3D program Program Structure Program.
2009 GRAPHICS : PROJECT 1 BASED ON DX9 BASICS. Documented by Dongjoon Kim SNU CS Ph.D Course Student Contact : NOTE.
Data Representation. What is data? Data is information that has been translated into a form that is more convenient to process As information take different.
Week 3 Lecture 4: Part 2: GLSL I Based on Interactive Computer Graphics (Angel) - Chapter 9.
 Learn some important functions and process in OpenGL ES  Draw some triangles on the screen  Do some transformation on each triangle in each frame.
Mesh Skinning Sébastien Dominé. Agenda Introduction to Mesh Skinning 2 matrix skinning 4 matrix skinning with lighting Complex skinning for character.
Advanced D3D10 Shader Authoring Presentation/Presenter Title Slide.
Programming with OpenGL Part 3: Shaders Ed Angel Professor of Emeritus of Computer Science University of New Mexico 1 E. Angel and D. Shreiner: Interactive.
CgFX Sébastien Dominé, NVIDIA. Overview What is CgFX? CgFX runtime Production pipeline with CgFX CgFX Tools set Demo.
GLSL I.  Fixed vs. Programmable  HW fixed function pipeline ▪ Faster ▪ Limited  New programmable hardware ▪ Many effects become possible. ▪ Global.
An Introduction to the Cg Shading Language Marco Leon Brandeis University Computer Science Department.
Computer Science – Game DesignUC Santa Cruz Tile Engine.
COMP 175 | COMPUTER GRAPHICS Remco Chang1/XX13 – GLSL Lecture 13: OpenGL Shading Language (GLSL) COMP 175: Computer Graphics April 12, 2016.
How to write a Pixel Shader CMT3311. Aim The aim of these slides is to introduce you to enough HLSL that you get a general understanding of pixel shaders.
How to use a Pixel Shader CMT3317. Pixel shaders There is NO requirement to use a pixel shader for the coursework though you can if you want to You should.
Week 3 - Monday CS361.
Programmable Shaders Dr. Scott Schaefer.
Week 8 - Wednesday CS361.
Image Filtering Advanced
Chapter 6 GPU, Shaders, and Shading Languages
GLSL I Ed Angel Professor of Computer Science, Electrical and Computer Engineering, and Media Arts Director, Arts Technology Center University of New Mexico.
9.2. Other notable AI Aspects / HLSL Intro
Ch2: Data Representation
Chapter VI OpenGL ES and Shader
ICG 2018 Fall Homework1 Guidance
Computer Graphics Practical Lesson 10
Programming with OpenGL Part 3: Shaders
Mickaël Sereno Shaders Mickaël Sereno 25/04/2019 Mickaël Sereno -
Computer Graphics Introduction to Shaders
CIS 441/541: Introduction to Computer Graphics Lecture 15: shaders
03 | Creating, Texturing and Moving Objects
CS 480/680 Computer Graphics GLSL Overview.
CS 480/680 Fall 2011 Dr. Frederick C Harris, Jr. Computer Graphics
Presentation transcript:

1 High Level Shader Language (HLSL) Chapter 11

2 What is HLSL? The previous vertex and pixel shader programming is to use assembly language to write instructions, which can de directly executed by GPU Graphical Processing Unit. HLSL, which refers to High Level Shader Language, is a C style programming language in GPU. However, in order to make HLSL working, the GPU of video card must have ability to compile HLSL into assembly instructions. The minimal requirement for GPU is to fit the shader version 2. Some tested GPU chips are: ATI Radeon Xpress 200 or high. nVIDIA GeForce 5200 or high Intel GMA 945 is failed to execute IndexBuffer

3 Check video card shader Version Caps DevCaps = Manager.GetDeviceCaps(0, DeviceType.Hardware ); DeviceType DevType = D3D.DeviceType.Reference; CreateFlags DevFlags = CreateFlags.SoftwareVertexProcessing; if ((DevCaps.VertexShaderVersion >= new Version(2, 0)) && (DevCaps.PixelShaderVersion >= new Version(2, 0))) { DevType =DeviceType.Hardware; if (DevCaps.DeviceCaps. SupportsHardwareTransformAndLight ) { DevFlags = CreateFlags.HardwareVertexProcessing; if (DevCaps.DeviceCaps.SupportsPureDevice) { DevFlags |= CreateFlags.PureDevice; }

4 Class Effect HLSL code is written in text file with extension *.fx. First we need to load is to an Effect object. public static Effect FromFile( Device device, string fileName, Include includeFile, // use null ShaderFlags flags, EffectPool pool // use null ) Example Effect effect = Effect.FromFile(device, "rotation.fx", null, ShaderFlags.None, null);

5 Structure of HLSL code HLSL code has four parts: 1.Variables that get values from application 2.Input and Output structure (optional) 3.Functions 4.Techniques and passes. One HLSL file could have more t echniques. One technique can have multiple passes. Lets see the following example struct VS_OUPUT { float4 pos : POSITION; float4 color : COLOR0; }; float4x4 WorldViewProj : WORLDVIEWPROJECTION;

6 VS_OUTPUT Rotation(in float4 position : POSITION, in float4 color: COLOR0) { VS_OUTPUT Out = (VS_OUTPUT)0; Out.pos = mul(position, WorldViewProj); // Set position Out.color = color; // Set color return Out; } technique Transformation { pass Pass0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = NULL; } }

7 VertexDeclaration decl; 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) VertexDeclaration in HLSL This is same as ASM shader definition

8 effect.SetValue(object_name_in_HLSL, object_in_application) Send Value to Shader We need to send some values from application to GPU, besides the Vertices information. One data must be sent is the matrix that is the product of an object WorldMatrix, ViewMatrix and ProjectionMatrix. If we have more than one objects, then we need send more such matrix. If we want set light in Shader, then we need to send the light direction vector and the inverse matrix of object WorldMatrix. If we want to do animation, then some dynamic data are also to be sent. The basic usage is For example: effect.SetValue(" WorldViewProj", MatrixWorldViewProj)

9 Some control code CullMode = None; // can be control in application CullMode = ccw; FillMode = WireFrame; // can be control in application FillMode = solid; Zenable = true; ZWriteEnable = true; ZFunc = less; StencilEnable = false; AlphaBlendEnable = false; AlphaTestEnable = false; ColorWriteEnable = red | green | blue; Srcblend = One; Destblend = One;

10 Set Matrix 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, f ); float t = (float)Environment.TickCount/500f *Math.PI; Matrix matRot= Matrix.RotationY(t); Matrix worldViewProj = matRot * matView* matProj ; effect.SetValue("WorldViewProj", worldViewProj); }

11 One Pass Render private void Render() { device.BeginScene(); device.RenderState.CullMode = Cull.None ; effect.Technique = "Transformation"; device.VertexDeclaration = decl; device.SetStreamSource(0, VB,0); effect.Begin(0); effect.BeginPass(0); device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1); effect.EndPass(); effect.End(); device.EndScene(); Device.Present(); }

12 Multiple Passes Render private void Render() {..... int numPasses = effect.Begin(0); for (int i = 0; i < numPasses; i++) { effect.BeginPass(i); device.DrawPrimitives( ); effect.EndPass(); } effect.End(); }

13 Output

14 HLSL with Texture If we set texture data by code device.SetTexture(0, texture0); Then in HLSL we can use sampler TextureSampler; to get the image data. The pixel color will be color = tex2D(TextureSampler, textureCoords); However, we must use a pixel operation function to get the color. We won’t get Texture color in Vertex operation function

15 Example sampler TextureSampler; // input texture float4x4 WorldViewProj : WORLDVIEWPROJECTION; void Rotation(in float4 inputPosition : POSITION, in float2 inputTexCoord : TEXCOORD0, out float4 outputPosition : POSITION, out float2 outputTexCoord : TEXCOORD0) { // Get position outputPosition = mul(inputPosition, WorldViewProj); outputTexCoord = inputTexCoord; } This function only gets the position of the vertex. Also it output the texture coordinates outputTexCoord. Any output could be used as the input of the next function.

16 technique TransformTexture { pass P0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = compile ps_1_1 TextureColor(); } } void TextureColor( in float2 textureCoords : TEXCOORD0, out float4 diffuseColor : COLOR0) { // Get the texture color diffuseColor = tex2D(TextureSampler, textureCoords); }; textureCoords is the out put of the last function The pass will call two functions

17 Output

18 HLSL with Multiple Textures It is easy to send multiple textures to HLSL by SetValue(…) After loading them, use code Texture t1, t2, t3; In HLSL, we set this way effect.SetValue("Texture1", t1); effect.SetValue("Texture2", t2); effect.SetValue("Texture3", t3); Texture Texture1; Texture Texture2; Texture Texture3; sampler samp1 = sampler_state { texture = ; } sampler samp2 = sampler_state { texture = ; } sampler samp3 = sampler_state { texture = ; }

19 Texture Texture1; Texture Texture2; Texture Texture3; sampler samp1 = sampler_state { texture = ; minfilter = LINEAR; mipfilter = LINEAR; magfilter = LINEAR; }; sampler samp2 = sampler_state { texture = ; minfilter = LINEAR; mipfilter = LINEAR; magfilter = LINEAR; }; sampler samp3 = sampler_state { texture = ; minfilter = LINEAR; mipfilter = LINEAR; magfilter = LINEAR; }; float4x4 WorldViewProj : WORLDVIEWPROJECTION; float4 Alpha;

20 void Rotation( in float4 inputPosition : POSITION, in float2 inputTexCoord : TEXCOORD0, out float4 outputPosition : POSITION, out float2 outputTexCoord : TEXCOORD0 ) { outputPosition = mul(inputPosition, WorldViewProj); outputTexCoord = inputTexCoord; } void TextureColor1( in float2 textureCoords : TEXCOORD0, out float4 diffuseColor : COLOR0) { diffuseColor = tex2D(samp1, textureCoords); };

21 void TextureColor2( in float2 textureCoords : TEXCOORD0, out float4 diffuseColor : COLOR0) { diffuseColor = tex2D(samp2, textureCoords); }; void TextureColor3( in float2 textureCoords : TEXCOORD0, out float4 diffuseColor : COLOR0) { diffuseColor = tex2D(samp3, textureCoords); };

22 void TextureColor4( in float2 textureCoords : TEXCOORD0, out float4 diffuseColor : COLOR0) { vector color1 = tex2D(samp1, textureCoords); vector color2 = tex2D(samp2, textureCoords); diffuseColor = color1*color2 ; // must ps_2_0 version }; void TextureColor5( in float2 textureCoords : TEXCOORD0, out float4 diffuseColor : COLOR0) { vector color1 = tex2D(samp1, textureCoords); diffuseColor = 1-color1; };

23 void TextureColor6( in float2 textureCoords : TEXCOORD0, out float4 diffuseColor : COLOR0){ vector color1 = tex2D(samp1, textureCoords); vector color2 = tex2D(samp2, textureCoords); diffuseColor = 0.9-(1-color1)*color2 ; }; void TextureColor7( in float2 textureCoords : TEXCOORD0, out float4 diffuseColor : COLOR0){ float4 a = float4(0.33f, 0.33f, 0.33f, 0.0f); vector color1 = tex2D(samp1, textureCoords); diffuseColor.xyz = dot(a, color1); diffuseColor.w=1.0; };

24 void TextureColor8( in float2 textureCoords : TEXCOORD0, out float4 diffuseColor : COLOR0) { diffuseColor.x = textureCoords.x; diffuseColor.y = textureCoords.y; diffuseColor.z =0; diffuseColor.w = 1.0; }; void TextureColor9( in float2 textureCoords : TEXCOORD0, out float4 diffuseColor : COLOR0) { vector color1 = tex2D(samp1, textureCoords); vector color2 = tex2D(samp2, textureCoords); diffuseColor = color1*Alpha + color2*(1-Alpha) ; };

25 technique TransformTexture1{ pass P0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = compile ps_1_1 TextureColor1(); } } technique TransformTexture2{ pass P0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = compile ps_1_1 TextureColor2(); } } technique TransformTexture3{ pass P0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = compile ps_1_1 TextureColor3(); } }

26 technique TransformTexture4{ pass P0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = compile ps_2_0 TextureColor4(); } } technique TransformTexture5{ pass P0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = compile ps_1_1 TextureColor5(); } } technique TransformTexture6{ pass P0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = compile ps_2_0 TextureColor6(); } }

27 technique TransformTexture7{ pass P0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = compile ps_1_1 TextureColor7(); } } technique TransformTexture8{ pass P0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = compile ps_1_1 TextureColor8(); } } technique TransformTexture9{ pass P0 { VertexShader = compile vs_1_1 Rotation(); PixelShader = compile ps_2_0 TextureColor9(); } }

28 protected override void OnKeyDown(KeyEventArgs e) { if(e.KeyCode ==Keys.Up) flag--; if(e.KeyCode ==Keys.Down) flag++; if(flag==6) flag=1; if(flag==0) flag =5; if (flag==1)effect.Technique = "TransformTexture1"; if(flag==2)effect.Technique = "TransformTexture2"; if(flag==3)effect.Technique = "TransformTexture3"; if(flag==4)effect.Technique = "TransformTexture4"; if(flag==5)effect.Technique = "TransformTexture5"; if(flag==6)effect.Technique = "TransformTexture6"; if(flag==7)effect.Technique = "TransformTexture7"; if(flag==8)effect.Technique = "TransformTexture8"; if(flag==9)effect.Technique = "TransformTexture9"; } Control code in application

29 HLSL with Lights Color = lightColor*saturate(dot(lightDirection, objectNormal)) All lights are applied to the last position of the 3D object. However, in HLSL the object is in its original position. Therefore we can either multiply the inverse of the world matrix of the object to the lights direction or multiply world matrix to the normal direction of the 3D object in HLSL. The formula of the color is: Two directions lightDirection and objectNormal must be normalized and in the same world coordinate system LastColor = Color *(1-ambient) +ambient)

30 HLSL Animation HLSL animation is exactly same as ASM shader animation. Mesh0 Mesh1 left eyebrow down Mesh2 right eyebrow down Mesh3 smile The animation formula is mesh0+  *(mesh1-mesh0)+  *(mesh2-mesh0)+  *(mesh3-mesh0) Here ,  and  are floating numbers between 0 and 1

31 VertexElement[] TweenElements = new VertexElement[] { new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0), new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0), new VertexElement(0, 24, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0), 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) Declare Vertex Element for HLSL

32 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), new VertexElement(3, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 3), new VertexElement(3, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 3), new VertexElement(3, 24, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 3), VertexElement.VertexDeclarationEnd }; VertexDeclaration declaration ;

33 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; } Define Vertex Format

34 private VertexBuffer CreateVertexBufferWithFormat(Mesh mesh) { int total = mesh.NumberVertices ; Vertex[] src = (Vertex[])mesh.LockVertexBuffer(typeof(Vertex), LockFlags.None, total); VertexBuffer VB = new VertexBuffer(typeof(Vertex), total, device, Usage.WriteOnly, 0, Pool.Managed); Vertex[] dst = (Vertex[])VB.Lock(0, typeof(Vertex), 0, total); for(int k=0; k<total; k++){dst[k] = src[k]; } VB.Unlock(); mesh.UnlockVertexBuffer(); return VB; } Create VertexBuffer that has vertex Format

35 private void SetMesh() { ExtendedMaterial[] emtrl; Mesh0 = Mesh.FromFile("base.x", MeshFlags.Managed, device, out emtrl ); materials = new Material[ emtrl.Length ]; textures = new Texture[ emtrl.Length ]; for(int i = 0; i < emtrl.Length; i++) { if (emtrl[i].TextureFilename != null) { textures[i] = TextureLoader.FromFile( device, emtrl[i].TextureFilename); } mesh1 = Mesh.FromFile( "smile.x", MeshFlags.Managed, device); mesh2 = Mesh.FromFile( "l-ebrow-down.x", MeshFlags.Managed, device); mesh3 = Mesh.FromFile( "l-ebrow-down.x", MeshFlags.Managed, device);

36 VB0 = CreateVertexBufferWithFormat(mesh0); VB1 = CreateVertexBufferWithFormat(mesh1); VB2 = CreateVertexBufferWithFormat(mesh2); VB3 = CreateVertexBufferWithFormat(mesh3); GraphicsStream stream = VB0.Lock(0, mesh0.NumberVertices, LockFlags.None) ; radius =Geometry.ComputeBoundingSphere( stream, mesh0.NumberVertices, Vertex.Format, out vCenter); Matrix S = Matrix.Scaling(4/radius, 4/radius, 4/radius); Matrx T = Matrix.Translation (-vCenter); worldMatrix = T*S; effect = Effect.FromFile(device, "HardwareHLSL.fx", null, null, ShaderFlags.NotCloneable, null ); }

37 private void SetViewAndProjection() { viewMatrix = Matrix.LookAtLH( new Vector3(0, 0, -8), new Vector3(0, 0, 0), new Vector3(0,1,0)); projectionMatrix = Matrix.PerspectiveFovLH( (float)Math.PI / 4f, (float)this.Width / (float)this.Height, 0.1f, 10000f ); worldMatrix = T*S*rotationMatrix; Matrix mat = worldMatrix*viewMatrix * projectionMatrix; effect.SetValue( "WorldViewProjection", mat); effect.SetValue( "World", rotationMatrix ); }

38 protected override void OnMouseDown(MouseEventArgs e) { if(e.Button ==MouseButtons.Right ) return; down = true; lastX = e.X ;lastY = e.Y ; } protected override void OnMouseUp(MouseEventArgs e) {down = false; } protected override void OnMouseMove(MouseEventArgs e) { if(!down) return; float dx = (float)(lastX - e.X) ; float dy = (float)(lastY - e.Y) ; lastX = e.X ; lastY = e.Y ; Matrix mat = Matrix.RotationYawPitchRoll(dx/80f, dy/80f, 0.0f); rotationMatrix = mat*rotationMatrix; }

39 public void SetWeight() { float t1 = 1f; float t2 = 1.25f; float t3 = 1.5f; float time = (float) Environment.TickCount /400; Wight1 = (float)Math.Pow( Math.Sin( t1 * time), 2); Wight2 = (float)Math.Pow( Math.Sin( t2 * time), 2); Wight3 = (float)Math.Pow( Math.Sin( t3 * time), 2); effect.SetValue( "Weight1", Wight1 ); effect.SetValue( "Weight2", Wight2 ); effect.SetValue( "Weight3", Wight3 ); }

40 private void Render() { device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, 0x000000ff, 1.0f, 0); AttributeRange[] attributes = mesh0.GetAttributeTable(); device.BeginScene(); SetWeight(); SetViewAndProjection(); device.SetStreamSource(0, VB0,0 ); device.SetStreamSource(1, VB1,0 ); device.SetStreamSource(2, VB2,0 ); device.SetStreamSource(3, VB3, 0 ); device.VertexDeclaration = declaration; effect.Technique = "Tween"; device.Indices = mesh0.IndexBuffer; int numPasses = effect.Begin( FX.None );

41 for (int pass = 0; pass < numPasses; pass++) { effect.BeginPass(pass); for( int i = 0; i < attributes.Length; i++) { effect.SetValue("Tex0", textures[i]); effect.SetValue("UseTexture", textures[i] != null ); effect.SetValue("MaterialDiffuse", ColorToVector4( materials[i].Diffuse )); effect.CommitChanges(); device.DrawIndexedPrimitives( PrimitiveType.TriangleList, 0, attributes[i].VertexStart, attributes[i].VertexCount, attributes[i].FaceStart * 3, attributes[i].FaceCount ); } effect.EndPass(); } effect.End(); device.EndScene(); device.Present(); }

42 HLSL code float4x4 WorldViewProjection;// World * View * Projection float4x4 World;// World matrix float3 LightDirection = { 0, 0.5f, -1 }; float4 MaterialDiffuse; float Weight1; float Weight2; float Weight3; bool UseTexture = false; texture Tex0; sampler Tex0Sampler = sampler_state { Texture = ; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; };

43 struct VS_INPUT { float4 position0 : POSITION0; float3 normal0: NORMAL0; float2 tex0 : TEXCOORD0; float4 position1 : POSITION1; float3 normal1: NORMAL1; float4 position2 : POSITION2; float3 normal2: NORMAL2; float4 position3 : POSITION3; float3 normal3: NORMAL3; }; void ps( in float2 tex0: TEXCOORD0, in float3 normal: TEXCOORD1, out float4 color: COLOR0 ) { if (UseTexture) { color = tex2D( Tex0Sampler, tex0 );} else { color = MaterialDiffuse; } color *= saturate(dot(LightDirection, normal)); };

44 void vsTween( in VS_INPUT input, out float4 position : POSITION0, out float2 tex1 : TEXCOORD0, out float3 normal : TEXCOORD1) { float4 pos = input.position0; pos += (input.position1 - input.position0) * Weight1; pos += (input.position2 - input.position0) * Weight2; pos += (input.position3 - input.position0) * Weight3; position = mul(pos, WorldViewProjection); float3 nor = input.normal0; nor += (input.normal1 - input.normal0) * Weight1; nor += (input.normal2 - input.normal0) * Weight2; nor += (input.normal3 - input.normal0) * Weight3; normal = mul( nor, World ); tex1 = input.tex0; };

45 technique Tween { pass P0 { VertexShader = compile vs_2_0 vsTween(); PixelShader = compile ps_2_0 ps(); } }