Странность прозрачности в OpenGL - PullRequest
0 голосов
/ 21 ноября 2019

Я пытаюсь визуализировать куб, где каждая сторона имеет 64х64 грани (32 * 32 квадрата, состоящие из 2 треугольников). Вершины удаляются из дубликата перед отправкой меша в OpenGL.

Я что-то напутал и получаю некоторые странные результаты:

  1. Куб прозрачен снаружи только в отрицательных позициях относительно камеры по оси X.
  2. Вертикальные полосы, которые делают его сплошным. Кто они такие? Я предполагаю, что это связано с тем, что куб состоит из 32х32 рядов граней (x2).
  3. У меня CullFace установлен на Back, но Cube сплошной изнутри (стороны не обтянуты). Я бы понял проблему, если FrontFace Cw / Ccw был неправильным по сравнению с порядком индексов, но в любом случае работает. Я ожидаю, что это отбросит одну из сторон.

Тщение в течение нескольких часов меня не смутило, поэтому я надеюсь, что кто-то может помочь.

enter image description hereПолное видео на YouTube .

#version 450 core

layout (location = 0) in mediump vec3 aPos;
layout (location = 1) in mediump vec3 aNormal;
layout (location = 2) in mediump vec2 aTexCoords;

out mediump vec3 vs_FragPos;
out mediump vec3 vs_Normal;
out mediump vec2 vs_Uv;
out mediump vec3 vs_LightPos;
out mediump vec3 vs_LightColor;

layout (location = 10) uniform  mat4 iProjection;
layout (location = 11) uniform  mat4 iView;
layout (location = 12) uniform  mat4 iModel;
layout (location = 20) uniform  vec3 lghtPos;
layout (location = 21) uniform  vec3 lightColor;

void main(void)
{
    gl_Position = iProjection * iView * iModel * vec4(aPos, 1.0);
    vs_FragPos = vec3(iProjection * vec4(aPos, 1.0));
    vs_Normal = aNormal;
    vs_Uv = aTexCoords;
    vs_LightPos = lghtPos;
    vs_LightColor = lightColor;
}
#version 450 core
in mediump vec3 vs_FragPos;
in mediump vec3 vs_Normal;
in mediump vec2 vs_Uv;
in mediump vec3 vs_LightPos;
in mediump vec3 vs_LightColor;
uniform sampler2D textureObject;

out mediump vec4 color;

float near = 0.1; 
float far  = 100.0; 

float LinearizeDepth(float depth) 
{
    float z = depth * 2.0 - 1.0; // back to NDC 
    return (2.0 * near * far) / (far + near - z * (far - near));    
}

void main(void)
{
    float depth = LinearizeDepth(gl_FragCoord.z) / far;
    color = vec4(vec3(depth), 1.0);
}

Я использую их в качестве основы для построения сетки, но каждая боковая грань повторяется для каждой соответствующей стороны. (Язык C #)

private static readonly Vector3[] _cubeVertices = new[]
{
    new Vector3(0, 0, 0), // 0
    new Vector3(1, 0, 0), // 1
    new Vector3(1, 1, 0), // 2
    new Vector3(0, 1, 0), // 3
    new Vector3(0, 1, 1), // 4
    new Vector3(1, 1, 1), // 5
    new Vector3(1, 0, 1), // 6
    new Vector3(0, 0, 1), // 7
};

private static readonly Vector3[] _cubeNormals = new[]
{
    Vector3Ex.Right, Vector3Ex.Left,
    Vector3Ex.Up, Vector3Ex.Down,
    Vector3Ex.Forward, Vector3Ex.Back
};
// For reference:
// Up = new Vector3(0F, 1F, 0F);
// Down = new Vector3(0F, -1F, 0F);
// Left = new Vector3(-1F, 0F, 0F);
// Right = new Vector3(1F, 0F, 0F);
// Forward = new Vector3(0F, 0F, 1F);
// Back = new Vector3(0F, 0F, -1F);

private static readonly int[] _cubeTriangles = new[]
{
    1, 2, 5, // East face
    1, 5, 6,
    0, 7, 4, // West face
    0, 4, 3,

    2, 3, 4, // Up face
    2, 4, 5,
    0, 6, 7, // Down face
    0, 1, 6,

    0, 2, 1, // South face
    0, 3, 2,
    5, 4, 7, // North face
    5, 7, 6,
};

Ответы [ 2 ]

1 голос
/ 21 ноября 2019

Я использовал RenderDoc для отладки своего приложения и нашел одну запись, которую я пропустил. Я использую NoesisGUI для рендеринга Xaml в верхней части экрана, и он отключил грань отбраковки, тест глубины и установил для маски глубины значение false (а также установил буфер трафарета). Сброс их для каждого кадра устранил проблему.

0 голосов
/ 21 ноября 2019

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

Кажется, вы наматываете свои треугольники по часовой стрелке. Это может произойти с индексированными сетками, закодированными вручную.

Сократите область применения и попытайтесь нарисовать 2 треугольника на лицо.

Передние треугольники должны быть намотаны против (против) по часовой стрелке, какпоэтому (для простоты приведена плоскость):

private static readonly Vector3[] PlaneVertices = new[]
{
    new Vector3(0, 0, 0), // 0
    new Vector3(1, 0, 0), // 1
    new Vector3(1, 1, 0), // 2
    new Vector3(0, 1, 0), // 3
};

private static readonly int[] _cubeTriangles = new[]
{
    0, 1, 2,
    0, 2, 3
};

Если вы посмотрите на это визуально:

3--------2
 |     /|
 |    / |
 |   /  |
 |  /   |
 | /    |
 |/     |
0--------1

Если вы повторите этот шаблон для каждой грани куба, аппаратное обеспечение будетгенерировать правильные нормали и правильно отображать. См. здесь для получения дополнительной информации о отбраковке и намотке.

Кроме того, как упомянул Спектре в своем комментарии, проверьте значения Z-буфера и убедитесь, что там достаточно точности для обработки всех вашихгеометрии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...