@willmotil wrote:
Im not very good at hlsl semantics.
What is the prefered or proper way to pass a orientation matrix thru to a shader.Specifically the questions i have at the moment are related to passing and accessing.
Which data type should i use?
Is it ok to use position or should i use blendweights or texturecoordinates whats the difference ?
Are there limits to how many i can pass of a type ?
Are there specific cavets or hlsl access rules for them ?the cs.
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System; using System.Runtime.InteropServices; namespace GLParticleTestTrimed { public class Game2_HwiShader05 : Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; SpriteFont font; ParticleSystem05 particleSystem; Matrix viewProjection; Texture2D particleTexture; Effect particlesEffect; // basically a elaborate timing device. float cyclePercentage = 0f; double fullCycleTimeInSeconds = 1.2d; double cycleTime = 0d; double elapsedUpdateTime = 0; double last = 0d; double now = 0d; public Game2_HwiShader05() { graphics = new GraphicsDeviceManager(this); graphics.GraphicsProfile = GraphicsProfile.HiDef; graphics.PreferMultiSampling = false; Window.AllowUserResizing = true; graphics.PreferredBackBufferWidth = 1024; graphics.PreferredBackBufferHeight = 768; Content.RootDirectory = "Content"; } protected override void Initialize() { base.Initialize(); } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); font = Content.Load<SpriteFont>("MgFont"); particlesEffect = Content.Load<Effect>("ParticleEffect03GL"); particleTexture = Content.Load<Texture2D>("particle"); particleSystem = new ParticleSystem05(particlesEffect) { // Set this to blast out more particles InstanceCount = 10000, ParticleSize = new Vector2(3.0f, 7.0f), ParticleTexture = particleTexture }; SetUpViewProjection(); particleSystem.IntializeParticleSystemBuffers(GraphicsDevice); } public void SetUpViewProjection() { // Setup the worldViewProj matrix float width = GraphicsDevice.PresentationParameters.BackBufferWidth; float height = GraphicsDevice.PresentationParameters.BackBufferHeight; float aspect = width / height; Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0.01f, 0.01f, 5.0f), Vector3.Forward, Vector3.Up); Matrix projMatrix = Matrix.CreatePerspectiveFieldOfView(1.56f, aspect, .1f, 1000); viewProjection = viewMatrix * projMatrix; } protected override void UnloadContent() { Content.Unload(); } protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); CycleTiming(gameTime); particleSystem.UpdateParticleTime((float)(cyclePercentage)); base.Update(gameTime); } public void CycleTiming(GameTime gameTime) { last = now; now = gameTime.TotalGameTime.TotalSeconds; elapsedUpdateTime = now - last; cycleTime += elapsedUpdateTime; if (cycleTime >= fullCycleTimeInSeconds) cycleTime -= fullCycleTimeInSeconds; cyclePercentage = (float)(cycleTime / fullCycleTimeInSeconds); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.Black); GraphicsDevice.BlendState = BlendState.Additive; GraphicsDevice.DepthStencilState = DepthStencilState.Default; particleSystem.DrawParticles(viewProjection, GraphicsDevice); spriteBatch.Begin(); spriteBatch.DrawString(font, cyclePercentage.ToString(), new Vector2(20, 20), Color.Green); spriteBatch.End(); base.Draw(gameTime); } } public class ParticleSystem05 { // Vertex data VertexBuffer vertexBuffer; IndexBuffer indexBuffer; VertexBufferBinding vertexBufferBinding; // Instance data InstanceDataOrientation[] instanceDataOrientaion; VertexBuffer instanceBuffer; VertexBufferBinding instanceBufferBinding; int numInstancesToDraw; float cyclePercentageTime = 0; Effect particlesEffect; public Vector2 ParticleSize { get; set; } public Texture2D ParticleTexture { get; set; } public uint InstanceCount { get; set; } public int MaxVisibleParticles { get; private set; } public ParticleSystem05(Effect effect) { particlesEffect = effect; } public void IntializeParticleSystemBuffers(GraphicsDevice graphicsDevice) { // set up the indice stuff int[] indices = new int[6]; // indices to triangle vertices indices[0] = 1; indices[1] = 0; indices[2] = 2; // ccw indices[3] = 3; indices[4] = 1; indices[5] = 2; // indexBuffer = new IndexBuffer(graphicsDevice, typeof(int), 6, BufferUsage.WriteOnly); indexBuffer.SetData(indices); // set up the vertex stuff // Create a single quad centered at the origin float halfParticleWidth = ParticleSize.X / 2; float halfParticleHeight = ParticleSize.Y / 2; float z = 0.0f; VertexPositionTexture[] vertices = new VertexPositionTexture[4]; //vertices[3].texCoordinate = new Vector2(1.0f, 1.0f); vertices[0].position = new Vector3(-halfParticleWidth, -halfParticleHeight, z); // lt 0 vertices[1].position = new Vector3(halfParticleWidth, -halfParticleHeight, z); // rt 1 vertices[2].position = new Vector3(-halfParticleWidth, halfParticleHeight, z); // lb 2 vertices[3].position = new Vector3(halfParticleWidth, halfParticleHeight, z); // rb 3 // u,v texture coords vertices[0].texCoordinate = new Vector2(0.0f, 0.0f); vertices[1].texCoordinate = new Vector2(1.0f, 0.0f); vertices[2].texCoordinate = new Vector2(0.0f, 1.0f); vertices[3].texCoordinate = new Vector2(1.0f, 1.0f); // vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionTexture.VertexDeclaration, 4, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); vertexBufferBinding = new VertexBufferBinding(vertexBuffer); // set up the instance stuff MaxVisibleParticles = (int)(InstanceCount); instanceDataOrientaion = new InstanceDataOrientation[MaxVisibleParticles]; // set particles randomly Random rnd = new Random(); /* randomly places the particle positions, and color changer */ float halfWidth = graphicsDevice.PresentationParameters.BackBufferWidth * .5f; float halfHeight = graphicsDevice.PresentationParameters.BackBufferHeight * .5f; for (int i = 0; i < MaxVisibleParticles; ++i) { // instance orientation; instanceDataOrientaion[i].instanceForward = Vector3.Forward; instanceDataOrientaion[i].instanceUp = Vector3.Up; instanceDataOrientaion[i].instanceLeft = Vector3.Left; // instance data float position instanceDataOrientaion[i].instancePosition = new Vector3 ( (rnd.Next(0, (int)(halfWidth) * 2) - halfWidth), (rnd.Next(0, (int)(halfHeight * 2)) - halfHeight), ((float)(rnd.Next(1, MaxVisibleParticles + 1)) / (float)(MaxVisibleParticles + 1) * 650 + 350) * -1f ); // instance data float time instanceDataOrientaion[i].instanceTimeOrId = (float)(rnd.Next(0, MaxVisibleParticles + 1)) / (float)(MaxVisibleParticles + 1);//(float)(i) / (float)(MaxVisibleParticles + 1f); // for a timed id } instanceBuffer = new VertexBuffer(graphicsDevice, InstanceDataOrientation.VertexDeclaration, MaxVisibleParticles, BufferUsage.WriteOnly); instanceBufferBinding = new VertexBufferBinding(instanceBuffer, 0, 1); instanceBuffer.SetData(instanceDataOrientaion); } // We could draw less instances here. public void UpdateParticleTime(float seconds) { // i could use my dynamic dead alive buffer here to keep the sorting smooth. numInstancesToDraw = MaxVisibleParticles; cyclePercentageTime = seconds; } public void DrawParticles(Matrix viewProj, GraphicsDevice graphicsDevice) { // Select the technique. particlesEffect.CurrentTechnique = particlesEffect.Techniques["ParticleDrawingSimple"]; // Initialise our shader constants particlesEffect.Parameters["ViewProjection"].SetValue(viewProj); particlesEffect.Parameters["ParticleTexture"].SetValue(ParticleTexture); particlesEffect.Parameters["CyclePercentageTime"].SetValue(cyclePercentageTime); // Set buffers to device graphicsDevice.SetVertexBuffers(vertexBufferBinding, instanceBufferBinding); graphicsDevice.Indices = indexBuffer; // Draw particlesEffect.CurrentTechnique.Passes[0].Apply(); graphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 2, numInstancesToDraw); } } // the instanceDataType [StructLayout(LayoutKind.Sequential)] public struct InstanceDataOrientation : IVertexType { public Vector3 instanceForward; public Vector3 instanceUp; public Vector3 instanceLeft; public Vector3 instancePosition; public float instanceTimeOrId; public static readonly VertexDeclaration VertexDeclaration; static InstanceDataOrientation() { var elements = new VertexElement[] { new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 1), // The usage index must match. new VertexElement(12, VertexElementFormat.Single, VertexElementUsage.BlendWeight, 0), new VertexElement(24, VertexElementFormat.Vector3, VertexElementUsage.BlendWeight, 1), new VertexElement(36, VertexElementFormat.Vector3, VertexElementUsage.BlendWeight, 2), new VertexElement(48, VertexElementFormat.Vector3, VertexElementUsage.BlendWeight, 3), //new VertexElement( offset in bytes, VertexElementFormat.Single, VertexElementUsage. option, shader element usage id number ) }; VertexDeclaration = new VertexDeclaration(elements); } VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } } } // the vertexDataType [StructLayout(LayoutKind.Sequential)] public struct VertexPositionTextureNormal : IVertexType { public Vector3 position; public Vector2 texCoordinate; public static readonly VertexDeclaration VertexDeclaration; static VertexPositionTextureNormal() { var elements = new VertexElement[] { new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), new VertexElement(12, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0), }; VertexDeclaration = new VertexDeclaration(elements); } VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } } } }
the shader
// FxHwInstanceing05.fx #if OPENGL #define SV_POSITION POSITION #define VS_SHADERMODEL vs_3_0 #define PS_SHADERMODEL ps_3_0 #else #define VS_SHADERMODEL vs_4_0 #define PS_SHADERMODEL ps_4_0 #endif //_________________________________________________________________ static const float PI = 3.14159; static const float PI2 = 6.28318; static const float EIGHT_PI = 25.13274; matrix ViewProjection; float CyclePercentageTime; Texture2D ParticleTexture; sampler2D TexSampler = sampler_state { Texture = <ParticleTexture>; //AddressU = Wrap;//AddressV = Wrap;//MinFilter = Anisotropic;//MagFilter = Anisotropic;//MipFilter = Point; }; //__________________________________________________________ struct VSInstanceInputSimple { float3 InstancePosition : POSITION1; float InstanceTimeOrId : BLENDWEIGHT0; float3 InstanceForward : BLENDWEIGHT1; float3 InstanceUp : BLENDWEIGHT2; float3 InstanceLeft : BLENDWEIGHT3; }; struct VSVertexInputSimple { float4 Position : POSITION0;//SV_POSITION; float2 TexCoord : TEXCOORD0; //float3 Normal : NORMAL0; }; struct VSOutputSimple { float4 Position : SV_POSITION; float2 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; VSOutputSimple MainVSSimple(in VSVertexInputSimple vertexInput, VSInstanceInputSimple instanceInput) { VSOutputSimple output; // first i have to get this all to compile without error. float3 instancePosition = instanceInput.InstancePosition; float instanceTimeOrId = instanceInput.InstanceTimeOrId; // create the world float4x4 world; world[0] = float4(instanceInput.InstanceForward, 0.0f); world[1] = float4(instanceInput.InstanceUp, 0.0f); world[2] = float4(instanceInput.InstanceLeft, 0.0f); world[3] = float4(instancePosition, 0.0f); // <- i may need to zero this out first lets see. matrix worldViewProjection = mul(world, ViewProjection); // here is the tricky part the intention is to put this into the proper wvp position in one shot. // however i might have to mult the world without translation. // then translate the vertexposition by the instanceposition and multiply. float4 posVert = mul(vertexInput.Position, ViewProjection); output.Position = posVert; // pass textcoords thru output.TexCoord = vertexInput.TexCoord; // change color float4 colRed = float4(1.0f, 0.0f, 0.0f, .99f); float4 colGreen = float4(0.0f, 1.0f, 0.0f, .99f); float4 colBlue = float4(0.0f, 0.0f, 1.0f, .99f); output.Color = (colRed * instanceTimeOrId) + // colors are based on the instance id or time not x y order as such they go from zero to 1 and blue is drawn first. (colGreen* ((0.5f - abs(instanceTimeOrId - 0.5f))*2.0f)) + (colBlue * (1.0f - instanceTimeOrId)); output.Color.a = 1.0f; return output; } float4 MainPSSimple(VSOutputSimple input) : COLOR0 { float4 col = tex2D(TexSampler, input.TexCoord) * input.Color; // straight clip alpha draws clip(col.a - .05f); return col; } technique ParticleDrawingSimple { pass { VertexShader = compile VS_SHADERMODEL MainVSSimple(); PixelShader = compile PS_SHADERMODEL MainPSSimple(); } };
it also uses a small texture.
Well it's compiling with blendweights but im getting a error on my passed view projection matrix that says its not set to a instance of a object ? though it looks set to me.
Posts: 1
Participants: 1