我在使用OpenGL绘图时遇到问题,我需要确切地看到在深度缓冲区中放置了什么值.谁能告诉我如何检索这些值?谢谢克里斯
我试图通过从标准GL 移植一些代码,在iOS上的OpenGL ES 2.0中使用一些阴影效果.部分示例涉及将深度缓冲区复制到纹理:
glBindTexture(GL_TEXTURE_2D, g_uiDepthBuffer);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 800, 600, 0);
Run Code Online (Sandbox Code Playgroud)
但是,似乎ES上不支持glCopyTexImage2D.读取相关的线程,似乎我可以使用帧缓冲区和片段着色器来提取深度数据.所以我试图将深度组件写入颜色缓冲区,然后复制它:
// clear everything
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// turn on depth rendering
glUseProgram(m_BaseShader.uiId);
// this is a switch to cause the fragment shader to just dump out the depth component
glUniform1i(uiBaseShaderRenderDepth, true);
// and for this, the color buffer needs to be on
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
// and clear it to 1.0, like how the depth buffer starts
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); …Run Code Online (Sandbox Code Playgroud) 我的顶点线是:
GLfloat vertices[]=
{
0.5f,0.5f,0.5f,
-0.5f,0.5f,0.5f,
-0.5f,-0.5f,0.5f,
0.5f,-0.5f,0.5f,//face 1
0.5f,-0.5f,-0.5f,
-0.5f,-0.5f,-0.5f,
-0.5f,0.5f,-0.5f,
0.5f,0.5f,-0.5f,//face 2
0.5f,0.5f,0.5f,
0.5f,-0.5f,0.5f,
0.5f,-0.5f,-0.5f,
0.5f,0.5f,-0.5f,//face 3
-0.5f,0.5f,0.5f,
-0.5f,0.5f,-0.5f,
-0.5f,-0.5f,-0.5f,
-0.5f,-0.5f,0.5f,//face 4
0.5f,0.5f,0.5f,
0.5f,0.5f,-0.5f,
-0.5f,0.5f,-0.5f,
-0.5f,0.5f,0.5f,//face 5
-0.5f,-0.5f,0.5f,
-0.5f,-0.5f,-0.5f,
0.5f,-0.5f,-0.5f,
0.5f,-0.5f,0.5f//face 6
};
Run Code Online (Sandbox Code Playgroud)
现在,我正在改变z绳索:
for(int i=0;i<24;i++)
vertices[i*3+2]*=10
glDepthRange(0,10.0);
Run Code Online (Sandbox Code Playgroud)
现在,我期待由于glDepthRange调用,z线将被映射到-0.5到0.5范围,并且我可以看到一个合适的立方体,但是它给出o/p,就像我在上面用变形几何注释glDepthRange一样.
我有以下C++ OpenGL代码,它渲染场景中像素的RGB值:
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, _windowWidth, _windowHeight);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
float aspectRatio = float(_windowWidth) / float(_windowHeight);
gluPerspective(60.0f, aspectRatio, 0.1f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
_camera.Update();
glLoadMatrixf(_camera.Matrix()[0]);
_scene.Render();
glutSwapBuffers();
Run Code Online (Sandbox Code Playgroud)
但是,我想改为渲染场景的深度缓冲区,即每个像素值都是摄像机前面的z距离.
也就是说,我目前正在获得顶部图像,但我想要底部图像(此处的图像):

我该怎么办呢?我不认为我正在使用着色器(我是吗?) - 这里给出的建议似乎表明这可能只适用于着色器.
还有这个代码,虽然这看起来像是使用着色器.修改我的代码以使用着色器有多难?
我有一个 JavaFX 3D 场景,在随机位置添加了一堆盒子和球体。似乎深度顺序都是错误的,我不知道为什么。我曾尝试使用 myNode.setDepthTest(DepthTest.ENABLE) 但这似乎没有帮助。我附上了一个应用程序,它应该可以证明这个问题。
知道我在这里可能做错了什么吗?非常感谢任何帮助。
import javafx.application.Application;
import javafx.application.ConditionalFeature;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.DepthTest;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SubScene;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Shape3D;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
public class Array3DTest extends Application {
double mousePosX;
double mousePosY;
double mouseOldX;
double mouseOldY;
double mouseDeltaX;
double mouseDeltaY;
/**
* This is the group which rotates
*/
Group root3D;
/**
* The camnera to
*/ …Run Code Online (Sandbox Code Playgroud) 我正在试验 3D 图形而不依赖任何 3D 库,例如 Java3D、OpenGL、DirectX 等。我有一个工作 Z 缓冲区(又名“深度缓冲区”),但我想不出绘制三角形的方法到那个缓冲区。(每个三角形都由 3D 中的三个点指定。)
任何人都可以提供在 Z 缓冲区中绘制三角形的伪代码吗?
我需要使用渲染的深度图从屏幕空间位置计算3D坐标。不幸的是,使用常规光线追踪对我来说不是一种选择,因为我要处理的单个几何图形包含大约5M张面。
所以我想我将执行以下操作:
这种工作,但是以某种方式定位点总是在物体的后面,因此我的深度计算可能有问题。
渲染深度图非常简单:
const depthTarget = new THREE.WebGLRenderTarget(w, h);
const depthMaterial = new THREE.MeshDepthMaterial({
depthPacking: THREE.RGBADepthPacking
});
// in renderloop
renderer.setClearColor(0xffffff, 1);
renderer.clear();
scene.overrideMaterial = depthMaterial;
renderer.render(scene, camera, depthTarget);
Run Code Online (Sandbox Code Playgroud)
使用以下命令在鼠标位置查找存储的颜色值:
renderer.readRenderTargetPixels(
depthTarget, x, h - y, 1, 1, rgbaBuffer
);
Run Code Online (Sandbox Code Playgroud)
并使用(从packing.glsl中的GLSL版本改编)转换回float:
const v4 = new THREE.Vector4()
const unpackDownscale = 255 / 256;
const unpackFactors = new THREE.Vector4(
unpackDownscale / (256 * 256 * 256),
unpackDownscale / (256 * 256),
unpackDownscale / 256,
unpackDownscale
); …Run Code Online (Sandbox Code Playgroud) 在 OpenGL 中,您可以像这样线性化深度值:
float linearize_depth(float d,float zNear,float zFar)
{
float z_n = 2.0 * d - 1.0;
return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
}
Run Code Online (Sandbox Code Playgroud)
(来源:https : //stackoverflow.com/a/6657284/10011415)
但是,Vulkan 处理深度值的方式略有不同(https://matthewwellings.com/blog/the-new-vulkan-coordinate-system/)。我不太明白它背后的数学原理,我必须对函数进行哪些更改才能使用 Vulkan 线性化深度值?
我正在尝试将球体渲染为冒名顶替者,但在计算球体表面点的深度值时遇到问题。
在这里,您可以看到当我围绕冒名顶替球体和与球体相交的“真实”立方体移动相机时会发生什么。
你可以看到,当我移动相机时,深度值不一致,立方体的某些部分应该在球体内部,取决于相机的位置,进出球体。
这些是 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 = …Run Code Online (Sandbox Code Playgroud)
我已经为此苦苦挣扎了一段时间,但我无法弄清楚是否可以为HDRP创建一个DepthMask着色器(如此处所述)。
对于我的确切用途,我试图在应用了材质的任何形状上创建一个“洞”,以显示在所有内容后面渲染的不同相机的内容。
我尝试摆弄着色器内的渲染队列、不同的 ZTest 和 ZWrite 组合,以及我发现的着色器的一些变体。最重要的是,我尝试摆弄我能想到的基本 HDRP 着色器的每个配置,这可能会有所作为。
我能得到的最接近的结果是使物体后面的透明材料消失。这确实意味着,如果我将所有不透明材质设置为透明,我会得到我想要的效果,但这并不理想,因为它破坏的东西比解决的东西多。理想情况下,我能够以某种方式在不透明材质上使用 HDRP 透明优先级系统,但我不确定这是否可行。
我不太确定下一步要尝试什么,任何帮助将不胜感激!