Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Программирование игр, графики и искусственного интеллекта > Нет нормалей в Mesh


Автор: EgoBrain 8.11.2008, 11:54
Скачал готовый Mesh объект в формате .3ds, конвертнул в .x через Conv3ds.exe, открываю получившийся .x-файл в  DirectX View (утилита поставляемая с DirectX SDK March 2008) все нормально: есть материалы (текстуры) есть нормали, только 1 недостаток: при перерисовки появляется какой-то "мусор" на моделе (по объекту как бы разбрасываются мелкие полигоны, преимущественно по краям), если приблизить до максимума, то "мусор" исчезает. Открываю этот же .x-файл в MeshView (утилита поставляемая с DirectX SDK Summer 2004) - "мусора" нет. И еще одна проблемка: загружаю модель в своей MDX-программе - нет нормалей :(  И так: почему в одной программе "мусор" есть, а в другой (более старой) - нет, и почему у меня в программе объект без нормалей (если дело в них)?

Вот скрины:

Объект с "мусором"                           user posted image
Объект без "мусора"                         user posted image
Объект без нормалей в моей проге user posted image

Вот код проги:

Код

namespace Mouse
{
    public partial class Form1 : Form
    {
         ...
         
        private Mesh sofa = null;

        
        private Material[] sofaMaterials;
        private Texture[] sofaTextures;

        ...

        private void LoadMesh(string file, ref Mesh mesh, string texturefilename, ref Material[] meshMaterials,
            ref Texture[] meshTextures) //Метод загрузки Mesh-объекта
        {
            ExtendedMaterial[] mtrl;

            mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);

            if ((mtrl != null) && (mtrl.Length > 0))
            {
                meshMaterials = new Material[mtrl.Length];
                meshTextures = new Texture[mtrl.Length];

                for (int i = 0; i < mtrl.Length; i++)
                {
                    meshMaterials[i] = mtrl[i].Material3D;

                    if ((mtrl[i].TextureFilename != null) && (mtrl[i].TextureFilename != string.Empty)
                        && texturefilename != null)
                    {
                        meshTextures[i] = TextureLoader.FromFile(device, texturefilename);
                    }
                }
            }
        }

         private void DrawMesh(ref Mesh mesh, ref Material[] meshMaterials, 
            ref Texture[] meshTextures, float yaw, float pitch, float roll, float x, float y, float z, 
            float xScaling, float yScaling, float zScaling)  //Метод рисования Mesh-объекта
        {
            device.Transform.World = Matrix.RotationYawPitchRoll(yaw, pitch, roll) *
                 Matrix.Scaling(xScaling, yScaling, zScaling) * Matrix.Translation(x, y, z);

            for (int i = 0; i < meshMaterials.Length; i++)
            {
                device.Material = meshMaterials[i];
                if (meshTextures.Length > 0)
                device.SetTexture(0, meshTextures[i]);
                mesh.DrawSubset(i);
            }
        }


Эта же самая прога нормально рисует .x объекты, которые идут с SDK, и я еще пробовал сферу в 3ДМаксе с текстурой делать, потом конвертнул в .x той же прогой Conv3ds.exe - все норм, а вот с этой софой фигня какая-та.
P.S. Как сделать spoiler? А то картинки скрыть поидее нада smile 

Автор: mr.DUDA 8.11.2008, 19:48
Стоит проверить, есть ли wireframe режиме "лишние" полигоны (там где мусор). Возможно также нормали не нормализованы (длина не 1), или в твоей проге шейдер освещения сделан некорректно. С Conv3ds.exe не работал ни разу, просто предположения.

Автор: EgoBrain 9.11.2008, 05:54
Да х3 конвертер виноват или нет, я о нем на всякий случай упомянул. А с освящением (оно не шейдерное) все в порядке, в этой же сцене остальные объекты нормально отображаются и те же функции их грузят и рисуют. В wireframe мусора нету, да и откуда бы он взялся, если в других прогах все норм отображается. Но меня все-таки больше нормали беспокоят, мне эти объекты в проект внедрять нада.

Добавлено через 10 минут
Как в DX проверить на нормализвацию и нормализовать нормали?

Добавлено через 10 минут и 32 секунды
 smile 

Автор: EgoBrain 9.11.2008, 08:29
Попробовал другой Mesh объект. Судя по изображению я уже начал сомневаться в том, что дело в нормалях. Посмотрите на изображение, в чем тут дело, почему моя картинки не такая качественная как в утилитах DirectX SDK и в 3DsMax?

Моя катинка:                     user posted image
DirectX SDK Util картинка: user posted image
3DsMax картинка:             user posted image

Автор: EgoBrain 9.11.2008, 11:44
Дальше хуже. Беру еще более сложный объект - модель BMW325I. И что же происходит когда я ее загружаю и рисую этими самыми функциями:

Это то, что рисует моя программа: user posted image
А это как должно быть:                    user posted image
В чем же дело, я в шоке, просто плачу. Наверное чего-то не хватает, каких-то объектов рисования... Пожалуйста помогите кто разбирается.

Автор: mr.DUDA 9.11.2008, 12:06
Последние скрины больше всего похожи на засветку. В свойства diffuse, ambient и specular у материала (буде таковой имеется в Mesh или MeshPart) заглянуть пробовали?

Автор: EgoBrain 9.11.2008, 13:13
Получается к каждому объекту необходимо индивидуально подбирать эти параметры?

Добавлено через 6 минут и 47 секунд
Посмотрел свойства части материалов этого объекта Specular и Diffuse вроде ничего необычного, а вот Ambient значение все имеют одно и то же A=255, R=0, G=0, B=0.

Автор: mr.DUDA 9.11.2008, 19:47
EgoBrain, альфа в освещении вообще не участвует. Засветка (если это она) происходит от умножения цвета текстуры или цвета объекта (если без текстуры) на значение большее чем 1. В результате: out_color = texColor * (diffuseMat * diffuseLight + specularColor * specularLight + ambientMat * ambientLight), где texColor не участвует если нет текстуры. Если одна из переменных выходит за рамки 0..1, получится засветка. Значения цветов 0..255 отображаются на 0..1 при расчётах.

Добавлено через 3 минуты и 53 секунды
P.S. а вообще я не телепат чтобы читать чужие исходники и модели на расстоянии, если нужна помощь - скинь сюда или мне на мыло проект, попробуем вместе разобраться...

Автор: EgoBrain 10.11.2008, 12:37
Ок. Вот проект скидываю на мыло = 2,74 Мб: VS 2008 Proj подойдет?
P.S. Все по учебнику, пока ничего своего не придумывал по DX  smile 

Автор: mr.DUDA 11.11.2008, 11:04
Смотри в ПМ.

Автор: mr.DUDA 11.11.2008, 13:37
Это были нормали, хотя в PIX например всё с ними в порядке (или пикс их нормализует, непонятно). Чтобы пофиксить баг, добавь в SetUpCamera строку:
Код
device.RenderState.NormalizeNormals = true;


Будет как на скриншоте.

З.Ы. ещё посоветовал бы поставить в конструкторе Width и Height например 800 на 600, а в InitializeDirectX брать размеры так:
Код
            pp.BackBufferWidth = this.ClientRectangle.Width;
            pp.BackBufferHeight = this.ClientRectangle.Height;


И при создании девайса ставь HardwareVertexProcessing, будет летать намного быстрее  smile 

Автор: EgoBrain 11.11.2008, 14:07
Во!  smile  Спасибо добрый человек! Картинка ощутима улучшилась!
Но на этом мои вопросы не иссекают, а наоборот умножаются  smile 
Для начала, как опытный программер, что скажете о концепции кода, правильно и рационально ли построение сцены организовано и т.п.?
NormalizeNormals в RenderState это и есть нормализация нормалей, о которой писали выше?
Что такое "PIX"? И по поводу программируемого конвейра: в учебники говорилось, что Флаг - HardwareVertexProcessing необходим для шейдеров, а про скорость я даже и не думал. Ну я в этой теме еще нуб. Надеюсь хоть на какие-нить мало мальские ответы. Понимаю, что про все нада читать статьи и т.п., но от разнообразия и количества информации, которую необходимо еще узнать и осмыслить разбегаются мылси, а ответ тут был бы проще smile

Добавлено через 1 минуту и 44 секунды
По части установки размеров буфера кадра при изменении размеров окна: это происходит автоматически средой исполнения.

Добавлено через 6 минут и 21 секунду
Благодаря нормализации нормалей затенение объектов стало более сглаженным, до этого в глаза бросалось как отдельные полигоны затемняются. Выглядело неудовлетворительно.

Автор: mr.DUDA 11.11.2008, 14:29
Цитата(EgoBrain @  11.11.2008,  14:07 Найти цитируемый пост)
Но на этом мои вопросы не иссекают, а наоборот умножаются 

 smile 

Цитата(EgoBrain @  11.11.2008,  14:07 Найти цитируемый пост)
По части установки размеров буфера кадра при изменении размеров окна: это происходит автоматически средой исполнения. 

Начальный размер для бэкбуффера ты сам задаёшь; проверь, поставив к примеру pp.BackBufferWidth = this.Width / 2, увидишь заблуренную картинку. ДиректХ сам меняет размеры в случае сброса девайса при ресайзинге и т.д.

Цитата(EgoBrain @  11.11.2008,  14:07 Найти цитируемый пост)
что скажете о концепции кода, правильно и рационально ли построение сцены организовано и т.п.?

Ну это не мне решать. Со временем опыт подскажет, что и где можно было бы улучшить, а так если по коду - сильно не к чему придраться. smile 

Цитата(EgoBrain @  11.11.2008,  14:07 Найти цитируемый пост)
NormalizeNormals в RenderState это и есть нормализация нормалей, о которой писали выше?

Это рендер стейт, который не на всех картах может поддерживаться (в капсах посмотреть можно, есть ли поддержка). Вообще нормализовать нормали надо непосредственно при их генерации, т.е. один раз, а не заставлять GPU выполнять несколько лишних умножений и извлечение корня. В принципе это не критично по производительности, современная видеокарта среднего уровня даже не поперхнётся от этого рендерстейта.

Цитата(EgoBrain @  11.11.2008,  14:07 Найти цитируемый пост)
Что такое "PIX"?

Мегатулза по адресу "Program Files\Microsoft DirectX SDK (August 2008)\Utilities\bin\x86\PIXWin.exe", с жутким интерфейсом и миллионом возможностей, этакий швейцарский нож от Microsoft, позволяет к примеру захватывать полную инфу о конкретном кадре а после выхода из приложения - просматривать и анализировать что происходило на каждом вызове Direct3D. Из самого рулеза - просмотр содержимого буферов и отладка шейдеров. Смотри скриншот для примера.

Цитата(EgoBrain @  11.11.2008,  14:07 Найти цитируемый пост)
И по поводу программируемого конвейра: в учебники говорилось, что Флаг - HardwareVertexProcessing необходим для шейдеров, а про скорость я даже и не думал.

В доке по DX SDK ничего про это не сказано (см. топик "Processing Vertex Data (Direct3D 9)"). Факт в том, что работает быстрее, т.к. карточка а не CPU занимается обработкой вершин.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)