1
\$\begingroup\$

Take this DrawModel() provided by MSDN:

private void DrawModel(Model m)
{
    Matrix[] transforms = new Matrix[m.Bones.Count];
    float aspectRatio = graphics.GraphicsDevice.Viewport.Width / 
        graphics.GraphicsDevice.Viewport.Height;
    m.CopyAbsoluteBoneTransformsTo(transforms);
    Matrix projection = 
        Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
        aspectRatio, 1.0f, 10000.0f);
    Matrix view = Matrix.CreateLookAt(new Vector3(0.0f, 50.0f, Zoom), 
        Vector3.Zero, Vector3.Up);

    foreach (ModelMesh mesh in m.Meshes)
    {
        foreach (BasicEffect effect in mesh.Effects)
        {
            effect.EnableDefaultLighting();

            effect.View = view;
            effect.Projection = projection;
            effect.World = gameWorldRotation * 
                transforms[mesh.ParentBone.Index] * 
                Matrix.CreateTranslation(Position);
        }
        mesh.Draw();
    }
}

How would I apply a custom effect to a model with that? Effect doesn't have View, Projection, or World members. This is what they recommend replacing the foreach loop with:

foreach (ModelMesh mesh in terrain.Meshes)
{
    foreach (Effect effect in mesh.Effects)
    {
        mesh.Draw();
    }
}

Of course, that doesn't really work. What else needs to be done?

EDIT: This is the effect I want to apply, generated by RenderMonkey:

string Procedural_Graphic_Effects_2D_Electricity_Single_Pass_ScreenAlignedQuad : ModelData = "..\\..\\..\\Program Files (x86)\\AMD\\RenderMonkey 1.82\\Examples\\Media\\Models\\ScreenAlignedQuad.3ds";

float4x4 World;
float4x4 View;
float4x4 Projection;

struct VS_OUTPUT {
   float4 Pos: POSITION;
   float2 texCoord: TEXCOORD;
};

VS_OUTPUT Procedural_Graphic_Effects_2D_Electricity_Single_Pass_Vertex_Shader_main(float4 Pos: POSITION){
   VS_OUTPUT Out;

   // Clean up inaccuracies
   Pos.xy = sign(Pos.xy);

   Out.Pos = float4(Pos.xy, 0, 1);
   Out.texCoord = Pos.xy;

   return Out;
}





float4 color
<
   string UIName = "color";
   string UIWidget = "Color";
   bool UIVisible =  true;
> = float4( 0.69, 0.48, 1.00, 1.00 );
float glowStrength
<
   string UIName = "glowStrength";
   string UIWidget = "Numeric";
   bool UIVisible =  true;
   float UIMin = 0.00;
   float UIMax = 200.00;
> = float( 144.00 );
float height
<
   string UIName = "height";
   string UIWidget = "Numeric";
   bool UIVisible =  true;
   float UIMin = 0.00;
   float UIMax = 2.00;
> = float( 0.44 );
float glowFallOff
<
   string UIName = "glowFallOff";
   string UIWidget = "Numeric";
   bool UIVisible =  true;
   float UIMin = 0.00;
   float UIMax = 0.30;
> = float( 0.02 );
float speed
<
   string UIName = "speed";
   string UIWidget = "Numeric";
   bool UIVisible =  true;
   float UIMin = 0.00;
   float UIMax = 3.00;
> = float( 1.86 );
float sampleDist
<
   string UIName = "sampleDist";
   string UIWidget = "Numeric";
   bool UIVisible =  true;
   float UIMin = 0.00;
   float UIMax = 0.04;
> = float( 0.01 );
float ambientGlow
<
   string UIName = "ambientGlow";
   string UIWidget = "Numeric";
   bool UIVisible =  true;
   float UIMin = 0.00;
   float UIMax = 1.00;
> = float( 0.50 );
float ambientGlowHeightScale
<
   string UIName = "ambientGlowHeightScale";
   string UIWidget = "Numeric";
   bool UIVisible =  true;
   float UIMin = 0.00;
   float UIMax = 8.00;
> = float( 1.68 );
float vertNoise
<
   string UIName = "vertNoise";
   string UIWidget = "Numeric";
   bool UIVisible =  true;
   float UIMin = -1.00;
   float UIMax = 1.00;
> = float( 0.78 );
float time_0_X : Time0_X;
texture Noise_Tex
<
   string ResourceName = "..\\..\\..\\Program Files (x86)\\AMD\\RenderMonkey 1.82\\Examples\\Media\\Textures\\NoiseVolume.dds";
>;
sampler Noise = sampler_state
{
   Texture = (Noise_Tex);
   ADDRESSU = WRAP;
   ADDRESSV = WRAP;
   ADDRESSW = WRAP;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
   MIPFILTER = LINEAR;
};
float4 Procedural_Graphic_Effects_2D_Electricity_Single_Pass_Pixel_Shader_main(float2 texCoord: TEXCOORD) : COLOR {
   float2 t = float2(speed * time_0_X * 0.5871 - vertNoise * abs(texCoord.y), speed * time_0_X);

   // Sample at three positions for some horizontal blur
   // The shader should blur fine by itself in vertical direction
   float xs0 = texCoord.x - sampleDist;
   float xs1 = texCoord.x;
   float xs2 = texCoord.x + sampleDist;

   // Noise for the three samples
   float noise0 = tex3D(Noise, float3(xs0, t)).r;
   float noise1 = tex3D(Noise, float3(xs1, t)).r;
   float noise2 = tex3D(Noise, float3(xs2, t)).r;

   // The position of the flash
   float mid0 = height * (noise0 * 2 - 1) * (1 - xs0 * xs0);
   float mid1 = height * (noise1 * 2 - 1) * (1 - xs1 * xs1);
   float mid2 = height * (noise2 * 2 - 1) * (1 - xs2 * xs2);

   // Distance to flash
   float dist0 = abs(texCoord.y - mid0);
   float dist1 = abs(texCoord.y - mid1);
   float dist2 = abs(texCoord.y - mid2);

   // Glow according to distance to flash
   float glow = 1.0 - pow(0.25 * (dist0 + 2 * dist1 + dist2), glowFallOff);

   // Add some ambient glow to get some power in the air feeling
   float ambGlow = ambientGlow * (1 - xs1 * xs1) * (1 - abs(ambientGlowHeightScale * texCoord.y));

   return (glowStrength * glow * glow + ambGlow) * color;
}


//--------------------------------------------------------------//
// Technique Section for Effect Workspace.Procedural Graphic Effects 2D.Electricity
//--------------------------------------------------------------//
technique Electricity
{
   pass Single_Pass
   {
      CULLMODE = NONE;

      VertexShader = compile vs_1_1 Procedural_Graphic_Effects_2D_Electricity_Single_Pass_Vertex_Shader_main();
      PixelShader = compile ps_2_0 Procedural_Graphic_Effects_2D_Electricity_Single_Pass_Pixel_Shader_main();
   }

}

EDIT: Simply changing the code in the way that MSDN suggested, my entire model is replaced by a smooth curved line (static, not animated) with the effect applied to said line. The line takes up the entire width of the screen, and does not move when the ship object moves. I know that the ship.position changes properly because other objects look in the direction that the ship is at all times. However, looking at what's drawn in place of the ship, it would appear to not move at all.

\$\endgroup\$
2
  • \$\begingroup\$ That's a lot of code with hardly any question. Can you elaborate more on what you've tried and why you think it didn't work? \$\endgroup\$ – MichaelHouse Apr 10 '12 at 21:51
  • \$\begingroup\$ My edit at the bottom describes what happened. \$\endgroup\$ – Fibericon Apr 11 '12 at 3:17
1
\$\begingroup\$

Effect has a Parameter collection, so you can do:

effect.Parameters["World"].SetValue(World)

\$\endgroup\$
1
  • \$\begingroup\$ A little more explanation would make this a better answer. \$\endgroup\$ – MichaelHouse Apr 10 '12 at 21:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.