Cesium中通过射线计算日照

Cesium中通过射线计算日照

在这里插入图片描述

前段时间接触到一个需求,需要实时的计算建筑的日照,通常优先通过shadow map来实现。通过shadow map可以直接获取某一时刻的光照信息,累积不同太阳光位置的shadow map即可得到物体表面的光照时长。

不过本人技术有限,还没能力手撕shadow map,之前看了光线追踪的内容,考虑到也可以通过射线求交的方法来计算物体表面是否直达光源,来累积光照时长。

累积光照时长需要解决一下几个问题:

  • 对于复杂几何结构的物体不可能直接求交,算法过于复杂
  • 需要知道不同时刻的太阳位置
  • 不同的日照时长通过不同的颜色来表达

OBB

这里仅实现对立方体的遮挡计算,即通过计算物体的有向外包矩形来概化射线求交。

太阳位置

Cesium中内置了计算太阳位置的方法,通过Simon1994PlanetaryPositions可以计算得到某时刻的太阳在地球坐标系内的位置。对应代码中的SunHelper.js文件中的方法。

let transforMatrix=Transforms.computeTemeToPseudoFixedMatrix(date);
let sunpos=Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame(date);
Matrix3.multiplyByVector(transforMatrix,sunpos,sunpos);

由于晚上没必要计算日照,所以多加一步,在物体的位置生成一个平面,当作地平线,在平面以下的当作晚上,在平面以上的当作白天。仅在平面以上的太阳位置需要参与计算

颜色表达

能累积到光照的次数后,即可以直接换算到不同的颜色,可以用LUT,也直接除一个整数限制到1以内即可

实现流程

起止日期计算太阳位置

这里计算得到的太阳位置需要换成光线方向,并不是需要真的太阳位置。太阳位置减去物体位置得到大致的光线方向。如下sunposs存储筛选后的太阳光线方向。

const startDate = JulianDate.fromDate(new Date("2023/07/02 18:00:00"));
viewer.clockViewModel.currentTime = startDate;
const hours = 24;
const sunposs = [];
for (let i = 0; i < hours; i++) {const date = new JulianDate();JulianDate.addHours(startDate, i, date);console.log(date);let sunpos = ComputeSunPos(date);const dir = new Cartesian3();Cartesian3.subtract(sunpos, suninitpos, dir);Cartesian3.normalize(dir, dir);const dist = Plane.getPointDistance(tgplane, sunpos);if (dist > 0) {sunposs.push(dir);}
}

生成立方体

我手上没有实际的楼的数据,就手动创建了几个立方体,来计算遮挡。

可以参看createBox方法。

立方体即当作OBB,传入FragmentShader中参与相交计算。OBB通过一个立方体中心,和立方体的三个半轴来构造。数据也仅传入立方体中心和三个半轴。

最开始担心精度抖动问题,立方体中心点采用了EncodedCartesian3进行了高低位拆分。中心和半轴依次存入boxcentersboxaxies中。

提交数据到GPU

数据还是通过uniform类型来提交,暂未考虑数据过大的问题。

不支持uniform数组

调试的时候发现,通过{type: , value: }提交数据后,无法正确传入到shader中。翻看createUniformArray.js中的代码发现UniformArrayFloatVec3.set方法,对于提交的数组并没有正确解析(也可能是没找到正确的用法),这里我直接改了对应的代码,在设置value的时候判断一下是不是数组。

const value = this.value instanceof Array?this.value:this.value.value;

数据提交还是正常的fabric,里面的rtc_lxs也是测试精度抖动问题,感觉实际并没有多少效果。

fabric: {uniforms: {lxs: { type: `vec3[${sunposs.length}]`, value: sunposs },boxcenters: { type: `vec3[${boxcenters.length}]`, value: boxcenters },boxaxies: { type: `vec3[${boxaxies.length}]`, value: boxaxies },rtc_lxs:new Cartesian3(-2764233.530084816, 4787599.944020384, 3170398.735383637)}}

立方体求交

OBB求交就不多说了,还是用的PlaneSet,即一对平面,立方体为三组平面,通过计算射线的进去,离开的时间来判断是否相交。

在FS中实现相交算法后,即可遍历太阳位置和立方体,判断每个太阳下,立方体直接的相互遮挡,记录相交次数。

在立方体相交时,剔除法线和光线朝向反向的顶点,保证背面不累计次数。

具体代码,看仓库里面吧。懒得说了。

现有问题

目前计算过于耗时,在距离立方体近的视角下,帧数只有个位数,后面有时间再优化一下。

在这里插入图片描述

边缘计算抖动: 在能射到光源和不能射到光源的交界处,计算总是抖动,边界及其不稳定,这个不知道啥问题,有大佬懂得可以指教一下。

代码没整理,后期优化。

仓库地址

YHLpuyu/cesium_shine: cesium实现日照分析,纯几何方法 (github.com)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SPINN:基于设备和云的神经网络协同递进推理

SPINN&#xff1a;基于设备和云的神经网络协同递进推理 论文标题&#xff1a;SPINN: synergistic progressive inference of neural networks over device and cloud 原文链接&#xff1a;https://dl.acm.org/doi/10.1145/3372224.3419194 论文动机 现代CNN过多的计算需求&am…

将 Kwargs 传递给 Python 中的另一个函数

文章目录 Python 中的关键字参数在 Python 中使用**kwargs 调用函数使用 Python 将 kwargs 传递给另一个函数总结 Python 列出了可以传递给程序中的函数的两种类型的参数。 非关键字参数 (**args) 和关键字参数 (**kwargs)。 通常&#xff0c;python 函数必须使用正确数量的参…

华秋亮相2023世界汽车制造技术暨智能装备博览会,推动汽车产业快速发展

洞悉全球汽车产业格局&#xff0c;前瞻业界未来趋势。2023年7月27日-30日&#xff0c;时隔三年&#xff0c;重聚武汉国际博览中心&#xff0c;2023世界汽车制造技术暨智能装备博览会盛大开幕。深耕汽车行业多年的世界汽车制造技术暨智能装备博览会&#xff0c;掀起行业热点新高…

死磕Android性能优化,卡顿原因与优化方案

随着移动互联网的快速发展&#xff0c;Android应用的性能优化变得尤为重要。卡顿是用户体验中最常见的问题之一&#xff0c;它会导致应用的响应变慢、界面不流畅&#xff0c;甚至影响用户的使用体验。因此&#xff0c;我们需要深入了解卡顿问题的原因&#xff0c;并寻找相应的解…

Java中ArrayList常用方法的学习

Java中ArrayList常用方法的学习 需求分析代码实现小结Time 需求分析 ArrayList集合的常用方法学习 代码实现 java.util.ArrayList;/*** Author:LQ* Description:* Date:Created in 16:45 2023/8/9*/ public class ListTest {public static void main(String[] args) {ArrayLis…

WMS系列:层级树的surface 的创建

WMS 创建的surface 与 surfaceflinger 创建的Layer 是一一对应的&#xff0c;只不过可能是创建不同的 Layer 1. DefaultTaskDisplayArea 对应的surface 的创建 DefaultTaskDisplayArea 的调用栈如下&#xff0c;是在系统进程启动服务的时候&#xff0c;去创建对应的SurfaceCont…

Flutter:屏幕适配

flutter_screenutil flutter_screenutil是一个用于在Flutter应用程序中进行屏幕适配的工具包。它旨在帮助开发者在不同屏幕尺寸和密度的设备上创建响应式的UI布局。 flutter_screenutil提供了一些用于处理尺寸和间距的方法&#xff0c;使得开发者可以根据设备的屏幕尺寸和密度…

Segment Anything(SAM) 计算过程

给定输入图像 I ∈ R 3 H W I \in R^{3 \times H \times W} I∈R3HW。给定需要的prompts&#xff1a; M ∈ R 1 H W M \in R^{1 \times H \times W} M∈R1HW&#xff0c;代表图片的前背景信息。 P ∈ R N 2 P \in R^{N \times 2} P∈RN2&#xff0c;其中 N N N 是点的个数…

vscode 搭建STM32开发环境

1.需要软件 1.1 vscode 1.2 STM32CubeMX&#xff0c;这个不是必须的&#xff0c;我是为了方便生成STM32代码 2.vscode配置 2.1安装keil Assistant 2.2配置keil Assistant 3.STMCUBE生成个STM32代码 &#xff0c;如果有自己的代码可以忽略 4.代码添加到vscode&#xff0c;并…

模拟出栈的所有顺序(dfs+回溯)

题目&#xff1a; 已知某一个字母序列&#xff0c;把序列中的字母按出现顺序压入一个栈&#xff0c;在入栈的任意过程中&#xff0c;允许栈中的字母出栈&#xff0c;求所有可能的出栈顺序 示例&#xff1a; 输入abc 输出abc、acb、bac、bca、cba 代码如下 #define _CRT_SECURE…

JAVA集合框架 一:Collection(LIst,Set)和Iterator(迭代器)

目录 一、Java 集合框架体系 1.Collection接口&#xff1a;用于存储一个一个的数据&#xff0c;也称单列数据集合&#xff08;single&#xff09;。 2.Map接口&#xff1a;用于存储具有映射关系“key-value对”的集合&#xff08;couple&#xff09; 3.Iterator接口&#…

【ChatGPT 指令大全】怎么使用ChatGPT来辅助学习英语

在当今全球化的社会中&#xff0c;英语已成为一门世界性的语言&#xff0c;掌握良好的英语技能对个人和职业发展至关重要。而借助人工智能的力量&#xff0c;ChatGPT为学习者提供了一个有价值的工具&#xff0c;可以在学习过程中提供即时的帮助和反馈。在本文中&#xff0c;我们…

Android 视频播放器dkplayer

列表播放如图所示&#xff1a; 一、依赖 //添加RecyclerView的依赖包implementation androidx.recyclerview:recyclerview:1.2.1// 异步加载图片依赖implementation com.squareup.picasso:picasso:2.5.2// 上拉刷新、下来加载依赖implementation com.scwang.smartrefresh:Smart…

Kubernetes工作原理

一、案例概述 传统部署时代&#xff1a; 早期是在物理服务器上运行应用程序。无法为物理服务器中的应用程序定义资源边界&#xff0c;这会导致资源分配出现问题。例如&#xff1a;如果在物理服务器上运行多个应用程序&#xff0c;则可能会出现一个应用程序占用大部分资源的情况…

ffplay简介

本文为相关课程的学习记录&#xff0c;相关分析均来源于课程的讲解&#xff0c;主要学习音视频相关的操作&#xff0c;对字幕的处理不做分析 ffplay播放器的意义 ffplay.c是FFmpeg源码⾃带的播放器&#xff0c;调⽤FFmpeg和SDL API实现⼀个⾮常有⽤的播放器。 ffplay实现了播…

Spring Data学习笔记Day01-SpringData入门

Spring Data基本介绍 目录 Spring Data Redis 官方API参考手册&#xff01;★ Spring Data的价值★ Spring Data及其子项目★ 强大的Spring Data★ Repository接口★ 具体Repository接口★ Spring Data JPA开发★ Spring Boot如何选择DataSource★ 数据源相关配置★ 配置第三方…

爬虫014_文件操作_打开关闭_读写_序列化_反序列化---python工作笔记033

报错,没有指定路径,没有指定路径无法创建文件 这样可以在当前目录下创建一个可写的文件 可以看到找到刚才生成的文件,看看内容

Android进阶之SeekBar动态显示进度

SeekBar 在开发中并不陌生,默认的SeekBar是不显示进度的,当然用吐司或者文案在旁边实时显示也是可以的,那能不能移动的时候才显示&#xff0c;默认不显示呢,当然网上花哨的三方工具类太多了&#xff0c;但是我只是单纯的想在SeekBar的基础上去添加一个可以跟随移动显示的气泡而…

虹科新闻 | 虹科与Power-MI正式建立合作伙伴关系

近日&#xff0c;虹科与Power-MI正式建立合作伙伴关系&#xff0c;双方就工业预测性维护领域进行深入的交流与合作&#xff0c;未来将共同致力于为亚洲市场提供完整的、更高质量的预测性维护解决方案&#xff0c;解决亚洲客户的工业自动化挑战。 虹科与Power-MI都表示十分期待…

MySQL的查询方法

单表查询 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 要求&#xff1a; 1、显示所有职工的基本信息。 2、查询所有职工所属部门的部门号&#xff0c;不显示重复的部门号。 3、求出所有职工的人数。 4、…