OpenGL中仅首个生成的纹理保留透明度的问题求助
OpenGL透明纹理对象透明度丢失问题修复
问题现象
尝试显示两个带不同透明纹理的对象时,无论创建顺序如何,第二个对象总会丢失透明度:
- 先创建纹理A再创建B → B丢失透明度
- 先创建纹理B再创建A → A丢失透明度
即使注释图像加载代码、仅创建空纹理,只要存在第一个纹理,第二个的透明度就会失效。
核心原因
问题出在ShaderProgram的set_material方法中,给着色器的sampler2D uniform赋值时,错误地使用了纹理ID减1,而非当前激活的纹理单元索引。
OpenGL中,sampler2D需要接收的是纹理单元编号(如0对应GL_TEXTURE0),而非纹理对象的ID。当第二个纹理的ID为2时,diffuse.get_id()-1得到1,但此时激活的是GL_TEXTURE0(每个对象的纹理计数从0开始),导致着色器从错误的纹理单元采样,最终透明度失效。
修复方案
修改ShaderProgram::set_material中的纹理uniform赋值逻辑:
漫反射纹理部分修复
原错误代码:
self.set_1i(&name, (diffuse.get_id() - 1) as i32);
修改后代码:
self.set_1i(&name, (tex_count - 1) as i32);
镜面纹理部分同步修复
原错误代码:
self.set_1i(&name, (specular.get_id() - 1) as i32);
修改后代码:
self.set_1i(&name, (tex_count - 1) as i32);
验证说明
- 你已按从远到近排序透明对象,符合透明度混合的正确绘制顺序,无需调整。
- 纹理加载时使用
GL_RGBA作为内部格式,确保alpha通道被正确存储,逻辑正确。 - 着色器中
discard逻辑能正确剔除完全透明像素,无需修改。
内容的提问来源于stack exchange,提问作者Acerola
相关产品推荐
相关产品推荐

