Monogame 内容管道中的自定义默认效果

Custom Default Effect in Monogame Content Pipeline

所以我最终为 MonoGame 编写了我的第一个 HLSL 着色器,并设法以某种方式将它连接到我想要绘制的模型。 到目前为止,一切都很好。 然而 "somehow managed to do it code" 在我看来是丑陋的,并且可能不是实现此目标的预期方式:

internal Model(ContentManager content)
{
    mModel = content.Load<Microsoft.Xna.Framework.Graphics.Model>("models/CustomModel");
    // individual effect for individual models
    var effect = content.Load<Effect>("effects/CustomEffect").Clone();
    effect.Parameters["Texture"].SetValue(mModel.Meshes[0].MeshParts[0].Effect.Parameters["Texture"].GetValueTexture2D());

    foreach (var mesh in mModel.Meshes)
    {
        foreach (var meshPart in mesh.MeshParts)
        {
            meshPart.Effect = effect;
        }
    }
}

如您所见,我分别加载了我的模型和效果,并将模型的所有 BasicEffects 替换为我新加载的自定义效果。并保留旧的 TextureVariable。

我自己相信有一个更优雅的解决方案,一个涉及告诉 MonoGame 使用 CustomEffect 而不是 BasicEffect 的解决方案。 我知道使用 MGCB 工具我可以为 ModelProcessor 指定一个 DefaultEffect,但是我还没有找到我需要做什么才能在游戏崩溃的情况下指定我的效果并告诉我 effects/CustomEffect 不是'没有有效的效果。

那么有没有更好的方法来实现我现有代码的相同目标?如果是,怎么做?

看起来每个 effect 都有相同的值,因为它在 for-loop 中没有改变。

所以我认为您也可以在 meshPart 中定义 effect。所以你不必为每个人都检查 for-loop。

也可以在game1.csLoadcontentclass中创建效果,这样就不用每次都重新定义了。

据我所知,我想就是这样了。

您的解决方案是可用的主要解决方案,也是最灵活的。

您确实需要将效果克隆和参数行移动到 foreach 循环内并将其更改为:

var effect = content.Load<Effect>("effects/CustomEffect").Clone();
effect.Parameters["Texture"].SetValue(meshPart.Effect.Parameters["Texture"].GetValueTexture2D());

否则模型的所有部分将使用相同的纹理。

缺乏优雅之处在于这是 XNA 平台的直接 carry-over。

另一种选择是使您的参数和语义与 BasicEffect 的参数和语义匹配,此时您应该 能够在模型处理器中设置它。模型处理器期望参数存在并以特定顺序存在。