Матрица проекции наклоняет плоскости ближе к камере - PullRequest
0 голосов
/ 03 ноября 2019

Я пишу очень простой каркасный рендер в Java с использованием графики. У меня есть проблема, которую я до сих пор не смог решить. Мой вывод выглядит следующим образом: Incorrect Cube

Однако я поместил тот же куб в Blender и переместил его в то же место, и он выглядел так: Correct cube from blender

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

Похоже, что плоскости ближе становятся больше быстрее по сравнению с другими. прочьЯ вижу этот эффект при уменьшении масштаба. Какова причина этого? Я пробовал различные методы, в том числе уменьшение кода, чтобы камера не двигалась, чтобы убедиться, что у меня нет ошибок при повороте камеры, а также использование формул, описанных в Интернете, для проецирования точки.

Мой код показался мне слишком длинным для сайта, поэтому я поместил его здесь: https://pastebin.com/2huLqexm

Вот фрагмент кода камеры (я считаю виновником):

public class Camera {
        public double nearDist;
        public double farDist;

        public Vec3 location;
        public Vec3 lookAt;

        public int screenWidth;
        public int screenHeight;
        public double right;
        public double top;

        public Camera(double fov, double nearDist, double farDist, 
                        int screenWidth, int screenHeight) {
            this.nearDist = nearDist;
            this.farDist = farDist;

            this.screenWidth = screenWidth;
            this.screenHeight = screenHeight;

            this.top = nearDist*Math.tan(Math.toRadians(fov/2.0));
            this.right = top*((double)screenWidth/screenHeight);
        }

        private int[] toDevice(Vec3 in) {
            double x = (in.x/right)*(screenWidth/2) + screenWidth/2;
            double y = screenHeight/2 - (in.y/top)*(screenHeight/2);
            int[] ret = {(int)x, (int)y};
            return ret;
        }

        public void render(Graphics g, Object3D obj) {
            for (int[] f : obj.faces) {
                Polygon p = new Polygon();
                for (int vi : f) {
                    Vec3 coord = obj.verts.get(vi);
                    Vec3 vert = new Vec3(-nearDist/coord.z * coord.x, -nearDist/coord.z * coord.y, 0);
                    int[] scr = toDevice(vert);
                    p.addPoint(scr[0], scr[1]);
                }
                g.setColor(Color.black);
                g.drawPolygon(p);
            }
        }
    }

Должно работать из коробки с javac Cube.java ; java Cube (Powershell / Bash)

...