因此,当我应用于其中的一些纹理具有alpha通道时,我试图找出在OpenGL中渲染3D模型的最佳方法.
当我启用了深度缓冲区并开始绘制3D模型中的所有三角形时,如果它绘制了一个位于模型中另一个三角形前面的三角形,那么当它到达它时它将不会渲染后三角形.问题是当前三角形具有alpha透明度时,应该能够看到它后面的三角形,但后面的三角形仍然没有渲染.
禁用深度缓冲区可以消除这个问题,但会产生一个明显的问题:如果三角形是不透明的,那么如果渲染后它仍然会在它后面渲染三角形.
例如,我正在尝试渲染一棵松树,它基本上是一些堆叠在一起的锥体,它们具有透明的底座.下图显示了启用深度缓冲区时出现的问题:

您可以看到如何仍然可以看到透明三角形的轮廓.
下图显示了禁用深度缓冲区时的样子.

在这里,您可以看到树背面的一些三角形是如何在树的其余部分前呈现的.
任何想法如何解决这个问题,并正确渲染松树?
PS我正在使用着色器渲染所有内容.
我正在尝试替换gl_FragDepthOpenGL ES 2.0中缺少的OpenGL功能.
我需要一种在片段着色器中设置深度的方法,因为在顶点着色器中设置它对于我的目的来说不够准确.AFAIK唯一的方法是使用渲染到纹理的帧缓冲区,在其上完成第一个渲染过程.该深度纹理存储屏幕上每个像素的深度值.然后,深度纹理附加在最终渲染过程中,因此最终渲染器知道每个像素的深度.
由于iOS> = 4.1支持GL_OES_depth_texture,我正在尝试使用GL_DEPTH_COMPONENT24或GL_DEPTH_COMPONENT16用于深度纹理.我正在使用以下调用来创建纹理:
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textureId, 0);
Run Code Online (Sandbox Code Playgroud)
帧缓冲区创建成功,但我不知道如何继续.我对附加到帧缓冲区的深度纹理缺乏一些基本的了解.
gl_FragColor是,即使纹理是深度纹理,仍然是RGBA值.我无法在片段着色器中设置深度,因为gl_FragDepth在OpenGL ES 2.0中缺少sampler2D?glTexImage2D来GL_DEPTH_COMPONENT16,GL_DEPTH_COMPONENT16_OES还是GL_DEPTH_COMPONENT24_OES?GL_DEPTH_ATTACHMENT?是否正确?如果我改变它GL_COLOR_ATTACHMENT0,我得到一个不完整的帧缓冲.许多人使用通常的透视矩阵与第三行像这样:
(0 0 (n+f)/(n-f) 2*n*f/(n-f))
Run Code Online (Sandbox Code Playgroud)
但它在远剪裁面附近浮动精度有问题.结果是z战斗.如何使用z的线性变换?让我们将矩阵第三行更改为:
(0 0 -2/(f-n) (-f-n)/(f-n))
Run Code Online (Sandbox Code Playgroud)
它将是从[-n,-f]到[-1,1]的线性变换z.然后,我们将在顶点着色器中添加该行:
gl_Position.z *= gl_Position.w;
Run Code Online (Sandbox Code Playgroud)
透视分割后,z值将被恢复.
为什么不到处使用?我在互联网上发现了很多文章.所有这些都使用了通常的矩阵.我描述的线性变换是否存在我看不到的问题?
更新:这不是重复这个.我的问题不是关于如何做线性深度缓冲.就我而言,缓冲区已经是线性的.我不明白,为什么这个方法没用?内部webgl管道中是否存在陷阱?
试图了解与通用移动目标的 WebGL 开发相关的许多问题,现在我需要将深度信息存储在纹理附件中以供以后检索和后处理。
JavaScript:
var depthRB = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthRB);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRB);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
Run Code Online (Sandbox Code Playgroud)
顶点着色器:
precision mediump float;
uniform mat4 u_transformMatrix;
attribute vec3 a_position;
varying float v_depth;
void main() {
vec4 tcoords = u_transformMatrix * vec4(a_position, 1.0);
v_depth = 0.5 * (tcoords.z …Run Code Online (Sandbox Code Playgroud) 我一直在使用glDisable(GL_DEPTH_TEST)禁用深度测试,认为它只会禁用深度"测试".我之所以感到困惑的原因是因为我创建了两个函数,一个用于禁用深度"test",另一个用于禁用深度"写入"glDepthMask(GL_FALSE);
如果禁用GL_DEPTH_TEST禁用"测试"和"写入",那么它是否相当于:
glDepthFunc(GL_ALWAYS?); // DISABLE TESTS (OR ACTUALLY ALWAYS LET THE TEST SUCCEED)
glDepthMask(GL_FALSE); // DISABLE WRITES
Run Code Online (Sandbox Code Playgroud)
我认为GL_DEPTH_TEST除非我想禁用测试和写入,否则禁用很少,我想知道哪一个更好.措辞似乎令人困惑,但也许只是我.我认为禁用深度测试glDepthFun(GL_ALWAYS)仍然会进行比较,我想在仍然允许写入的情况下,没有办法完全禁用深度测试?
我在opengl es 2.0中的简单方块上渲染png,但是当我尝试在正方形后面绘制一些东西时,我已经绘制了我的顶部正方形中的透明区域呈现与背景相同的颜色.
我在每个渲染调用的开头调用它们.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Run Code Online (Sandbox Code Playgroud) 所有几何体都存储在一个VBO中(透明+不透明).我不能排序几何.如何在不丢失数据颜色的情况下禁止从glsl写入深度缓冲区?
在DirectX中,您可以拥有单独的渲染目标和深度缓冲区,因此您可以绑定渲染目标和深度缓冲区,执行一些渲染,移除深度缓冲区,然后使用旧的深度缓冲区作为纹理进行更多渲染.
你会如何在opengl中解决这个问题?根据我的理解,你有一个framebuffer对象,它包含颜色缓冲区和可选的深度缓冲区.我不认为我可以同时绑定几个帧缓冲对象,我是否必须在每次更改时重新创建帧缓冲对象(可能是帧的几次)?普通的opengl程序如何做到这一点?
我一直在使用OpenGL测试了一段时间,一直没能得到深度缓存工作,尽管使用GLUT_DEPTH作为一个参数glutInitDisplayMode和做glClear(GL_DEPTH_BUFFER_BIT)在显示功能的开始.我不知道还有什么我想念的.
下面是最小工作示例和图1和2.当您想要查看另一个时,请注释掉图1和2下的参数.
图1(蓝色上方):
图2(红色下方):
例:
#include <vector>
#include <gl\glut.h>
typedef std::vector<float> floatvec;
// Figure 1 (above blue)
float posX = 8.00f;
float posY = 7.54f;
float posZ = -0.89f;
float angleX = 300.50f;
float angleY = 45.33f;
// Figure 2 (below red)
float posX = 4.12f;
float posY = -4.87f;
float posZ = -3.84f;
float angleX = 343.25f;
float angleY = -45.00f;
int screenW = 720;
int screenH = 540;
float fMin = 0.5; …Run Code Online (Sandbox Code Playgroud) depth-buffer ×9
opengl ×6
c++ ×2
framebuffer ×2
glsl ×2
opengl-es ×2
shader ×2
webgl ×2
graphics ×1
javascript ×1
transparency ×1
zbuffer ×1