Я изучаю OpenGL, и у меня есть маленькая 3D-сцена с некоторыми объектами. В вершинном шейдере GLSL я умножаю вершины на матиксах следующим образом:
vertexPos= viewMatrix * worldMatrix * modelMatrix * gl_Vertex;
gl_Position = vertexPos;
vertexPos — это переменная переменная vec4, и я передаю ее фрагментному шейдеру.
Вот как эта сцена выглядит нормально:
нормальный рендер
Но тогда я хочу сделать отладочный рендер. Я пишу во фрагментном шейдере:
gl_FragColor = vec4(vertexPos.x, vertexPos.x, vertexPos.x, 1.0);
vertexPos умножается на все матрицы, включая матрицу перспективы, и я предполагал, что получу плавный градиент от центра экрана к правому краю, потому что они отображаются в квадрате от -1 до 1. Но похоже, что они находятся в пространстве экрана, но перспективная деформация не применяется. Вот что я вижу:
(не смотрите на красную линию и источник света, они используют разные шейдеры)
Если я разделю это примерно на 15, это будет выглядеть так:
gl_FragColor = vec4(vertexPos.x, vertexPos.x, vertexPos.x, 1.0)/15.0;
Может кто-нибудь объяснить мне, почему координаты не являются однородными и сцена по-прежнему отображается правильно с искажением перспективы?
Постскриптум если я попытаюсь поместить gl_Position во фрагментный шейдер вместо vertexPos, это не сработает.
Так называемый перспективное деление применяется к gl_Position
после того, как он вычислен в вершинном шейдере:
gl_Position.xyz /= gl_Position.w;
Но это не случится с вашими изменениями, если вы не сделаете это вручную. Таким образом, вам нужно добавить
vertexPos.xyz /= vertexPos.w;
в конце вашего вершинного шейдера. Обязательно сделай это после вы копируете значение в gl_Position
Вы не хотите делать деление дважды.
Других решений пока нет …