4.0 KiB
4.0 KiB
屏幕空间背景(白底 + 灰色网格线)说明
这份文档解释项目里新增的“3D 软件常见的白色背景 + 灰色分割线网格”是怎么实现的,以及如何调整效果。
需求点:
- 背景看起来更“科技感”(轻微渐变 + 网格线 + vignette)
- 背景不随相机旋转(不受 yaw/pitch/zoom 影响)
实现方式概览(为什么它不会旋转)
我们采用“屏幕空间(screen-space)”绘制方式:
- 画一个全屏 quad(两个三角形),顶点坐标直接写在裁剪空间 NDC([-1,1])
- fragment shader 使用
gl_FragCoord(屏幕像素坐标)生成网格线
由于整个背景是直接画在屏幕坐标系里,不使用 uMVP,所以它不会跟着相机旋转或移动。
关键文件
- 资源注册:
resources.qrc- 新增:
shaders/bg.vert、shaders/bg.frag
- 新增:
- Shader:
shaders/bg.vert:全屏 quad 的顶点 shader(裁剪空间直出)shaders/bg.frag:背景颜色 + 抗锯齿网格线(基于gl_FragCoord)
- C++(OpenGLWidget):
src/glwidget.h:新增m_bgProg、m_bgVao/m_bgVbo、initBackgroundGeometry_()src/glwidget.cppGLWidget::initPrograms_():编译/链接背景 programGLWidget::initBackgroundGeometry_():创建全屏 quad VAO/VBOGLWidget::paintGL():先画背景(关闭深度写入),再画 3D 内容
渲染顺序(为什么不会影响 3D 深度)
背景绘制发生在 GLWidget::paintGL() 的最前面:
glClear(...)清空颜色/深度- 绘制背景(屏幕空间)
glDisable(GL_DEPTH_TEST);glDepthMask(GL_FALSE);(不写深度)
- 恢复深度状态
glDepthMask(GL_TRUE);glEnable(GL_DEPTH_TEST);
- 再绘制 panel / dots(正常 3D 深度测试)
因此:背景永远在最底层,而且不会把深度缓冲弄脏。
全屏 quad(背景几何)
GLWidget::initBackgroundGeometry_() 创建一个覆盖整个屏幕的矩形(两个三角形):
- 顶点坐标是 NDC(裁剪空间):
- (-1,-1) 到 (1,1)
- 顶点 shader(
shaders/bg.vert)仅仅把它输出到gl_Position
这样不需要任何相机矩阵,也不会“跟着相机”动。
网格线怎么画出来的(bg.frag)
shaders/bg.frag 主要做了三件事:
1) 背景渐变底色
- 使用
uv = gl_FragCoord.xy / uViewport得到 0..1 的屏幕坐标 - 在 y 方向做一个轻微渐变(上更亮、下稍灰)
2) 细网格 + 粗网格(分割线)
用 uMinorStep / uMajorStep(单位:像素)控制网格间距:
uMinorStep:细分格子(更淡)uMajorStep:粗分格子(更明显)
网格线本质是对 fract(coord / step) 做“距离最近线”的计算,然后用 fwidth 做抗锯齿:
fwidth会随着屏幕像素密度和视角变化自动调整边缘过渡,避免锯齿
3) 轻微 vignette
四角略暗、中心略亮,让画面更聚焦、更像 3D 软件视口。
HiDPI 注意点(为什么要乘 devicePixelRatio)
Qt 的 width()/height() 是“逻辑像素”;而 gl_FragCoord 是“物理像素”。
所以背景在 C++ 里传入:
uViewport = (width * dpr, height * dpr)- 网格 step 也乘
dpr
否则在高 DPI 屏幕上网格会显得“变密/变粗”。
如何调整外观(常用参数)
调整网格密度
在 src/glwidget.cpp 里设置了:
uMinorStep = 24 px(细线间距)uMajorStep = 120 px(粗线间距)
改这两个值就能让网格更密/更稀。
调整颜色/强度/科技感
在 shaders/bg.frag 里可以改:
topCol/botCol:背景渐变颜色minorCol/majorCol:网格线颜色mix(...)的系数:线条深浅- vignette 强度:
dot(p,p)前面的系数
可选增强(如果你想更像 Blender/Unity)
- 加“坐标轴线”(X 红、Z 蓝或灰色加深)并在中心画十字
- 增加 UI 开关:显示/隐藏网格、调 step、调强度
- 增加“地平线”或 “ground plane” 的淡淡雾化效果