OpenGL渲染OpenCV视频时图像坐标异常的原因与修复
OpenGL渲染OpenCV视频时修改纹理坐标后异常的原因与修复方案
我来帮你分析这个问题——你修改顶点着色器后出现的视频异常,其实是两个常见的OpenGL Shader陷阱导致的,咱们一步步拆解:
问题根源
1. 未处理边界情况导致的未定义行为
你的顶点着色器里只判断了pos.y < 0.0f和pos.y > 0.0f,完全漏掉了pos.y == 0.0f的情况。这时候rst和texPos这两个变量都没有被赋值,属于未定义行为——OpenGL会使用这些变量的随机垃圾值,直接导致画面出现不可预测的错误。
2. 纹理坐标突变引发的光栅化插值错误
当你把上半部分顶点的texPos硬设为vec2(1.0f, 1.0f)时,相邻顶点(比如屏幕上下分界处的顶点)之间的纹理坐标出现了巨大差异。OpenGL的片元着色器会对顶点输出的texPos进行线性插值,这会导致上下区域过渡的片元纹理坐标被错误拉伸,出现模糊、错位甚至完全混乱的画面。
修复方案
第一步:先补全边界条件的处理
首先必须处理pos.y == 0.0f的情况,把它归到任意一个分支里,避免未定义行为:
#version 330 core layout(location = 0) in vec2 vert_pos; layout(location = 1) in vec2 tex_pos; uniform mat3 trans1; uniform mat3 trans2; out vec2 texPos; void main() { vec3 pos = vec3(-vert_pos.y, vert_pos.x, 0.0f); vec3 rst; vec2 outTexPos; if(pos.y < 0.0f) { rst = pos; outTexPos = tex_pos; } else { // 包含pos.y == 0.0f的所有情况 rst = pos; outTexPos = vec2(1.0f, 1.0f); } gl_Position = vec4(rst.x, rst.y, 0.0f, 1.0f); texPos = outTexPos; }
第二步:针对你的真实需求优化(应用不同旋转矩阵)
如果你的目标是对图像上下部分应用不同的旋转矩阵,而不是单纯测试纹理坐标,那你需要对顶点位置和纹理坐标都应用对应的变换矩阵,而不是硬改纹理坐标。注意要把齐次坐标的w分量设为1.0,才能正确应用矩阵变换:
#version 330 core layout(location = 0) in vec2 vert_pos; layout(location = 1) in vec2 tex_pos; uniform mat3 trans1; // 下半部分的变换矩阵 uniform mat3 trans2; // 上半部分的变换矩阵 out vec2 texPos; void main() { // 转为齐次坐标(w=1.0),才能正确应用仿射变换 vec3 pos = vec3(-vert_pos.y, vert_pos.x, 1.0f); vec3 texVec = vec3(tex_pos, 1.0f); vec3 rstPos; vec3 rstTex; if(pos.y < 0.0f) { rstPos = trans1 * pos; rstTex = trans1 * texVec; // 如果有独立的纹理变换矩阵,这里替换成对应的即可 } else { rstPos = trans2 * pos; rstTex = trans2 * texVec; } // 齐次坐标转回笛卡尔坐标(除以w分量) gl_Position = vec4(rstPos.x / rstPos.z, rstPos.y / rstPos.z, 0.0f, 1.0f); texPos = vec2(rstTex.x / rstTex.z, rstTex.y / rstTex.z); }
额外建议:拆分绘制避免插值问题
如果你只是想测试上下区域的独立纹理显示,还可以把原来的单个四边形拆分成两个独立的四边形(上半屏和下半屏),分别设置纹理坐标和绘制,这样就不会出现跨区域的插值异常了。
内容的提问来源于stack exchange,提问作者Biobot
相关产品推荐
相关产品推荐

