Камера (LootkAt + Ортогональная проекция) не хочет работать [SlimDX/D3D9]

Я не очень понимаю, как "камеры" работают с D3D9

Во-первых, как я настроил камеру:

     public Camera()
    {
        this.eye = new Vector3(0.0f, 0.0f, 0.0f);
        this.lookAt = new Vector3(0.0f, 0.0f, 1.0f);
        this.up = new Vector3(0.0f, 1.0f, 0.0f);
        viewMatrix = Matrix.LookAtLH(eye, lookAt, up);
        projectionMatrix = Matrix.OrthoLH(1 * zoomLevel, 1 * zoomLevel, 0.0f, 1.0f);
    }

И мои вершины:

        vertices = new VertexTexture[]
        {
            new VertexTexture()
            {
                Position =  new Vector4(0.0f, 0.0f, 0.0f, 1.0f),
                TextureCoord = new Vector2(0.0f, 1.0f)
            },
            new VertexTexture()
            {
                Position =  new Vector4(0.0f, model.Height, 0.0f, 1.0f),
                TextureCoord = new Vector2(0.0f, 0.0f)
            },
            new VertexTexture()
            {
                Position =  new Vector4(model.Width, model.Height, 0.0f, 1.0f),
                TextureCoord = new Vector2(1.0f, 0.0f)
            },
            new VertexTexture()
            {
                Position =  new Vector4(model.Width, 0.0f, 0.0f, 1.0f),
                TextureCoord = new Vector2(1.0f, 1.0f)
            }
        };

Оно работает. Я могу двигать камеру, масштабировать и т.д.

Но свойства камеры кажутся мне странными! Я думал, что это будет что-то вроде:

    public Camera()
    {
        this.eye = new Vector3(0.0f, 0.0f, 1.0f);
        this.lookAt = new Vector3(0.0f, 0.0f, 0.0f);
        this.up = new Vector3(0.0f, 1.0f, 0.0f);
        viewMatrix = Matrix.LookAtLH(eye, lookAt, up);
        projectionMatrix = Matrix.OrthoLH(1 * zoomLevel, 1 * zoomLevel, 0.1f, 100.0f);
    }

но с такими параметрами не работает. То же самое, если я изменю координату Z для своего плана (которую нужно установить на 0, чтобы работать).

Теперь я пытаюсь визуализировать другие объекты. Я генерирую вершины для сферы (она отлично работает на D3D 10, сфера с радиусом 1 генерируется вокруг (0;0;0)), но на экране ничего не появляется.

Я играл с параметрами глаза и взгляда, но я могу понять, как заставить его работать, так что же я делаю неправильно?


person qventura    schedule 08.02.2012    source источник


Ответы (2)


Сначала немного предыстории. В ортогональной проекции нам технически не нужно преобразование координаты Z, но на самом деле системе D3D все равно, какую проекцию вы используете - для устройства это просто матрица преобразования и ничего больше. Таким образом, координата Z всегда преобразуется независимо от типа проекции. С другой стороны, координаты камеры не преобразуются матрицей проекции (иначе позиционирование было бы кошмаром). Теперь давайте вернемся к вашей ситуации и посмотрим, что происходит.

Указав zn=0.1f в OrthoLH, вы объявляете, что это ваша минимальная глубина. Следовательно, каждая вершина будет сдвинута по глубине на -0,1f. С преобразованным макетом вершин Z будет 0,9f, но вы помните, что камера не пострадает? Итак, он все еще на глубине 1.0f, и поэтому вы ничего не видите: за камерой нет вершин.

Добавьте сюда ошибку вычисления плавающей запятой, и вы поймете, почему настройка камеры на 0,9f иногда помогает, а иногда нет. Тем не менее, установка position на 0.8f будет работать в любом случае.

person real4x    schedule 09.02.2012

Во-первых, спасибо за ответ. Мне удалось избежать проблемы, настроив камеру с такими свойствами:

        this.eye = new Vector3(0.0f, 0.0f, 0.0f);
        this.lookAt = new Vector3(0.0f, 0.0f, 1.0f);
        this.up = new Vector3(0.0f, 1.0f, 0.0f);

        viewMatrix = Matrix.LookAtLH(eye, lookAt, up);
        projectionMatrix = Matrix.OrthoLH(1 * zoomLevel, 1 * zoomLevel, 0.0f, 10000000.0f);    :D

Я еще раз прочитаю, что вы сказали, и подумаю о лучшем исправлении :)

Я думаю, что моя проблема связана с моими вершинами... например, я создаю сферу с радиусом 20, затем я преобразую эти вершины, чтобы они соответствовали сфере шириной 20 пикселей, путем масштабирования в соответствии с моими экранными координатами.

        worldMatrix = SlimDX.Matrix.Identity;
        worldMatrix = SlimDX.Matrix.Scaling(new Vector3(2.0f / ControlWidth, 2.0f / ControlHeight, 1.0f));
        worldMatrix = SlimDX.Matrix.Multiply(worldMatrix, SlimDX.Matrix.Translation(new Vector3(-1.0f, -1.0f, 0.0f)));

Мое масштабирование X / Y в порядке. Но как масштабировать координату Z? 2.0/((ControlHeight + ControlWidth)/2)?

Я еще раз прочитаю ваш анзер, чтобы все понять :)

person qventura    schedule 09.02.2012
comment
При масштабировании нет ничего плохого в том, чтобы делать то же самое, что и для X/Y. Описанная проблема касается только смещения (в частности - координаты Z вершины). С глазом, размещенным на Z=0.0, zn=0.0 и неотрицательными Z-координатами вершин, вы должны быть в порядке с любыми преобразованиями. - person real4x; 09.02.2012