HLSL шейдеры, как нарисовать модель с ее оригинальными цветами? - PullRequest
1 голос
/ 17 февраля 2011

Я сделал эту очень простую 3D-модель экспортированной в формат .x с помощью Google SketchUp, модель представляет собой простой куб и не имеет текстур, только разные цвета для каждого его лица.

Я написал этот HLSLкод, чтобы попытаться отобразить эту модель с ее оригинальными цветами, но она не работает, я получаю "The current vertex declaration does not include all the elements required by the current vertex shader. Color0 is missing" при вызове метода 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, и до сих пор все, что я мог сделать, это нарисовать модель с другим цветом, определенным в шейдере по всей модели: [

1 Ответ

2 голосов
/ 17 февраля 2011

Я впервые смотрю на .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, я вижу, что геометрия сетки, каналы, такие как цвета и нормали, и т. д. хранятся как отдельные «объекты» (простокак в DOM в XNAs Content Pipeline).

В то время как ваша модель имеет определения для данных о положении (Mesh), нормальных данных (MeshNormals) и координат текстуры (MeshTextureCoords) (все они определены ниже раздела шаблонов) Iне может видеть сечения типа MeshVertexColors.

Вместо этого создается впечатление, что четыре материала определены и применены к граням моделей с использованием сечения

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

.

Итаку вас нет вершинных цветов для импортирования ModelProcessor или отображения вашего шейдера.

Возможно, в Sketchup есть опция для включения вершиныЦвета.Однако, если вы не можете найти / не хотите его искать, вы можете добавлять и удалять вершинные каналы в конвейере контента, создавая обработчик контента в проекте расширения конвейера контента.

(я знаю этозвучит очень неприятно, но на самом деле это действительно отличная функция, когда вы к ней привыкли!)

В Интернете довольно много уроков по этому поводу, но в двух словах:

  1. Зайдите вVS, щелкните правой кнопкой мыши, Добавить новый проект> Библиотека расширений конвейера содержимого
  2. В этом новом проекте добавьте новый элемент Content Processor, что-то вроде следующего:
  3. Перекомпилируйте и затем вВ поле Content Processor вашей модели .X файла в проекте Content выберите нового импортера (по имени, которое вы дадите ему в атрибуте DisplayName)

То, что это делает, по существу перехватывает данные изваш .X после того, как он был импортирован в объектную модель документа XNAs, и до того, как он был преобразован в новый класс Model, процессsor проверяет наличие цветового канала вершины и, если он не найден, генерирует и добавляет его, прежде чем ModelProcessor создаст VertexDeclaration и упакует все данные вершины в VertexBuffer для загрузки графическим процессором.

Это будет просто отображать куб в виде сплошного пурпурного цвета, но, по крайней мере, вы сможете увидеть, работает ли ваш шейдер.

[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 с ним при выходе - не проблема, просто действительно раздражает, когда вы забыли закомментировать его;)

...