当前位置: 首页 > java >正文

针对渲染圆柱体出现“麻花“状问题解决

圆柱体渲染结果,在侧面有麻花状条纹,边缘不够硬朗,上下的圆看起来不够平,很明显,是法向量导致的。

                原始模型                                                      渲染结果

计算点的法向量采用简单的平均法:

  • 计算该点相邻面的法向量

  • 将所有相邻面的法向量取平均

  • 最后归一化为单位向量

C++代码:


void compute_vertex_normals_manual(const Mesh& mesh, std::vector<Vector_3>& vertex_normals) {vertex_normals.resize(mesh.num_vertices(), Vector_3(0, 0, 0));// 记录每个顶点的相邻面数(用于平均)std::vector<unsigned int> vertex_face_count(mesh.num_vertices(), 0);for (auto face : mesh.faces()) {auto h = mesh.halfedge(face);auto v0 = mesh.target(h);auto v1 = mesh.target(mesh.next(h));auto v2 = mesh.target(mesh.prev(h));Point_3 p0 = mesh.point(v0);Point_3 p1 = mesh.point(v1);Point_3 p2 = mesh.point(v2);Vector_3 e0 = p1 - p0;Vector_3 e1 = p2 - p0;// 计算面法向量(先归一化,再累加)Vector_3 face_normal = CGAL::cross_product(e0, e1);double len = CGAL::sqrt(face_normal.squared_length());if (len > 0) face_normal = face_normal / len;// 累加归一化后的面法向量vertex_normals[v0] += face_normal;vertex_normals[v1] += face_normal;vertex_normals[v2] += face_normal;// 更新相邻面计数vertex_face_count[v0]++;vertex_face_count[v1]++;vertex_face_count[v2]++;}// 计算平均法向量并归一化for (size_t i = 0; i < vertex_normals.size(); ++i) {if (vertex_face_count[i] > 0) {vertex_normals[i] = vertex_normals[i] / vertex_face_count[i];double len = CGAL::sqrt(vertex_normals[i].squared_length());if (len > 0) vertex_normals[i] = vertex_normals[i] / len;}}
}

原因分析:模型不够精细,点太少,三角形 顶点1、 2 、3的法向量不一样,显卡在渲染的时候会进行插值,插值的点会根据点1、2、3的法向量自动计算,渲染时有过度的效果,因此看起来会有倾斜的条纹。

                     原始模型                                                      渲染结果

解决办法: 

确保统一平面上的点的法向量一致或有平直的过度,那么渲染就比较自然了。

方案1. 将上下两个圆和侧面分离,作为独立的对象渲染,使得边缘处的法向量不受平均法向量影响

                             原始模型                                                      渲染结果

方案2. 精细化模型,简单的方法是在硬边缘处增加卡线,每条边缘增加两条卡线,使受平均法向量影响的点限制在两条卡线中间,只有边缘处有平滑效果,其他的三角形过度就是平直的

                             原始模型                                                      渲染结果

http://www.xdnf.cn/news/285.html

相关文章:

  • 《操作系统真象还原》第九章(2)——线程
  • 「仓颉编程语言」Demo
  • kaamel Privacy agent:AI赋能的隐私保护技术解决方案
  • 广东水利水电安全员 B 证考试精选题
  • 电能质量治理解决方案:构建高效、安全的电力系统
  • 中国首个全国34省3,667个城市多属性建筑数据集(屋顶、高度、结构、功能、风格、年龄、质量等属性)
  • 《TIME-LLM: TIME SERIES FORECASTINGBY REPROGRAMMING LARGE LANGUAGE MODELS》
  • LeeCode912. 排序数组
  • 嵌入式学习(39)-基于STM32的GPIO电平反转检测
  • rhce第一次作业
  • GitHub创建远程仓库
  • DB-Day8笔记-with公共表达式综合案例窗口函数进阶
  • 【HCIA】使用Access port实现简易的VLAN间通信
  • 静态测试:软件质量保障的第一道防线
  • LeetCode每日一题4.18
  • 海关总署广东:广东外贸一季度进出口2.14万亿元 同期增长4.2%
  • 斐波那契数列计算:数据结构与算法视角
  • C++(17):通过filesystem获取文件的大小
  • Promise的详细讲解
  • python豆包语音合成并播放
  • 如何用 esProc 将数据库表转储提速查询
  • 视频编解码种类/技术/区别/优缺点汇总
  • osgb和obj格式互转
  • 代码学习总结(四)
  • LabVIEW技巧——获取文件版本信息
  • 【Python】使用Flet开发批量解密Excel工具
  • 遥感技术赋能电力设施监控:应用案例篇
  • 2024年RIS SCI2区:自适应天鹰算法AAO,深度解析+性能实测
  • Docker 容器与镜像核心操作命令大全(实战指南)
  • Andorid 使用 libphonenumber-android 获取国际电话区号