Jump to content
  • Advertisement
Sign in to follow this  
chibitotoro0_0

[SOLVED] MultiMaterial Shader

This topic is 3162 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

SOLUTION: When you are making changes between a effect pass, make sure you use the effect.CommitChanges() function to pass the changes to the video card or else weird things happen! Thanks to http://forums.xna.com/forums/p/38756/225413.aspx for the solution! -------------------------- QUESTION: I'm running into problems drawing different parts of the same model as separate entities. Using my draw function I've commented two areas "PART 1" and "PART 2" when used separately they generated nice results, but as both are used together weird things start happening. Here are some screenshots. Sorry for the long post. Thank you to anyone viewing this and to those offering help! Part 1 - Everything is good Part 2 - Everything is good Part 1 and 2 - BAD My draw function: graphics.GraphicsDevice.Clear(Color.Black); graphics.GraphicsDevice.RenderState.DepthBufferEnable = true; graphics.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace; graphics.GraphicsDevice.RenderState.AlphaBlendEnable = false; //calculate bone transforms Matrix[] transforms = new Matrix[mAirplane.ModelObject.Bones.Count]; mAirplane.ModelObject.CopyAbsoluteBoneTransformsTo(transforms); // Use the AmbientLight technique from Shader.fx. You can have multiple techniques in a effect file. If you don't specify // what technique you want to use, it will choose the first one by default. effect.CurrentTechnique = effect.Techniques["SpecularLight"]; Matrix renderMatrix, objectMatrix, worldMatrix, viewMatrix, projMatrix; worldMatrix = Matrix.Identity; objectMatrix = mAirplane.Transform(); renderMatrix = Matrix.CreateScale(1.5f) * objectMatrix; projMatrix = mCamera.Projection(); viewMatrix = mCamera.View(); Vector4 vLightDirection = new Vector4(0.0f, 1.0f, 0.0f, 1.0f); Vector4 vecEye = new Vector4(mCamera.Position.X, mCamera.Position.X, mCamera.Position.Z, 0); Vector4 vLightDiffuse = new Vector4(0.8f, 0.0f, 0.0f, 1.0f); Vector4 vLightSpecular = new Vector4(0.5f, 0.5f, 0.0f, 1.0f); Vector4 vLightAmbient = new Vector4(0.5f, 0.5f, 0.5f, 1.0f); effect.Parameters["vecEye"].SetValue(vecEye); effect.Parameters["vecLightDir"].SetValue(vLightDirection); effect.Parameters["vLightDiffuse"].SetValue(vLightDiffuse); effect.Parameters["vLightSpecular"].SetValue(vLightSpecular); effect.Parameters["vLightAmbient"].SetValue(vLightAmbient); BasicEffect currentMaterial; Model currentModel; ModelMesh currentMesh; Vector4 vMaterialDiffuse; Vector4 vMaterialSpecular; Vector4 vMaterialAmbient; Matrix worldInverse; // PART 1 ----------------------------------------- currentModel = mAirplane.ModelObject; currentMesh = currentModel.Meshes[0]; currentMaterial = (BasicEffect)currentMesh.MeshParts[0].Effect; // calculate our worldMatrix.. worldMatrix = transforms[currentMesh.ParentBone.Index] * renderMatrix; worldInverse = worldMatrix; effect.Begin(); effect.CurrentTechnique.Passes[0].Begin(); vMaterialDiffuse = new Vector4(currentMaterial.DiffuseColor.X, currentMaterial.DiffuseColor.Y, currentMaterial.DiffuseColor.Z, 1.0f); vMaterialSpecular = new Vector4(currentMaterial.SpecularColor.X, currentMaterial.SpecularColor.Y, currentMaterial.SpecularColor.Z, 1.0f); vMaterialAmbient = new Vector4(currentMaterial.AmbientLightColor.X, currentMaterial.AmbientLightColor.Y, currentMaterial.AmbientLightColor.Z, 1.0f); effect.Parameters["HasTexture"].SetValue(currentMaterial.TextureEnabled); effect.Parameters["matWorldViewProj"].SetValue(worldMatrix * viewMatrix * projMatrix); effect.Parameters["matWorld"].SetValue(worldMatrix); effect.Parameters["vMaterialDiffuse"].SetValue(vMaterialDiffuse); effect.Parameters["vMaterialSpecular"].SetValue(vMaterialSpecular); effect.Parameters["vMaterialAmbient"].SetValue(vMaterialAmbient); effect.Parameters["ColorMap"].SetValue(colorMap); // Render our meshpart graphics.GraphicsDevice.Vertices[0].SetSource(currentMesh.VertexBuffer, 0, currentMesh.MeshParts[0].VertexStride); graphics.GraphicsDevice.Indices = currentMesh.IndexBuffer; graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, currentMesh.MeshParts[0].BaseVertex, 0, currentMesh.MeshParts[0].NumVertices, currentMesh.MeshParts[0].StartIndex, currentMesh.MeshParts[0].PrimitiveCount); effect.CurrentTechnique.Passes[0].End(); effect.End(); // PART 2 ----------------------------------------- currentModel = mAirplane.ModelObject; currentMesh = currentModel.Meshes[0]; currentMaterial = (BasicEffect)currentMesh.MeshParts[1].Effect; // calculate our worldMatrix.. worldMatrix = transforms[currentMesh.ParentBone.Index] * renderMatrix; worldInverse = worldMatrix; effect.Begin(); effect.CurrentTechnique.Passes[0].Begin(); vMaterialDiffuse = new Vector4(currentMaterial.DiffuseColor.X, currentMaterial.DiffuseColor.Y, currentMaterial.DiffuseColor.Z, 1.0f); vMaterialSpecular = new Vector4(currentMaterial.SpecularColor.X, currentMaterial.SpecularColor.Y, currentMaterial.SpecularColor.Z, 1.0f); vMaterialAmbient = new Vector4(currentMaterial.AmbientLightColor.X, currentMaterial.AmbientLightColor.Y, currentMaterial.AmbientLightColor.Z, 1.0f); effect.Parameters["HasTexture"].SetValue(currentMaterial.TextureEnabled); effect.Parameters["matWorldViewProj"].SetValue(worldMatrix * viewMatrix * projMatrix); effect.Parameters["matWorld"].SetValue(worldMatrix); effect.Parameters["vMaterialDiffuse"].SetValue(vMaterialDiffuse); effect.Parameters["vMaterialSpecular"].SetValue(vMaterialSpecular); effect.Parameters["vMaterialAmbient"].SetValue(vMaterialAmbient); effect.Parameters["ColorMap"].SetValue(colorMap); // Render our meshpart graphics.GraphicsDevice.Vertices[0].SetSource(currentMesh.VertexBuffer, 0, currentMesh.MeshParts[1].VertexStride); graphics.GraphicsDevice.Indices = currentMesh.IndexBuffer; graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, currentMesh.MeshParts[1].BaseVertex, 0, currentMesh.MeshParts[1].NumVertices, currentMesh.MeshParts[1].StartIndex, currentMesh.MeshParts[1].PrimitiveCount); effect.CurrentTechnique.Passes[0].End(); effect.End(); Shader code: /* * Tutorial * XNA Shader programming * www.gamecamp.no * * by: Petri T. Wilhelmsen * e-mail: petriw@gmail.com * * Feel free to ask me a question, give feedback or correct mistakes! * */ // Global variables // Can be accessed from outside the shader, using Effect->Parameters["key"] where key = variable name float4x4 matWorldViewProj; // The projected and tranformed matrix float4x4 matWorld; // The world matrix float4 vecLightDir; // Light direction float4 vecEye; // Eye position float4 vLightDiffuse; // Diffuse color float4 vLightSpecular; // Specular color float4 vLightAmbient; // Ambient light float4 vMaterialDiffuse; //material diffuse float4 vMaterialSpecular; //material spec float4 vMaterialAmbient; //material ambient bool HasTexture; texture ColorMap; struct OUT { float4 Pos : POSITION; // Position float3 L : TEXCOORD0; // Light dir float3 N : TEXCOORD1; // Normal float3 V : TEXCOORD2; // View/Eye float2 Tex:TEXCOORD3; //texture color }; OUT VS(float4 Pos : POSITION, float3 N : NORMAL,float2 Tex:TEXCOORD) { OUT Out = (OUT)0; Out.Pos = mul(Pos, matWorldViewProj); Out.N = mul(N, matWorld); // Just pass textures trough Out.Tex = Tex; // Tranform Pos with matWorld in order to get the correct view vector. float4 PosWorld = mul(Pos, matWorld); Out.L = vecLightDir; // Eye position - vertex position returns the view direction from eye to the vertex. Out.V = vecEye - PosWorld; return Out; } // Create a sampler for the ColorMap texture using leanear filtering and clamping sampler ColorMapSampler = sampler_state { Texture = <ColorMap>; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; AddressU = Clamp; AddressV = Clamp; }; float4 PS(float3 L: TEXCOORD0, float3 N : TEXCOORD1, float3 V : TEXCOORD2,float2 Tex: TEXCOORD3) : COLOR { // normalize our vectors. float3 Normal = normalize(N); float3 LightDir = normalize(L); float3 ViewDir = normalize(V); // Get the color from ColorMapSampler using the texture coordinates in Tex. float4 Color; if(HasTexture==true) Color = tex2D(ColorMapSampler, Tex); else Color=vMaterialDiffuse; //Color=vMaterialDiffuse; // calculate diffuse light float Diff = saturate(dot(Normal, LightDir)); // Create our reflection shader // R = 2 * (N.L) * N – L float3 Reflect = normalize(2 * Diff * Normal - LightDir); // Calculate our specular light float Specular = pow(saturate(dot(Reflect, ViewDir)), 20); // R.V^n // return our final light equation // I = A + Dcolor * Dintensity * N.L + Scolor * Sintensity * (R.V)n //return Color*vLightAmbient + Color*vLightDiffuse * Diff + Color*vLightSpecular * Specular; //return Color*vLightAmbient + Color*vLightDiffuse * Diff + Color*vLightSpecular * Specular; return Color*vMaterialDiffuse; } technique SpecularLight { pass P0 { ZENABLE = TRUE; ZWRITEENABLE = TRUE; CULLMODE = CCW; // compile shaders VertexShader = compile vs_1_1 VS(); PixelShader = compile ps_2_0 PS(); } } [Edited by - chibitotoro0_0 on October 29, 2009 7:29:58 AM]

Share this post


Link to post
Share on other sites
Advertisement
I didn't read all the code but looks like on the images that you've accidently swapped the part meshes when rendering.

Share this post


Link to post
Share on other sites
What i think is happening from previous tests. Is that when I run part 1 and 2 together, in the part 2 code it actually redraws the content from part 1 (as if the buffers hadn't been cleared) using the material from part 2

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!