【问题标题】:Changing color using a shader使用着色器更改颜色
【发布时间】:2013-08-05 22:17:16
【问题描述】:

我正在编写一个延迟着色器,作为第一步,为了熟悉 GLSL 并使用着色器和帧缓冲区,我正在尝试通过着色器更改网格的颜色。 我通过使用包含附件的数组调用 glDrawBuffers 将其链接到其中一个缓冲区,然后将纹理绑定到我的帧缓冲区:

    glReadBuffer(GL_NONE);
    GLint color_loc = glGetFragDataLocation(pass_prog,"out_Color");
    GLenum draws [1];
    draws[color_loc] = GL_COLOR_ATTACHMENT0;
    glDrawBuffers(1, draws);

    glBindTexture(GL_TEXTURE_2D, diffuseTexture);    
    glFramebufferTexture(GL_FRAMEBUFFER, draws[color_loc], diffuseTexture, 0);

我的片段着色器中有一个 out_Color 变量(否则它甚至无法编译),但我无法通过着色器中的该变量设置它来更改网格的颜色。 有谁知道为什么并且可以向我解释一下吗?

谢谢

编辑: 我的着色器: 顶点着色器

    #version 330


uniform mat4x4 u_Model;
uniform mat4x4 u_View;
uniform mat4x4 u_Persp;
uniform mat4x4 u_InvTrans;

in  vec3 Position;
in  vec3 Normal;

out vec3 fs_Normal;
out vec4 fs_Position;

void main(void) {
    fs_Normal = (u_InvTrans*vec4(Normal,0.0f)).xyz;
    vec4 world = u_Model * vec4(Position, 1.0);
    vec4 camera = u_View * world;
    fs_Position = camera;
    gl_Position = u_Persp * camera;
}

片段着色器

    #version 330

uniform float u_Far;

in vec3 fs_Normal;
in vec4 fs_Position;

out vec4 out_Normal;
out vec4 out_Position;
out vec4 out_Color;

void main(void)
{
    out_Normal = vec4(normalize(fs_Normal),0.0f);
    out_Position = vec4(fs_Position.xyz,1.0f); //Tuck position into 0 1 range
    out_Color = vec4(1.0f, 0.0f, 0.0f, 1.0f);//first three diffuse, last specular
}

而且我不是为了学习 GLSL 而做延迟着色器。我正在学习 GLSL 以使 延迟着色器。 =)

更多设置纹理的源代码:

glActiveTexture(GL_TEXTURE0);

glGenTextures(1, &depthTexture);
glGenTextures(1, &normalTexture);
glGenTextures(1, &positionTexture);
glGenTextures(1, &diffuseTexture);

//DEPTH TEXTURE
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);

//NORMAL TEXTURE
glBindTexture(GL_TEXTURE_2D, normalTexture);    
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);        
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0);

//POSITION TEXTURE
glBindTexture(GL_TEXTURE_2D, positionTexture);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);        
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0);

//DIFFUSE TEXTURE
glBindTexture(GL_TEXTURE_2D, diffuseTexture);   
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);        
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0);

 //create a framebuffer object
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);

 //Instruct openGL that we won't bind a color texture with the currently binded FBO
glReadBuffer(GL_NONE);
GLint normal_loc = glGetFragDataLocation(pass_prog,"out_Normal");
GLint position_loc = glGetFragDataLocation(pass_prog,"out_Position");
GLint color_loc = glGetFragDataLocation(pass_prog,"out_Color");
GLenum draws [3];
draws[normal_loc] = GL_COLOR_ATTACHMENT0;
draws[position_loc] = GL_COLOR_ATTACHMENT1;
draws[color_loc] = GL_COLOR_ATTACHMENT2;
glDrawBuffers(3, draws);

glBindTexture(GL_TEXTURE_2D, depthTexture); 
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0);
glBindTexture(GL_TEXTURE_2D, normalTexture);    
glFramebufferTexture(GL_FRAMEBUFFER, draws[normal_loc], normalTexture, 0);
glBindTexture(GL_TEXTURE_2D, positionTexture);    
glFramebufferTexture(GL_FRAMEBUFFER, draws[position_loc], positionTexture, 0);
glBindTexture(GL_TEXTURE_2D, diffuseTexture);    
glFramebufferTexture(GL_FRAMEBUFFER, draws[color_loc], diffuseTexture, 0);


 check FBO status
FBOstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(FBOstatus != GL_FRAMEBUFFER_COMPLETE) {
    printf("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO\n");
    checkFramebufferStatus(FBOstatus);
}


 switch back to window-system-provided framebuffer
glClear(GL_DEPTH_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);

编辑: 我解决了。谢谢。

【问题讨论】:

  • “//前三个漫反射,最后一个镜面反射”是什么意思?你没有得到纹理,因为你的着色器没有这样做。
  • 解决方案是什么?你介意把它贴出来让别人学习吗?谢谢
  • @fusi 实际上我不确定解决方案,我遇到了另一个错误,当我重置一切时它工作正常。我肯定从第一个配置到最后一个配置改变了一些东西,但我不知道是什么。对不起。
  • 发生在我们所有人身上:) 很高兴它的工作:)

标签: opengl glsl shader


【解决方案1】:

你应该这样做。我假设 out_color 被声明为 out vec4 out_Color:

Compile shaders and attach them to the program.
glBindFragDataLocation(program, 0, "out_Color");
glLinkProgram(program);
glUseProgram(program);

GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 }
glDrawBuffers(1, drawBuffers);

Setup FBO.

它应该可以工作,如果没有,请发布您的片段着色器和更多源代码。顺便说一句,我还应该说,创建一个延迟渲染器来学习 GLSL 并不是一个好主意。学习 GLSL 有更简单的方法。

【讨论】:

  • 我正在这样做。我已经让深度、位置和正常渲染目标工作了,但由于某种原因颜色不起作用。
猜你喜欢
  • 1970-01-01
  • 2019-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 2020-08-01
  • 2013-11-25
相关资源
最近更新 更多