HLSL着色器,如何用原始颜色绘制模型?

发布于 2024-10-17 18:12:06 字数 1148 浏览 10 评论 0原文

我使用 Google SketchUp 将这个非常简单的 3D 模型导出为 .x 格式,该模型是一个简单的立方体,没有纹理,每个面只有不同的颜色。

我编写了这个 HLSL 代码来尝试用它的原始颜色渲染这个模型,但是它不起作用,我得到一个 “当前顶点声明不包括当前顶点着色器所需的所有元素。Color0 是调用 ModelMesh.Draw() 方法时缺少”。这是我的 HLSL 代码:

float4x4 World;
float4x4 View;
float4x4 Projection;

struct AppToVertex
{
    float4 Position : POSITION0;
    float4 Color    : COLOR0;
};

struct VertexToPixel
{
    float4 Position : POSITION0;
    float4 Color    : COLOR0;
};

VertexToPixel ColoredVS(AppToVertex input)
{
    VertexToPixel output = (VertexToPixel)0;

    float4 iTransformed = mul(input.Position, World);
    float4 iView = mul(iTransformed, View);
    float4 iProjection = mul(iView, Projection);

    output.Position = iProjection;
    output.Color = input.Color;

    return output;
}

float4 ColoredPS(VertexToPixel input) : COLOR
{
    return input.Color;
}

technique Colored
{
    pass Pass0
    {
        VertexShader = compile vs_2_0 ColoredVS();
        PixelShader = compile ps_2_0 ColoredPS();
    }
}

这可能是一个菜鸟问题,我知道我可以通过简单地使用 BasicEffect 类(有效)来绘制这个模型,但我这样做只是为了学习 HLSL,到目前为止我所做的一切能够做的就是在整个模型的着色器中定义另一种颜色来绘制模型:[

I made this very simple 3D model exported to .x format with Google SketchUp, the model is a simple cube and has no textures, only different colors for each of it's face.

I have written this HLSL code to try to render this model with it's original colors, but it doesn't work, I get a "The current vertex declaration does not include all the elements required by the current vertex shader. Color0 is missing" when calling the ModelMesh.Draw() method. Here is my HLSL Code:

float4x4 World;
float4x4 View;
float4x4 Projection;

struct AppToVertex
{
    float4 Position : POSITION0;
    float4 Color    : COLOR0;
};

struct VertexToPixel
{
    float4 Position : POSITION0;
    float4 Color    : COLOR0;
};

VertexToPixel ColoredVS(AppToVertex input)
{
    VertexToPixel output = (VertexToPixel)0;

    float4 iTransformed = mul(input.Position, World);
    float4 iView = mul(iTransformed, View);
    float4 iProjection = mul(iView, Projection);

    output.Position = iProjection;
    output.Color = input.Color;

    return output;
}

float4 ColoredPS(VertexToPixel input) : COLOR
{
    return input.Color;
}

technique Colored
{
    pass Pass0
    {
        VertexShader = compile vs_2_0 ColoredVS();
        PixelShader = compile ps_2_0 ColoredPS();
    }
}

This is probably a noob question and I am aware that I could draw this model by simply using the BasicEffect class(which works), but I am doing this just for learning HLSL, and up to now all I was able to do was to draw a model with another color defined in the shader all over the model :[

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

耀眼的星火 2024-10-24 18:12:06

这是我第一次查看 .X,但我不相信 Sketchup 正在为您的模型导出顶点颜色。

(对这种格式更有经验的人,如果您发现任何错误,请纠正我!)

template Mesh {
<3D82AB44-62DA-11cf-AB39-0020AF71E433>
DWORD nVertices;
array Vector vertices[nVertices];
DWORD nFaces;
array MeshFace faces[nFaces];
[...]
}

template MeshVertexColors {
<1630B821-7842-11cf-8F52-0040333594A3>
DWORD nVertexColors;
array IndexedColor vertexColors[nVertexColors];
}

查看模型的 .X“声明”,我可以看到网格的几何形状、颜色和通道等通道。法线等存储为单独的“对象”(就像它们在 XNA 内容管道的 DOM 中一样)。

尽管您的模型具有位置数据 (Mesh)、法线数据 (MeshNormals) 和纹理坐标 (MeshTextureCoords) 的定义(全部在模板部分下定义),但我看不到任何 MeshVertexColors 类型的部分。

相反,似乎定义了四种材质,并使用该

 template MeshMaterialList {
<F6F23F42-7686-11cf-8F52-0040333594A3>
DWORD nMaterials;
DWORD nFaceIndexes;
array DWORD faceIndexes[nFaceIndexes];
[Material]
}

部分将其应用于模型面。

因此,您没有任何可供 ModelProcessor 导入的顶点颜色,也没有任何可供显示的着色器。

Sketchup 中可能有一个选项可以启用顶点颜色。但是,如果您找不到/不想查找它,则可以通过在内容管道扩展项目中创建内容处理器来添加和删除内容管道中的顶点通道。

(我知道这听起来确实令人不快,但实际上,当你习惯了它时,这是一个非常好的功能!)

网上有很多关于此的教程,但简而言之:

  1. 进入 VS,右键单击,添加新项目>;内容管道扩展库
  2. 在该新项目中,添加一个新的内容处理器项目,类似于下面的内容。
  3. 重新编译,然后在内容项目中的模型 .X 文件条目的内容处理器字段中,选择新的导入器(按您在 DisplayName 属性中指定的名称),

这实际上是在拦截 .X 之后的数据它已被导入到 XNA 文档对象模型中,并且在将其处理为新的模型类之前,处理器会检查是否存在顶点颜色通道,如果未找到,则在 ModelProcessor 创建顶点颜色通道之前生成并添加它。 VertexDeclaration 并将所有顶点数据打包到 VertexBuffer 中以供 GPU 加载。

这只会将立方体显示为纯紫色,但至少您可以看到着色器是否正在工作。

[ContentProcessor(DisplayName = "Processor to make sure we have vertex colours in all models")]
public class Character_Model_Processor : ModelProcessor
{
    public override ModelContent Process(NodeContent input, ContentProcessorContext context)
    {
        foreach(NodeContent c in input.Children)
        {
            if(c is MeshContent)
            {
                foreach(GeometryContent g in (c as MeshContent).Geometry)
                {
                    //Stop here and check out the VertexContent object (g.Vertices) and the Channels member of it to see how
                    //vertex data is stored in the DOM, and what you can do with it.
                    System.Diagnostics.Debugger.Launch();

                    AddVertexColorChannel(g.Vertices);
                }
            }
        }

        ModelContent model = base.Process(input, context);

        return model;
    }

    private void AddVertexColorChannel(VertexContent content)
    {
        if(content.Channels.Contains(VertexChannelNames.Color(0)) == false)
        {
            List<Microsoft.Xna.Framework.Color> VertexColors = new List<Microsoft.Xna.Framework.Color>();

            for (int i = 0; i < content.VertexCount; i++)
            {
                VertexColors.Add(Color.Purple);
            }

            content.Channels.Add(VertexChannelNames.Color(0), VertexColors);
        }
    }
}

祝你好运,抱歉,如果你已经知道其中的大部分内容,我想你可能知道所有关于管道修改的信息,如果你正在编写自己的着色器,但更好安全:)

编辑:只是关于 System.Diag... 行的注释,如果当你闯入调试器时,请确保当你完成探索时按下 F5 并让它运行它的进程,否则当它退出时它会带走你的主 VS 窗口 - 这不是一个问题,只是当你忘记注释它时真的很烦人出去 ;)

This is the first time i've looked at a .X but I don't believe that Sketchup is exporting vertex colours for your model.

(Someone who is more experienced with this format please correct me if you see anything wrong!)

template Mesh {
<3D82AB44-62DA-11cf-AB39-0020AF71E433>
DWORD nVertices;
array Vector vertices[nVertices];
DWORD nFaces;
array MeshFace faces[nFaces];
[...]
}

template MeshVertexColors {
<1630B821-7842-11cf-8F52-0040333594A3>
DWORD nVertexColors;
array IndexedColor vertexColors[nVertexColors];
}

Looking at your model's .X 'declarations', I can see the mesh's geometry, channels such as colours & normals, etc are stored as seperate 'objects' (just like they are in the DOM in XNAs Content Pipeline).

Whereas your model has definitions for position data (Mesh), normal data (MeshNormals) and texture coords (MeshTextureCoords) (all defined below the templates section) I can see no section of the type MeshVertexColors.

Instead it appears that four Materials are defined, and applied to your models faces using the

 template MeshMaterialList {
<F6F23F42-7686-11cf-8F52-0040333594A3>
DWORD nMaterials;
DWORD nFaceIndexes;
array DWORD faceIndexes[nFaceIndexes];
[Material]
}

section.

So you don't have any vertex colours for ModelProcessor to import, or your shader to display.

There is probably an option in Sketchup to enable Vertex Colours. However if you can't find/don't want to look for it, you can add and remove vertex channels in the Content Pipeline by creating a Content Processor in a Content Pipeline Extension project.

(I know this sounds really unpleasant but acctually this is a really great feature when you get used to it!)

There are quite a few tutorials online about this but in a nutshell:

  1. Go into VS, right click, Add New Project > Content Pipeline Extension Library
  2. In that new project, add a new Content Processor item, something along the lines of that below.
  3. Recompile and then in the Content Processor field of your models .X file entry in the Content project, select your new importer (by the name you give it in the DisplayName attribute)

What this is doing is essentially intercepting the data from your .X after it has been imported into XNAs Document Object Model, and before it is processed into a new Model class, the processor checks for the presence of a vertex colour channel, and if one is not found, generates and adds it, before the ModelProcessor creates the VertexDeclaration and packs all the vertex data into a VertexBuffer to be loaded by the GPU.

This will just the display the cube as a solid purple but at least you can see if your shader is working.

[ContentProcessor(DisplayName = "Processor to make sure we have vertex colours in all models")]
public class Character_Model_Processor : ModelProcessor
{
    public override ModelContent Process(NodeContent input, ContentProcessorContext context)
    {
        foreach(NodeContent c in input.Children)
        {
            if(c is MeshContent)
            {
                foreach(GeometryContent g in (c as MeshContent).Geometry)
                {
                    //Stop here and check out the VertexContent object (g.Vertices) and the Channels member of it to see how
                    //vertex data is stored in the DOM, and what you can do with it.
                    System.Diagnostics.Debugger.Launch();

                    AddVertexColorChannel(g.Vertices);
                }
            }
        }

        ModelContent model = base.Process(input, context);

        return model;
    }

    private void AddVertexColorChannel(VertexContent content)
    {
        if(content.Channels.Contains(VertexChannelNames.Color(0)) == false)
        {
            List<Microsoft.Xna.Framework.Color> VertexColors = new List<Microsoft.Xna.Framework.Color>();

            for (int i = 0; i < content.VertexCount; i++)
            {
                VertexColors.Add(Color.Purple);
            }

            content.Channels.Add(VertexChannelNames.Color(0), VertexColors);
        }
    }
}

Good luck, sorry if you already knew most of that, I guess you probably know all about the pipeline modifications if you are writing your own shaders but better safe :)

EDIT: Just a note about that System.Diag... line, if you break into the debugger, make sure you when you're done exploring that you hit F5 and let it run its course otherwise it takes your main VS window with it when it exits - not a problem just really annoying when you forget to comment it out ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文