Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 渲染深度到纹理_Java_Opengl_Glsl_Lwjgl_Framebuffer - Fatal编程技术网

Java 渲染深度到纹理

Java 渲染深度到纹理,java,opengl,glsl,lwjgl,framebuffer,Java,Opengl,Glsl,Lwjgl,Framebuffer,我无法获得正确渲染的深度。没有抛出错误,glCheckFramebufferStatus也表示它已完成 下面是代码,屏幕总是显示为白色。深度值不是1,但非常接近: 编辑: 所以我尝试线性化深度片段着色器内部的深度,然后直接绘制到屏幕上,以确保值是正确的。他们是正确的。然而,即使我将线性化的深度发送到我的全屏四元着色器(下面的第二个),屏幕仍然是全白色的 public void initFramebuffers() { glBindFramebuffer(GL_FRAMEBUFFER, d

我无法获得正确渲染的深度。没有抛出错误,glCheckFramebufferStatus也表示它已完成

下面是代码,屏幕总是显示为白色。深度值不是1,但非常接近:

编辑: 所以我尝试线性化深度片段着色器内部的深度,然后直接绘制到屏幕上,以确保值是正确的。他们是正确的。然而,即使我将线性化的深度发送到我的全屏四元着色器(下面的第二个),屏幕仍然是全白色的

public void initFramebuffers() {
    glBindFramebuffer(GL_FRAMEBUFFER, depthShader.fbo);
    depthShader.initTexture(width, height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthShader.tex, 0);
    glDrawBuffer(GL_NONE);
    glReadBuffer(GL_NONE);
}

public void initTexture(int width, int height, int format, int internalFormat) {
    tex = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_FLOAT, (ByteBuffer)null);
}
深度着色器:

#version 400

in vec3 pos;
in float radius;

uniform mat4 mView;
uniform mat4 projection;
uniform vec2 screenSize;
uniform vec3 lightPos;

out float depth;

float linearizeDepth(float depth) {
    float n = 0.01;
    float f = 100;
    return (2.0 * n) / (f + n - depth * (f - n));
}    

void main() {
    //calculate normal
    vec3 normal;
    normal.xy = gl_PointCoord * 2.0 - 1.0;
    float r2 = dot(normal.xy, normal.xy);
    
    if (r2 > 1.0) {
        discard;
    }
    
    normal.z = sqrt(1.0 - r2);

    //calculate depth
    vec4 pixelPos = vec4(pos + normal * radius, 1.0);
    vec4 clipSpacePos = projection * pixelPos;
    
    depth = clipSpacePos.z / clipSpacePos.w * 0.5f + 0.5f;
    depth = linearizeDepth(depth);
}
读取深度的着色器。线性化深度中的值是我的近距离和远距离:

#version 400

in vec2 coord;

uniform sampler2D depthMap;
uniform vec2 screenSize;
uniform mat4 projection;

out vec4 color;

float linearizeDepth(float depth) {
    float n = 0.01;
    float f = 100;
    return (2.0 * n) / (f + n - depth * (f - n));
}    

void main() {
    float curDepth = texture2D(depthMap, coord).x;
    //float d = linearizeDepth(curDepth);

    color = vec4(d, d, d, 1.0f);
}
绘制所有内容的代码:

//--------------------Particle Depth-----------------------
{
    glUseProgram(depthShader.program);
    glBindFramebuffer(GL_FRAMEBUFFER, depthShader.fbo);

    depthShader.particleDepthVAO(points);
    
    //Sets uniforms
    RenderUtility.addMatrix(depthShader, mView, "mView");
    RenderUtility.addMatrix(depthShader, projection, "projection");
    RenderUtility.addVector2(depthShader, screenSize, "screenSize");
    RenderUtility.addVector3(depthShader, lightPosition, "lightPos");
            
    glDisable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArray(depthShader.vao);

    glDrawArrays(GL_POINTS, 0, points.size());  
}

    //Draw full screen
{
    glUseProgram(blurShader.program);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
                
    blurShader.blurDepthVAO();
                
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, depthShader.tex);
    glUniform1i(blurShader.depthMap, 0);
    
    //Sets uniforms 
    RenderUtility.addMatrix(blurShader, mView, "mView");
    RenderUtility.addMatrix(blurShader, projection, "projection");
    RenderUtility.addVector2(blurShader, screenSize, "screenSize");
                
    //glEnable(GL_DEPTH_TEST);
                
    glBindVertexArray(blurShader.vao);
                
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glViewport(0, 0, width, height);
}

问题最终是我的顶点着色器的out变量名与片段着色器的in变量名(doh)不匹配。上面发布的代码是100%正确的,以防将来有人看到。

发布的代码有一些问题

渲染目标的使用不一致 在FBO的设置中,只有深度附件,没有颜色附件。颜色绘制缓冲区也被显式禁用:

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthShader.tex, 0);
glDrawBuffer(GL_NONE);
但是,片段着色器会写入颜色输出:

out float depth;
...
    depth = clipSpacePos.z / clipSpacePos.w * 0.5f + 0.5f;
    depth = linearizeDepth(depth);
要写入帧缓冲区的深度附件,必须设置预定义的
gl_FragDepth
变量的值。仅仅因为out变量名为
depth
,并不意味着它实际上被用作深度输出。如果要使用颜色输出,必须创建常规纹理,并将其附加到
GL\u color\u ATTACHMENT0
。这看起来更容易

线性化深度()计算 处理
clipSpacePos
的方式似乎是
linarizeDepth()
的参数介于0.0和1.0之间。这些极值的函数内计算如下:

0.0 --> (2.0 * n) / (f + n)
1.0 --> 1.0
对于1.0来说,这看起来不错,但是对于0.0来说,这是有问题的。我相信做准备的步骤实际上更为正确:

depth = clipSpacePos.z / clipSpacePos.w;
然后将-1.0和1.0之间的参数传递给函数,该函数随后生成:

-1.0 --> n / f
1.0  --> 1.0
事实上,对我来说,将整个事情缩放到0.0到1.0之间会更有意义,但至少这个版本有直观的意义,可以产生到远平面的相对距离

计算过于复杂 以上这些在我看来是不必要的复杂。您正在应用投影矩阵,从结果中获取深度,然后有效地反转投影矩阵应用的深度计算

一开始不应用投影矩阵,只取原始距离似乎简单得多。如果需要相对距离,仍然可以除以“远距离”。至少只要您使用标准投影矩阵,我相信以下内容相当于上面更正的计算:

vec4 pixelPos = vec4(pos + normal * radius, 1.0);
float f = 100.0;  // far plane
depth = -pixelPos.z / f;
减号之所以出现,是因为最常用的眼睛坐标系假设您向下看的是负z轴

如果希望结果介于0.0和1.0之间,还可以将其更改为:

float n = 0.01;   // near plane
float f = 100.0;  // far plane
depth = (-pixelPos.z - n) / (f - n);

深度片段着色器中的线性化不正确,已更正。根据我在网上读到的,线性化函数似乎是标准的。此外,着色器的实现基于请不要以使答案无效的方式编辑问题。这不是目的。其目的是反映我的代码的当前状态,即在我看到您的答案之前它所处的状态。让它保持这种状态对我来说只是一个错误,我忽略了更新它。它可能有点晚了,但在线性化深度值时仍然有一个错误。如果对你有用的话,你可能不会认为这一切都是错误的,但有另一种方法可以线性化深度(对我有用)。请看这个问题:在这个公式中,另一个f乘以linDepth()函数的返回值。
float n = 0.01;   // near plane
float f = 100.0;  // far plane
depth = (-pixelPos.z - n) / (f - n);