城市级河流三维处理及展示的一些技术

本文是一些算法技术的初探分析,会陆续修订。

1、问题

河流是一种非常复杂的多边形。在二维地图可以采用多边形填充算法(DDA)对任意复杂的多边形进行绘制与填充。但是三维引擎只能采纳三角面进行渲染。但在如此复杂的多边形面前,简单的三角化算法不能解决问题。会出现计算错误或者三角面很长的情况。

2、网格切割

将河流根据经纬度或者某些度量单位进行切割成瓦片是一种可行办法。可采用开源软件Clipper2进行处理。Clipper2是一个开源免费软件库(用 C++、C# 和 Delphi Pascal 编写),用于执行线和多边形裁剪和偏移。可以预见被切割的河流虽然比较规整,但三角化的效果(错误率和长三角情况)稍微会好一些。

3、河流带方向

比较好的河流效果应该是高仿真的效果。如GitHub - Arnklit/Waterways: A tool to generate river meshes with flow and foam maps based on bezier curves.

godot的Waterways插件

它需要曲线引导水的流动方向。适合手绘并且具备较好DEM的情况。在这里河流片元着色器的颜色可以描述为下面简单的公式。

color=f(g(time,noise),h(waterDepth,direction),p(waterNormal,waterColorRamp))

color=f(g(time,noise),h(waterDepth,direction),p(waterNormal,waterColorRamp))

如果基于该技术路线,那么还需要将矢量面的水面提取水面中心点。还有一点需要注意的是,该示例的多边形会根据与地面物体的碰撞,得到切割后的多边形。

4、计算水体深度

计算水体深度的代码非常有意思,我单独讲下。这里的水体深度不是严格的水面高度减去地形距离。而是通过显存中的深度值计算得到的。我附上源代码并进行简单解释:

float depth_tex = textureLod(DEPTH_TEXTURE, SCREEN_UV, 0.0).r;
//这行代码从名为 DEPTH_TEXTURE 的深度纹理中获取深度值。其中DEPTH_TEXTURE 是显存中已经计算的深度图。
//因为水面是后期处理,因此这个深度可以理解为DEM高度
float depth_tex_unpacked = depth_tex * 2.0 - 1.0;
float surface_dist = PROJECTION_MATRIX[3][2] / (depth_tex_unpacked + PROJECTION_MATRIX[2][2]);
//根据显存深度值得到真实的距离值
float water_depth = surface_dist + VERTEX.z;
//水体深度=眼睛到水底的距离+水平面的高度。
//比如眼睛到水底的距离是-3.2米,水平面的高度是4米,则水体深度是0.8米。

细心的读者会发现有几个比较难以理解的点。一是surface_dist的计算方法比较奇怪。二是眼睛到水底的距离为啥是负数。

先回答第二个问题,这是因为摄像机面朝负Z轴。对于位于摄像机前方的物体,其Z坐标将是负数。比如,一个物体在世界坐标系中的 Z 值为 -5,表示它在摄像机前方5个单位的地方。这种设计使得物体在视图空间中的深度易于理解和管理。

现在回答第一个问题。首先需要知道投影矩阵的公式,如下:

|  f/aspect  0         0               0          |  
|  0         f         0               0          |  
|  0         0         (zFar + zNear)/(zNear - zFar)   2*zFar*zNear/(zNear - zFar) |  
|  0         0        -1               0          |

其中 PROJECTION_MATRIX[3][2]表示 2*zFar*zNear/(zNear - zFar)。PROJECTION_MATRIX[2][2]表示(zFar + zNear)/(zNear - zFar) 。还需要知道一个物体在显存深度图的计算公式:


float distance = near * far / (far - depth * (far - near));

因为着色器并没有传递near和far,因此只需要证明下面两个公式是一致的即可。具体过程不再展开。

float distance = near * far / (far - depth1 * (far - near));--①float distance2=pm32/(depth2-pm22)------②depth2=depth1*2-1---③

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1538231.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Java 回顾方法的定义

一、方法的定义 1.修饰符(public static…)详见博客【Java 方法的定义】 2.返回值(int, double, char[],…., void)详见博客【Java 方法的定义】 3. break:跳出switch 结束循环,详…

2024年09月18日《每日一练》

1、 智慧城市建设参考模型包括有依赖关系的5层结构和对建设有约束关系的3个支撑体系,5层结构包括物联感知层、通信网络层、计算与存储层、数据及服务支撑层、智慧应用层;3个支撑体系除了建设和运营管理体系、安全保障体系之外还包括()。 A 人…

使用arduino玩基于esp8266的nodemcu开发板

一、简介 中秋节到图书馆看书,看到了arduino方面的书籍,里面有提到ESP8266模块。让我想起我抽屉里吃灰很久了的基于esp8266的nodemcu开发板。于是把书借回家研究了一下。这里做个记录。 二、我目前在使用的云服务器推荐 学Linux不搞个云服务器始终感觉…

进行直流充电桩测试仪的步骤和规范

直流充电桩测试仪是一种用于检测和评估直流充电桩性能的设备。它能够测量充电桩的输出电压、电流、功率等参数,并能够模拟各种负载条件,以测试充电桩的稳定性和可靠性。下面是进行直流充电桩测试仪的步骤和规范: 确保测试环境安全&#xff0…

2024.9.18 作业+思维导图

练习&#xff1a;提示并输入一个字符串&#xff0c;统计该字符串中字母、数字、空格、其他字符的个数并输出 #include <iostream>using namespace std;int main() {cout << "请输入一个字符串:" << endl;string str;int shuzi 0,zimu0,space 0,q…

MAGDA:多智能体指南驱动的诊断助手

MAGDA&#xff1a;多智能体指南驱动的诊断助手 秒懂大纲提出背景精细拆解输入输出全流程创意视角中文意译 论文&#xff1a;MAGDA: Multi-agent guideline-driven diagnostic assistance 秒懂大纲 ├── MAGDA: Multi-agent guideline-driven diagnostic assistance【研究主…

安全运维教程(非常详细)从零基础入门到精通,看完这一篇就够了

一、安全运维-网络 1、IP地址相关 IP地址属于网络层地址&#xff0c;用于标识网络中的节点设备。 IP地址由32bit构成&#xff0c;每8bit一组&#xff0c;共占用4个字节。 IP地址由两部分组成&#xff0c;网络位和主机位。 IP地址分类&#xff1a; 类别网络位子网掩码私有地…

嵌入式基本知识梳理

一、CPU的组成 CPU&#xff1a;中央处理器-----》soc(片上系统)&#xff08;描述的是一种芯片&#xff0c;这个芯片具有运算程序的能力&#xff09;、 UART: Universal Asynchronous Receiver/Transmitter&#xff0c;通用异步收发传输器&#xff09;是一种广泛使用的串行通信协…

达梦数据库导入xml迁移到达梦数据库大文件导致中断问题解决方案记录?

问题&#xff1a;我将同事给我的xml文件迁移到盗梦数据库&#xff0c;xml文件大约2G&#xff0c;在导入过程中&#xff0c;总是导入一半都不到就失败了。 原因&#xff1a;我的原因是我的电脑的系统的运行内存是16G的&#xff0c;后来我发现在没导入之前&#xff0c;其他进程已…

MODIS/Landsat/Sentinel下载教程详解【常用网站及方法枚举】

⛄前言 在当今快速发展的地球观测时代&#xff0c;遥感技术作为获取地球表面及其环境信息的重要手段&#xff0c;正以前所未有的广度和深度改变着我们对自然界的认知与管理方式。MODIS&#xff08;Moderate-resolution Imaging Spectroradiometer&#xff0c;中分辨率成像光谱…

Cloud Removal in Remote Sensing Using Sequential-BasedDiffusion Models论文翻译

MDPI 2023 论文名称:基于序列扩散模型的遥感云去除 摘要&#xff1a; 通过太空光学卫星收集的光学观测数据大多受到云层或雾霾的干扰&#xff0c;这限制了地球观测的进一步应用&#xff1b;因此&#xff0c;探索一种理想的去云方法至关重要。在本文中&#xff0c;我们提出了一…

电脑监控如何多画面显示?3个妙招分享,第一个你学会了吗?

电脑监控实现多画面显示&#xff0c;可以通过多种方法实现&#xff0c;以下是三个妙招的分享&#xff1a; 1. 使用专业监控软件 方法概述&#xff1a; 专业监控软件如安企神等&#xff0c;提供了强大的多画面显示功能。 这些软件通常支持自定义画面布局&#xff0c;如4分屏、…

鸿蒙Harmony应用开发,数据驾驶舱页面的实现

先来看看我们要实现的驾驶舱的页面是什么样的 对于这种 响应式布局的页面构建&#xff0c;我们的脑子里面要有一个概念&#xff0c;就是"分而治之"。我们把这个页面进行分割&#xff0c;分割成不同的块然后再来逐个实现. 不难发现&#xff0c;我们可以将这个看到的效…

【研发日记】嵌入式处理器技能解锁(六)——ARM的Cortex-M4内核

文章目录 前言 背景介绍 指令集架构 ARM起源 ARM分类 Cortex-M4 内核框架 指令流水线 实践应用 总结 参考资料 前言 见《【研发日记】嵌入式处理器技能解锁(一)——多任务异步执行调度的三种方法》 见《【研发日记】嵌入式处理器技能解锁(二)——TI C2000 DSP的SCI(…

数据结构与算法(Python)

引入 先来看一道题: 如果 abc1000&#xff0c;且 a^2b^2c^2&#xff08;a,b,c 为自然数&#xff09;&#xff0c;如何求出所有a、b、c可能的组合? 枚举法&#xff1a; # 如果 abc1000&#xff0c;且 a^2b^2c^2&#xff08;a,b,c 为自然数&#xff09;&#xff0c;如何求出…

ROS和ROS2借助智能大模型的学习和研究方法

机器人相关知识的本身和价值-CSDN博客 知识本身在智能时代毫无价值&#xff0c;需要基于知识应用和创新才有价值。 学历报废并非来自扩招&#xff0c;而是智能模型的快速发展。-CSDN blink-领先的开发者技术社区 2024年中秋&#xff0c;智能模型实力已经如此&#xff0c;但还…

Modbus_tcp

目录 一&#xff1a;modbus起源 1.起源 2. 分类&#xff1a; 3. 优势&#xff1a; 4. 应用场景&#xff1a; 5.ModbusTCP特点&#xff08;掌握&#xff09;&#xff1a; 二、 ModbusTCP的协议 1. 报文头 2. 寄存器 1. 线圈&#xff08;Coils&#xff09; 2. 离…

栈和队列OJ题C语言版

前情提要&#xff1a; 本次OJ题需要能够独立实现栈和队列&#xff0c;如果对栈和队列还不熟悉可以参考一下&#xff1a;栈和队列(C语言版)-CSDN博客 一、循环队列 1.题目 2.循环队列的概念 循环队列也是一种线性的数据结构&#xff0c;其操作表现基于先进先出的特性&#xff…

npm切换为淘宝镜像源

要切换 npm 的镜像源&#xff0c;您可以使用以下几种方法&#xff1a; 前言 然而&#xff0c;由于众所周知的网络环境问题&#xff0c;直接使用npm官方源下载依赖包时&#xff0c;常常会遇到速度慢甚至下载失败的情况。因此&#xff0c;使用更稳定、更快速的国内镜像源就显得尤…

JS基础:数组for循环年龄案例

<script>let eage1 []//定义一个空数组接受年龄for (let i 1; i < 5; i) {let eage prompt(请输入第${i}个年龄)//每次循环输入if (eage > 0 && eage < 100) {//满足0-100eage1.push(eage)//放入数组}}//1、依次打印数组输入进去的年龄document.writ…