首页 > 其他分享 >基于 GPU 渲染的高性能空间包围计算

基于 GPU 渲染的高性能空间包围计算

时间:2024-01-29 16:58:28浏览次数:26  
标签:texture1 渲染 检测 模型 高性能 GPU 100 着色器

空间包围检测在计算机图形学、虚拟仿真、工业生产等有着广泛的应用。

现代煤矿开采过程中,安全一直是最大的挑战之一。地质空间中存在诸多如瓦斯积聚、地质构造异常、水文条件不利等隐蔽致灾因素,一旦被触发,可能引发灾难性的后果。因此在安全生产过程中有效的管理和规避各隐蔽致灾因素,有着重要的意义。

通过对煤矿地质空间中各地质因素建模,建立空间数据库,还原地下真实场景,使用计算机图形学进行空间计算,可以实时监测各隐蔽致灾因素的位置和距离,指导安全生产,并进行可视化展示。

空间包围检测有多种方法,比如基于包围盒的检测,三角面碰撞检测等。本文提出了一种基于 GPU 渲染的高效计算方法。

假定待检测球体范围的半径为r。两种检测方法如下:

  • 方法 1:遍历模型所有的点,计算点和球心的距离。如果有距离小于 r,模型在球体范围内。
  • 方法 2:以检测区域的包围盒为正交投影空间,渲染所有需要检测的模型。渲染过程中计算每个渲染点到球心的距离,如果有距离小于r的渲染点,模型在球体范围内。

模型和检测区域有以下几种位置关系:

 

  • 图 1:模型完全在球体范围内:方法 1 可检测
  • 图 2:模型部分点在球体范围内:方法 1 可检测
  • 图 3:模型点不在球体范围内,部分三角面在球形范围内:方法 2 可检测
  • 图 4:模型不在球体范围内:方法 1 + 2 可检测
  • 图 5:模型完全包含球体范围:模型如果是空心的,方法 1 + 2 可检测模型不在球体范围内。如果需要计算结果是模型在球体范围内,也就是模型是实心的,建模时需要在模型内部加上额外的辅助计算的三角面,用于表达内部信息。此时用方法 1 + 2 可检测模型在球体范围内。

以上方法使用 WebGL 渲染到纹理(Render To Texture) 和 readPixels 功能。图扑 HT for Web SDK 组件库对 WebGL 底层复杂操作做了封装, 为用户省掉了繁琐的底层 WebGL 操作,可以方便快捷的实现正交透视、渲染到纹理和异步 readPixels 等高级 WebGL 功能。

 

方法 1:点检测法

准备一张 N X N 纹理图 texture1(HT RenderTarget),保证要检测的模型的数量不大于 N X N。每一个模型在纹理上分配一个像素,像素的位置为 (x,y)。

创建点渲染模式着色器程序,实现以下功能:

  • 顶点着色器:检测每个点到球心的距离,将距离是否小于r的信息传给片段着色器。指定的位置 (x,y) 赋给 gl_Position。
  • 片段着色器:如果距离小于 r, 渲染红色,否则不渲染颜色。

JavaScript 程序遍历每一个待检测模型,将模型的顶点和模型在纹理上的位置 (x,y) 通过 attribute 和 uniform 传给顶点着色器。所有模型渲染结束后,使用异步 readPixels 将渲染结果读出来。通过判断读取结果里每个像素点颜色值,获得模型是否在球体内部信息。

主要代码:

// 创建渲染材质1 const texture1 = new ht.graph3d.RenderTarget(g3d, g3d.getGL(), 100, 100);
// 循环渲染所有的模型,结果保存到texture1。 for (let i = 0; i < nodeCount; i++) {     data = datas[i];     tModel = getDataMesh(data); // 获取模型网格信息     // 准备着色器数据     tModel.mat = model4.mat;     tModel.matDef[DEFAULT_MAT_NAME] = model4.mat;     tModel.mat.modelMat = data.getMatrix4().toArray();     x = i % 100;     y = Math.floor(i / 100);     model4.mat.uPos = [x / 100 * 2 - 1 + 1 / 200, 2 * y / 100 - 1 + 1 / 200];     // 渲染到texture1     g3d.setViewport(gl, 0, 0, 100, 100);     g3d.renderModel(texture1, model4, {         clear: false     }); }
// 读取检测结果 texture1.readPixelsAsync(0, 0, 100, 100, null, (result) => {     for (let y = 0; y < 100; y++) {         for (let x = 0; x < 100; x++) {             // 遍历像素点,检测是否是红色             // ......         }     } });

 

方法 2:面检测法

准备两张纹理贴图 texture1 和 texture2。Texture1 的要求同方法 1。Texture2 默认使用 1000 X 1000 的分辨率。

创建两套着色器。第一套着色器使用三角面渲染:

  • 顶点着色器:正常计算顶点投影信息
  • 片段着色器:检测每一个点到球心的距离,如果小于 r,渲染红色

第二套着色器使用点渲染:

  • 顶点着色器:根据输入的 texture2 坐标(attribute),使用 texture2D 获取对应位置的颜色值,如果是红色,表示模型在球体内部,将此信息传给片段着色器。模型在 texture1 上的位置信息 (x,y) 赋给 gl_Position。
  • 片段着色器:如果距离小于 r, 渲染红色,否则不渲染颜色。

JavaScript 程序遍历每一个模型,使用着色器 1 将结果渲染到 texture2。渲染过程使用正交透视矩阵,视锥是球体的包围盒。JavaScript 将 texture2 (uniform sampler2D)、texture2 每个像素的 x, y位置信息 (attribute)、模型在 texture1 上的位置信息 (uniform) 传给顶点着色器 2。片段着色器 2 将模型是否在球体内的信息渲染到 texture1。所有模型渲染结束后,使用异步 readPixels 将渲染结果读出来。通过判断读取结果里每个像素点颜色值,获得模型是否在球体内部信息。

 

主要代码:


// 创建渲染材质1,2


const texture1 = new ht.graph3d.RenderTarget(g3d, g3d.getGL(), 100, 100);


const texture2 = new ht.graph3d.RenderTarget(g3d, g3d.getGL(), 1000, 1000);


 


// 循环渲染所有的模型到texture2。texture2信息渲染到texture1


for (let i = 0; i < nodeCount; i++) {


data = datas[i];


     tModel = getDataMesh(data); // 获取模型网格信息


  // 准备着色器1数据


     tModel.mat = model2.mat;


     tModel.matDef[DEFAULT_MAT_NAME] = model2.mat;


     tModel.mat.modelMat = data.getMatrix4().toArray();


// 渲染到texture2


     g3d.setViewport(gl, 0, 0, 1000, 1000);


     g3d.renderModel(texture2, tModel, { clear: true });


// 准备着色器2数据


model3.mat.uImage = texture2.texture;


     x = i % 100;


     y = Math.floor(i / 100);


     model3.mat.uPos = [x / 100 * 2 - 1 + 1 / 200, 2 * y / 100 - 1 + 1 / 200];


// 渲染到texture1


     g3d.setViewport(gl, 0, 0, 100, 100);


     g3d.renderModel(texture1, model3, { clear: false });


 }

 

 

方法 1 简单快速。但检测结果不准确。方法 2 检测结果准确,但计算过程复杂。实际使用中两种方法结合使用。首先使用方法 1 检测。对于不在球体范围内的模型,再使用方法 2 检测。

如果需要检测椭球体范围或者长方体的范围,可以获取椭球体或长方的变换矩阵,计算获得逆矩阵。将逆矩阵应用于每一个待检测模型的节点。此时只需要检测变换后的模型是否在单位圆或单位立方体内即可。HT SDK 3D 引擎库提供了丰富的数学计算 API,可以非常直观简洁的实现以上功能。

 

您可以至图扑软件官网查看更多案例及效果:https://www.hightopo.com/demos/index.html

 

标签:texture1,渲染,检测,模型,高性能,GPU,100,着色器
From: https://www.cnblogs.com/xhload3d/p/17994576

相关文章

  • Pytorch分布式训练,其他GPU进程占用GPU0的原因
    问题最近跑师兄21年的论文代码,代码里使用了Pytorch分布式训练,在单机8卡的情况下,运行代码,出现如下问题。也就是说GPU(1..7)上的进程占用了GPU0,这导致GPU0占的显存太多,以至于我的batchsize不能和原论文保持一致。解决方法我一点一点进行debug。首先,在数据加载部分,由于没有将lo......
  • 最新Unity DOTS Instancing合批:如何针对单个渲染实体修改材质参数
    最近在做DOTS的教程,由于DOTS(版本1.0.16)目前不支持角色的骨骼动画,我们是将角色的所有动画数据Baker到一个纹理里面,通过修改材质中的参数AnimBegin,AnimEnd来决定动画播放的起点和终点,材质参数AnimTime记录当前过去的动画时间。但是在做大规模战斗控制的时候,有10000+的小兵在战斗......
  • 3dmax效果图渲染出现曝光怎么才能解决?
    面对3dsMax渲染中曝光过度的问题,通常由于相机设定、场景照明或渲染参数不正确造成。适当调整这些因素至关重要,不仅能让渲染作品实现所需的真实与视觉效果,还能大幅提升其整体质量。本文将概述解决这一渲染难题的方法。3dmax效果图渲染出现曝光解决方法第一步按下F10,打开渲染面......
  • blender渲染有波纹光圈怎么解决
    在使用Blender进行三维渲染作业时,偶尔会遇到渲染图像中出现波纹光圈的问题,这种情况的出现会影响渲染效果的质量,导致最终产品效果图无法达到理想的状态,那么此类危机出现时,该如何解决呢?一起来简单看看吧。 出现波纹光圈原因常见的诱因包括光照设置不当、色彩位深不足、抗锯齿问......
  • LED高性能双通道输出DC-DC降压恒流芯片AP2813
    产品叙述AP2813是深圳市世微半导体有限公司推出的一款双路降压恒流驱动器,高效率、外围简单、内置功率管,适用于5-80V输入的高精度降压LED恒流驱动芯片。内置功率管输出大功率可达12W,大电流1.2A。AP2813一路直亮,另外一路通过MODE1切换全亮,爆闪。AP2813工作频率固定在150......
  • Python多任务协程:编写高性能应用的秘密武器
    测试管理班是专门面向测试与质量管理人员的一门课程,通过提升从业人员的团队管理、项目管理、绩效管理、沟通管理等方面的能力,使测试管理人员可以更好的带领团队、项目以及公司获得更快的成长。提供1v1私教指导,BAT级别的测试管理大咖量身打造职业规划。多任务协程编程协程,又......
  • Python多任务协程:编写高性能应用的秘密武器!
    多任务协程编程协程,又称微线程,纤程。英文名Coroutine。协程也是一种轻量级的多任务编程技术,它可以在同一个线程中实现多个任务的切换和调度。协程通过任务的暂停和恢复,避免了线程切换的开销并减少了锁的使用。协程常用于异步编程场景,比如网络编程和IO密集型任务。最大的优势就是协......
  • Python多任务协程:编写高性能应用的秘密武器
    多任务协程编程协程,又称微线程,纤程。英文名Coroutine。协程也是一种轻量级的多任务编程技术,它可以在同一个线程中实现多个任务的切换和调度。协程通过任务的暂停和恢复,避免了线程切换的开销并减少了锁的使用。协程常用于异步编程场景,比如网络编程和IO密集型任务。最大的优势就是协......
  • canvas文字的渲染问题
    1.简单的文字绘制,包括文字的一些样式的设置canvas的默认字体是‘10pxsans-serif’我们可以通过如下语句进行文字的设置constfonts=‘bolditalic’//倾斜加粗constname=‘宋体’constsize=‘14’consttext=‘canvas总结’constctx=document.getElementById("canv......
  • 效果图云渲染活动“喜迎龙年,渲染有礼”正式上线
    Renderbus瑞云渲染在2024年新年之际,特别推出了一个促销活动以庆祝“龙年”,并作为回馈给致力于效果图制作的客户们。在这次活动中,客户们可以在充值期间获得一些可通用的渲染券,这些券可以在后续进行影视动画或效果图渲染时使用。让我们一探究竟,看看此次优惠活动都包含哪些内容。......