Я пытаюсь внедрить систему отложенных надписей в пространстве экрана, используя OpenGL, следуя статье под названием «Рисование материала на других объектах с отложенными надписями в пространстве экрана», ссылка: http://martindevans.me/game-development/2015/02/27/Drawing-Stuff-On-Other-Stuff-With-Deferred-Screenspace-Decals/.
Красный куб затенен поверхсцена, которая соответствует стене с маской глубины, установленной в false.Ссылка на изображение (куб без границ): https://gyazo.com/8487947bd4afb08d8d0431551057ad6f
Глубинный буфер от стены вместе с некоторыми выходами вершинного шейдера используются для вычисления положения пространства объектов в стене в пределах размеров куба. Связанные проверки гарантируют, чточто каждый пиксель куба, находящийся за пределами пространственного положения объекта стены, отбрасывается.
Проблема в том, что границы не работают должным образом, куб полностью исчезает.
Потенциалнеисправности
Я проверил, правильно ли работает буфер глубины, визуализируя его в проходе освещения, и, кажется, он работает нормально.Глубинный буфер хранится в приложении цвета в gbuffer с плавающим размером GL_RGB32F.Ссылка на изображение (визуализация глубинного буфера Ligtingpass далекой стены): https://gyazo.com/69920a532ca27aa9f57478cb57e0c84c
Код шейдера декаля
VertexShader
// Vertex positions
vec4 InputPosition = vec4(aPos, 1);
// Viewspace Position
PositionVS = view* model* InputPosition;
// Clipspace Position
PositionCS = projection*PositionVS;
gl_Position = PositionCS;
FragmentShader
// Position on the screen
vec2 screenPos = PositionCS.xy / PositionCS.w;
// Convert into a texture coordinate
vec2 texCoord = vec2((1 + screenPos.x) / 2 + (0.5 / resolution.x), (1 -
screenPos.y) / 2 + (0.5 / resolution.y));
// Sampled value from depth buffer
vec4 sampledDepth = texture(gDepth, texCoord);
// View-direction
vec3 viewRay = PositionVS.xyz * (farClip / -PositionVS.z);
// Wallposition in view-space
vec3 viewPosition = viewRay*sampledDepth.z;
// Transformation from view-space to world-space
vec3 WorldPos = (invView*vec4(viewPosition, 1)).xyz;
// Transformation from world-space to object-space
vec3 objectPosition = (invModel*vec4(WorldPos, 1)).xyz;
// Bounds check, discard pixels outside the wall in object-space
if (abs(objectPosition.x) > 0.5) discard;
else if (abs(objectPosition.y) > 0.5) discard;
else if (abs(objectPosition.z) > 0.5) discard;
// Color to Gbuffer
gAlbedoSpec = vec4(1, 0, 0, 1);
Кодdescription
invView и invModel являются инверсией матриц вида и модели соответственно.Обратный расчет матрицы выполняется в ЦП и передается в виде фрагментов фрагменту шейдера.farClip - расстояние до дальней плоскости камеры (здесь установлено значение 3000).gDepth - это текстура глубины Гбуффера.
Проблема
Часть стены, которая соответствует кубу, должна быть затенена красным, как показано ниже, ее явно нет.
Ссылка на изображение (куб с границами): https://gyazo.com/ab6d0db2483a969db932d2480a5acd08
Я предполагаю, что проблема заключается в том, как позиция в пространстве вида преобразуется в позицию в пространстве объектов, но не могу разобраться!