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

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

时间:2024-02-07 17:03:31浏览次数:23  
标签:texture1 渲染 检测 模型 高性能 GPU 100 着色器

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

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

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

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

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

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

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

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

基于 GPU 渲染的高性能空间包围计算_顶点着色器_02

以上方法使用 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 将渲染结果读出来。通过判断读取结果里每个像素点颜色值,获得模型是否在球体内部信息。

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

主要代码:

// 创建渲染材质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 将渲染结果读出来。通过判断读取结果里每个像素点颜色值,获得模型是否在球体内部信息。

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

主要代码:

// 创建渲染材质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,可以非常直观简洁的实现以上功能。


标签:texture1,渲染,检测,模型,高性能,GPU,100,着色器
From: https://blog.51cto.com/u_15153979/9638659

相关文章

  • react引用async异步函数数据渲染
    当需要在React组件中引用异步函数获取的数据时,可以使用useState钩子来存储数据,并在组件渲染时进行处理。下面是一个示例,展示了如何在React中引用异步函数的数据并进行渲染:importReact,{useState,useEffect}from'react';functionMyComponent(){const[data,......
  • 阿里云轻量级 GPU 实例安装 NVIDIA 驱动
    实例规格:轻量级GPU实例vgn6i-vws/ecs.vgn6i-m4-vws.xlarge(4vCPU23GiB)操作系统:Ubuntu22.04第一部分:尝试失败的安装方法查询NVIDIA产品型号lspci|grep-invidia输出00:07.0VGAcompatiblecontroller:NVIDIACorporationTU104GL[TeslaT4](reva1)根据产......
  • 草图大师渲染效果图在哪里开启?
    很多人在使用草图大师进行渲染时还不够熟练,因此我将提供一个详尽的渲染指南。如果你正寻找相关帮助,那么请继续阅读。我相信这个接下来的内容将会对你大有帮助。通过这份教程,你将能够逐步掌握SketchUp中的渲染技术。不要错失学习和提升的机会!草图大师怎么渲染效果图?1、打开草图大......
  • 快速渲染效果图:设计师的高效工作流揭秘
    ​渲染技能是每个建模设计师需求的一个重要技能,尽管在许多设计公司里,建模和渲染往往是分开由各自的专家来完成。不过,一个全能型的建模师还是应该精通渲染技术。对于那些接外包项目来制作渲染效果图的设计师来说,掌握如何提速渲染变得尤为关键,因为这可以帮助他们提高工作效率,从而增......
  • 告别 GPU 焦虑,玩转极致性价比的 CPU 文生图
    作者:壮怀、竹刚AIGC中的StableDiffusion文生图模型是开源流行的跨模态生成模型,用于生成给定文本对应的图像。但由于众所周知的原因,GPU资源出现了一卡难求的现状,如何通过云计算快速提升业务规模,降低文生图的计算成本,以及更好的保护自定义的扩展模型?针对文生图模型特性和规模......
  • 火山引擎ByteHouse:如何为OLAP设计高性能向量检索能力?
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群背景随着LLM技术应用及落地,数据库需要提高向量分析以及AI支持能力,向量数据库及向量检索等能力“异军突起”,迎来业界持续不断关注。简单来说,向量检索技术以及向量数据库能为LLM提供外置的记......
  • 2月摸鱼计划03 从并发编程本质了解Go高性能的本质
    1.0从并发编程本质了解Go高性能的本质1.1Goroutine协程可以理解为轻量级线程;Go更适合高并发场景原因之一:Go语言一次可以创建上万协成;“快速”:开多个协成打印。gofunc():在函数前加go代表创建协程;time.Sleep():协程阻塞,使主协程在子协程结束前阻塞不退出;乱序输出说......
  • 零基础入门Vue之影分身之术——列表渲染&渲染原理浅析
    听我说从条件渲染那一篇,我学习到了如何用Vue对dom节点根据条件显示但单单有条件还不够啊,有时候数据是一大坨一大坨的数据,如果Vue不提供咱要么使用“v-html”要么就没办法实现v-html又感觉太low了,Vue提供了另外的指令更好的实现,那便是:列表渲染列表渲染:v-for简单的列表渲染......
  • 第八届:世界3D渲染挑战赛《无尽阶梯》报名开始
    全世界的3D艺术创作者们引颈期盼的盛事“全球3D渲染艺术大奖赛”已迈入第八个年头。本届比赛的主题为“无尽的阶梯”,参赛者们可通过挑战赛展现自身的创造力,比赛在行业内拥有极高的知名度,含金量十足,参赛这可通过这里提高自己在业界的曝光。下面一起来简单看看世界3D渲染挑战赛的开......
  • Proxmox 7.4 使用vgpu_unlock,为GTX1060开启vGPU支持
    本文在2021年发布的博客《Proxmox5.4使用vgpu_unlock,为GTX1060开启vGPU支持》,介绍了ProxmoxVE5.4上部署vGPUunlock的操作步骤。 后续有发布了在 ProxmoxVE7.x上支持vGPU的博客《Proxmox7.2部署DoraCloud桌面云,支持vGPU》,实现了通过3个脚本完成vGPU的配置。 ......