使用 GLSL 进行立方体贴图
Cubemapping with GLSL
我尝试使用 GLSL 进行立方体贴图。但是,对象是黑色的。
为什么物体无法遮蔽?
补充:
- 图片可以读取。
projectionMatrix、viewMatrix 和 baseColor 正常工作。
glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &_texture);
glActiveTexture(GL_TEXTURE1); // add
glBindTexture(GL_TEXTURE_CUBE_MAP, _texture);
QImage posx;
bool complateLoadCubeMapPosX = posx.load(("D:/posx.jpg"));
assert(complateLoadCubeMapPosX);
QImage negx;
bool complateLoadCubeMapNegX = negx.load(("D:/negx.jpg"));
assert(complateLoadCubeMapNegX);
QImage posy;
bool complateLoadCubeMapPosY = posy.load(("D:/posy.jpg"));
assert(complateLoadCubeMapPosY);
QImage negy;
bool complateLoadCubeMapNegY = negy.load(("D:/negy.jpg"));
assert(complateLoadCubeMapNegY);
QImage posz;
bool complateLoadCubeMapPosZ = posz.load(("D:/posz.jpg"));
assert(complateLoadCubeMapPosZ);
QImage negz;
bool complateLoadCubeMapNegZ = negz.load(("D:/negz.jpg"));
assert(complateLoadCubeMapNegZ);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // add
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // add
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // add
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // add
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // add
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, posx.width(), posx.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, posx.bits());
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, negx.width(), negx.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, negx.bits());
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, posy.width(), posy.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, posy.bits());
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, negy.width(), negy.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, negy.bits());
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, posz.width(), posz.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, posz.bits());
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, negz.width(), negz.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, negz.bits());
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glActiveTexture(GL_TEXTURE0); // add
MaterialManager::getInstance().createProgram("cubemap");
渲染代码:
GLuint program = MaterialManager::getInstance().getShader("cubemap");
glUseProgram(program);
glUniformMatrix4fv(glGetUniformLocation(program, "projMat"), 1, GL_FALSE, projectionMatrix.data());
glUniformMatrix4fv(glGetUniformLocation(program, "viewMat"), 1, GL_FALSE, viewMatrix.data());
glUniform4f(glGetUniformLocation(program, "baseColor"), 0.8f, 0.8f, 0.8f, 1.0f);
glUniform1i(glGetUniformLocation(program, "envMap"), 1); // change
glBindVertexArray(_vao);
glActiveTexture(GL_TEXTURE1); // add
glBindTexture(GL_TEXTURE_CUBE_MAP, _texture); // add
glDrawArrays(GL_TRIANGLES, 0, _normals.size());
glActiveTexture(GL_TEXTURE0); // add
glBindVertexArray(0);
片段着色器:
#version 450
#extension GL_NV_shadow_samplers_cube : enable
in vec4 position;
in vec3 normal;
out vec4 out_color;
uniform vec4 baseColor;
uniform samplerCube envMap;
...
void main()
{
out_color = vec4(textureCube(envMap, vec3(1.0, 0.0, 0.0)).rgb, 1.0);
}
您将 _texture 绑定为统一 (envMap),但该统一应包含纹理单元。我也没有看到你在渲染时绑定 _texture(缺少 glBindTexture(GL_TEXTURE_CUBE_MAP, _texture);
)
此外,您在创建纹理时没有设置采样器参数:
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
我尝试使用 GLSL 进行立方体贴图。但是,对象是黑色的。
为什么物体无法遮蔽?
补充:
- 图片可以读取。
projectionMatrix、viewMatrix 和 baseColor 正常工作。
glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &_texture); glActiveTexture(GL_TEXTURE1); // add glBindTexture(GL_TEXTURE_CUBE_MAP, _texture); QImage posx; bool complateLoadCubeMapPosX = posx.load(("D:/posx.jpg")); assert(complateLoadCubeMapPosX); QImage negx; bool complateLoadCubeMapNegX = negx.load(("D:/negx.jpg")); assert(complateLoadCubeMapNegX); QImage posy; bool complateLoadCubeMapPosY = posy.load(("D:/posy.jpg")); assert(complateLoadCubeMapPosY); QImage negy; bool complateLoadCubeMapNegY = negy.load(("D:/negy.jpg")); assert(complateLoadCubeMapNegY); QImage posz; bool complateLoadCubeMapPosZ = posz.load(("D:/posz.jpg")); assert(complateLoadCubeMapPosZ); QImage negz; bool complateLoadCubeMapNegZ = negz.load(("D:/negz.jpg")); assert(complateLoadCubeMapNegZ); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // add glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // add glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // add glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // add glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // add glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, posx.width(), posx.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, posx.bits()); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, negx.width(), negx.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, negx.bits()); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, posy.width(), posy.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, posy.bits()); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, negy.width(), negy.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, negy.bits()); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, posz.width(), posz.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, posz.bits()); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, negz.width(), negz.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, negz.bits()); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); glActiveTexture(GL_TEXTURE0); // add MaterialManager::getInstance().createProgram("cubemap");
渲染代码:
GLuint program = MaterialManager::getInstance().getShader("cubemap");
glUseProgram(program);
glUniformMatrix4fv(glGetUniformLocation(program, "projMat"), 1, GL_FALSE, projectionMatrix.data());
glUniformMatrix4fv(glGetUniformLocation(program, "viewMat"), 1, GL_FALSE, viewMatrix.data());
glUniform4f(glGetUniformLocation(program, "baseColor"), 0.8f, 0.8f, 0.8f, 1.0f);
glUniform1i(glGetUniformLocation(program, "envMap"), 1); // change
glBindVertexArray(_vao);
glActiveTexture(GL_TEXTURE1); // add
glBindTexture(GL_TEXTURE_CUBE_MAP, _texture); // add
glDrawArrays(GL_TRIANGLES, 0, _normals.size());
glActiveTexture(GL_TEXTURE0); // add
glBindVertexArray(0);
片段着色器:
#version 450
#extension GL_NV_shadow_samplers_cube : enable
in vec4 position;
in vec3 normal;
out vec4 out_color;
uniform vec4 baseColor;
uniform samplerCube envMap;
...
void main()
{
out_color = vec4(textureCube(envMap, vec3(1.0, 0.0, 0.0)).rgb, 1.0);
}
您将 _texture 绑定为统一 (envMap),但该统一应包含纹理单元。我也没有看到你在渲染时绑定 _texture(缺少 glBindTexture(GL_TEXTURE_CUBE_MAP, _texture);
)
此外,您在创建纹理时没有设置采样器参数:
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );