OpenGLTANotes

🕹️OpenGL丨半边结构模型读取&显示[2]

by ERIN.Z, 2022-12-05


本应是Mesh系列的第一篇~为了赶动画原理拖了几天。

上一篇中,我们用半边结构读取了网格,但实际上还没真正用到半边。

今天就是半边结构大显身手(?)的时候了!它可以快速找到每个顶点的所有邻居节点,以计算顶点的法线。 Shading

(入坑两年了,怎么还有人在写写了800次的基础卡渲.......)

B类作业④ 实验报告

实验原理

Shading

使用半边结构读入obj格式的三维网格模型,通过叉乘计算顶点法线,使用Blinn-Phone模型进行简单的渲染。

Interaction

模型交互使用了A类作业①魔方程序中构建的TrackBall类,将鼠标在窗口内的位置移动映射到球面,计算球面角对模型进行旋转。

实验步骤

1.使用半边结构读入网格

详见B类作业③实验报告。

2.计算顶点法线(见Vertex::computeNormal()

通过叉乘三角面的两个半边,我们可以获得三角面的法线。但顶点不止存在于一个三角面上,因此需要遍历所有其所在的三角面,对所有法线求平均值。

顶点不存储面相关的信息,因此遍历所有定点所在三角面是通过获取 所有顶点的出半边 实现的。通过outEdge->twin->next即可访问下一条出半边。 Outedges

计算得到的法线可视化如图: Normal

碎碎念:半边结构其实改了特别特别久。最开始没有成对创建半边,也没想起用哈希表,就分类讨论判断是否加新边之类的....改到头秃,最后索引关系还不对,算出来的法线: 。。。 像我的精神状态一样错乱......

3.渲染

将灯光位置与相机位置传入着色器,通过与Position做差可得到视线向量viewDir与光线向量lightDir,取平均得到半程向量H = normalize(viewDir+lightDir).点乘法线即可进行简单的光照计算。 Blinn-Phone 4.鼠标交互-旋转

引入了TrackBall类。

  • 当鼠标在窗口按下时,通过回调函数click_callback将鼠标位置传入TrackBall,并用布尔值leftkey记录按键状态。

  • 当鼠标在窗口移动时,若leftkey为真,通过回调函数mouse_callback将鼠标位置传入TrackBall,计算旋转角,并生成旋转矩阵,传递给vertex shader

实现细节:

  • 通过glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);开启鼠标监听
  • 使用glfwGetCursorPos()获得鼠标的屏幕坐标,并重映射至[-1,1]
  • TrackBall中用mat4 lasttrans记录先前的历史旋转。球面角计算得到的旋转轴是世界空间的,需要通过lasttrans的逆矩阵将旋转轴转换至物件空间。

5.鼠标交互-缩放

缩放的实现主要通过更改透视投影矩阵的视锥角实现。

  • 当滚轮在窗口改变时,通过回调函数scroll_callback将滚轮增减作用于视锥角。

6.渲染补充

补充了简单的程序化背景和简单的卡通渲染效果。

  • 在Blinn-Phone的光照基础上,对漫反射、高光的点乘计算值进行step()/smoothstep()即可获取清晰的光照边界。也可以添加ramp map以映射不同阶数的光照表现。

  • 背景由一个的四边形面片构成,在片元着色器中计算颜色。

    • 渐变:用TexCoords.y插值两种颜色。
    • 晶格化渐变:以TexCoords.y为半径的sdf画圆。
  • 将顶点朝法线方向偏移,即可获得描边效果。为刻画圈圈的网格结构,这里描边只绘制网格的背面,且绘制后不清理深度缓冲,这样在网格转折明显的部位仍可以出现描边效果。对比如下图: Outlined

(Yeah 我知道还有让描边宽窄不变的trick🤪🤪但我懒得写了。这个case里摄像机根本就不能动。)

  • 渲染时发现,附件提供的mesh模型缺少了一个三角面: (还以为法线又算错了 生气🤪

Snipaste_2022-12-05_11-06-29.jpg

为了视觉效果,在obj文件中添加了这个面。因此实际提交的`eight.uniform.obj`比附件提供的文件要多一行~

实验效果

  • 通过鼠标左键旋转模型。
  • 通过鼠标滚轮缩放模型。
  • 按键盘1/2/3切换显示效果。

Snipaste_2022-12-05_16-11-53.jpg

实验环境

Window 10. Visual Studio 2022.

依赖库:GLFW,GLAD, GLM

by ERIN.Z

2024 © typecho & elise