Arc*_* Pi 4 c++ opengl 3d graphics depth-buffer
我正在尝试将球体渲染为冒名顶替者,但在计算球体表面点的深度值时遇到问题。
在这里,您可以看到当我围绕冒名顶替球体和与球体相交的“真实”立方体移动相机时会发生什么。
你可以看到,当我移动相机时,深度值不一致,立方体的某些部分应该在球体内部,取决于相机的位置,进出球体。
这些是 impostor-sphere 的顶点和片段着色器。
顶点着色器:
#version 450 core
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec2 coords;
void main()
{
switch (gl_VertexID)
{
case 0:
coords = vec2(-1.0f, -1.0f);
break;
case 1:
coords = vec2(-1.0f, +1.0f);
break;
case 2:
coords = vec2(+1.0f, -1.0f);
break;
case 3:
coords = vec2(+1.0f, +1.0f);
break;
}
// right & up axes camera space
vec3 right = vec3(view[0][0], view[1][0], view[2][0]);
vec3 up = vec3(view[0][1], view[1][1], view[2][1]);
vec3 center = vec3(0.0f);
float radius = 1.0f;
// vertex position
vec3 position = radius * vec3(coords, 0.0f);
position = right * position.x + up * position.y;
mat4 MVP = projection * view * model;
gl_Position = MVP * vec4(center + position, 1.0f);
}
Run Code Online (Sandbox Code Playgroud)
片段着色器:
#version 450 core
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
in vec2 coords;
out vec4 pixel;
void main()
{
float d = dot(coords, coords);
if (d > 1.0f)
{
discard;
}
float z = sqrt(1.0f - d);
vec3 normal = vec3(coords, z);
normal = mat3(transpose((view * model))) * normal;
vec3 center = vec3(0.0f);
float radius = 1.0f;
vec3 position = center + radius * normal;
mat4 MVP = projection * view * model;
// gl_DepthRange.diff value is the far value minus the near value
vec4 clipPos = MVP * vec4(position, 1.0f);
float ndcDepth = clipPos.z / clipPos.w;
gl_FragDepth = ((gl_DepthRange.diff * ndcDepth) + gl_DepthRange.near + gl_DepthRange.far) * 0.5f;
pixel = vec4((normal + 1.0f) * 0.5f, 1.0f);
}
Run Code Online (Sandbox Code Playgroud)
我按照这个例子来计算深度值。
我传递给着色器的模型矩阵是一个单位矩阵,因此它不会影响操作。
非常感谢你的帮助!!
你的深度计算很好。您遇到的问题基本上与您从中进行深度计算的教程中概述的问题相同。这是该问题的不同表现形式,但它们都来自同一个地方:您对position相对于现实,不正确。所以错误的值被输入到深度计算中;您没有得到正确的结果也就不足为奇了。
这是您的基本问题的夸张的 2D 表示:
我们在视图处,看着点。根据您的冒名顶替者代码,我们将通过将 Point 向前垂直投影到平面直到它碰到球体来计算 Point 的位置。该计算产生了Impostor点。
然而,正如你所看到的,这不是真人秀。如果我们从 Point 到 View 画一条线(它代表我们应该从 View 在那个方向看到的东西),我们看到的球体上的第一个位置是 Real。这是非常从冒名顶替远。
由于根本问题是您的冒名顶替者位置计算是错误的,解决该问题的唯一方法是使用正确的冒名顶替者计算。正确的方法是(以一种或另一种方式)通过从 View 对球体进行光线追踪。这就是教程所做的。