大气层散射球类AtmosphericScatteringSphere代表地球外面的大气层散射球模型,可以控制开启/关闭渲染该对象。该类的类图如下。

该类所包含的主要字段、属性和方法如下:

public float m_radius;//大气层散射球半径,默认为地球赤道半径的1.025倍

protected int m_numberSlices; //大气层散射球切片数目,默认为75

protected int m_numberSections; //大气层散射球半径分割段数,默认为75

public static float m_fInnerRadius = 0; //大气层散射球内半径

public static float m_fOuterRadius = 0; //大气层散射球外半径

public static int TilesHigh = 4; //大气层散射球瓦片高度

public static int TilesWide = 8; //大气层散射球瓦片宽度

System.Collections.Generic.List<MeshSubset> m_meshList = new System.Collections.Generic.List<MeshSubset>();//存储大气层散射球剖分的格网子集

Vector3 m_lastSunPosition = Vector3.Empty;//太阳位置

System.Threading.Thread m_backgroundThread = null;//渲染大气层散射球的后台线程

bool active = false;//是否激活大气层散射球

System.DateTime m_lastOpticalUpdate = System.DateTime.MinValue; //大气层散射球最后的不透明度更新时间

bool m_canDoShaders = false;//是否能够执行着色器

short[] m_indices = null;//剖分散射球时的顶点索引,用来构造索引缓冲区

short[] m_indicesHighResolution = null;//精细的顶点索引,实际是通过指定精细的格网顶点密度是前者的2倍来重新计算实现的,75/4=18.75,取整为18,则精细的格网顶点密度为36

float[] fCameraDepth = new float[4] { 0, 0, 0, 0 };//相机深度

float[] fLightDepth = new float[4];//光照深度

float[] fSampleDepth = new float[4];//采样深度

float[] fRayleighSum = new float[] { 0, 0, 0 };//瑞利散射和

float[] fMieSum = new float[] { 0, 0, 0 };//米尔散射和

Vector3 vPos = new Vector3();//光照位置

float[] fAttenuation = new float[3];//环境光

Vector3 vCamera = new Vector3();相机位置

public void Init(float radius, int slices, int sections)方法用来初始化大气层散射球,内部调用SunCalculator类、TimeKeeper类和BoundingBox类的静态函数,这两个类在本篇结束时附后讲解。将散射球切分成4行×8列=32块,每一步内部又按照指定的格网子集密度(如纵、横密度均为18)进一步剖分计算需要绘制的格网顶点。默认经度和纬度的分割间隔均为45度。内部又调用CustomVertex.PositionColored[] CreateMesh(double minLat, double maxLat, double minLon, double maxLon, int meshPointCount)函数根据输入的经纬度范围创建格网子集。

public void Update(DrawArgs drawArgs)方法用来更新大气散射球的光照、模型等渲染元素,内部实际上是发起后台线程backgroundThread来实现的,线程绑定的处理函数为private void Updater()。而Update函数是在World类的public override void Update(DrawArgs drawArgs)中被调用的。

CustomVertex.PositionColored[] CreateMesh(double minLat, double maxLat, double minLon, double maxLon, int meshPointCount) 函数根据输入的经、纬度范围和格网子集密度来创建格网子集的顶点数组。

short[] computeIndices(int meshPointCount)方法根据指定的格网子集密度来计算每个格网顶点的索引,以便渲染时索引缓冲区使用。其中,索引总数=纵向点数×横向点数×2×3。在数组中索引范围为[0,索引总数-1]。

void Interpolate(ref float[] p, float x, float y)被SetColor函数调用。

public void SetColor(ref CustomVertex.PositionColored pVertex, DrawArgs drawArgs)被UpdateColor和getAtmosphereColor函数调用。

int getAtmosphereColor(DrawArgs drawArgs,CustomVertex.PositionColored pVertex)被ColoredSpherePartial函数调用。

private void UpdateColor(DrawArgs drawArgs, MeshSubset meshSubset, bool doHighResolution)函数暂时未被调用,所以处理颜色函数可以暂时不用分析。

private Mesh ColoredSpherePartial(DrawArgs drawArgs, float radius, double startLat, double endLat, int slices, int stacks, double lonSpan, double heading) 被UpdateSkyMesh函数调用。

void UpdateLightVector(),根据太阳位置更新光照位置和方向,被Render()和Updater()函数调用。

private void UpdateSkyMesh(DrawArgs drawArgs, double horizonSpan)被Render()函数调用。

public void Render(DrawArgs drawArgs) 方法在World类的public override void Render(DrawArgs drawArgs)中被调用的。

void MakeOpticalDepthBuffer(float fInnerRadius, float fOuterRadius, float fRayleighScaleHeight, float fMieScaleHeight) 被Updater()函数调用。

  实际上,大气散射球类只需要重点关注Update(DrawArgs drawArgs)和Render(DrawArgs drawArgs)两个方法,其余方法均直接或间接的被这两个方法调用。而这两个方法又分别被World类的Update(DrawArgs drawArgs)和Render(DrawArgs drawArgs)函数调用。

WorldWind源码剖析系列:大气层散射球类AtmosphericScatteringSphere的更多相关文章

  1. WorldWind源码剖析系列:星球类World

    星球类World代表通用的星球类,因为可能需要绘制除地球之外的其它星球,如月球.火星等.该类的类图如下. 需要说明的是,在WorldWind中星球球体的渲染和经纬网格的渲染时分别绘制的.经纬网格的渲染 ...

  2. WorldWind源码剖析系列:星球球体的加载与渲染

    WorldWind源码剖析系列:星球球体的加载与渲染 WorldWind中主函数Main()的分析 在文件WorldWind.cs中主函数Main()阐明了WorldWind的初始化运行机制(如图1所 ...

  3. WorldWind源码剖析系列:星球表面渲染类WorldSurfaceRenderer

    星球表面渲染类WorldSurfaceRenderer描述如何渲染星球类(如地球)表面影像纹理.该类的类图如下. 星球类World包含的主要的字段.属性和方法如下: public const int ...

  4. WorldWind源码剖析系列:表面影像类SurfaceImage

    表面影像类SurfaceImage描述星球类(如地球)表面纹理影像.该类的类图如下. 表面影像类SurfaceImage包含的主要的字段.属性和方法如下: string m_ImageFilePath ...

  5. WorldWind源码剖析系列:影像存储类ImageStore、Nlt影像存储类NltImageStore和WMS影像存储类WmsImageStore

    影像存储类ImageStore 影像存储类ImageStore提供了计算本地影像路径和远程影像影像URL访问的各种接口,是WmsImageStore类和NltImageStore类的基类.当划分完层次 ...

  6. WorldWind源码剖析系列:设置类SettingsBase

    PluginSDK中的星球设置类WorldSettings 和WorldWind.程序设置类WorldWindSettings均继承自父类SettingsBase.类图如下所示.其中父类Setting ...

  7. WorldWind源码剖析系列:表面瓦片类SurfaceTile

    表面瓦片类SurfaceTile描述星球类(如地球)表面纹理影像的瓦片模型.其类图如下. 表面瓦片类SurfaceTile包含的主要的字段.属性和方法如下: int m_Level;//该瓦片所属金字 ...

  8. WorldWind源码剖析系列:挂件类Widgets

    WorldWindow用户定制控件类中所包含的的挂件类Widgets控件主要有如下图所示的派生类.它们的类图如下所示. 鉴于挂件类Widgets及其派生类,相对简单,基本上都是些利用DirectX3D ...

  9. WorldWind源码剖析系列:外包围盒类BoundingBox和外包围球类BoundingSphere

    PluginSDK中的外包围盒.外包围球分别用类 BoundingBox和BoundingSphere描述,其类图如下所示. 外包围盒BoundingBox类的corners字段用来存储外包围盒的8个 ...

随机推荐

  1. 安装Mysql报错**此用户已存在!**

    我是安装了两个installer下载器,将其中一个删除运行另一个就会报这个错. 解决办法:将删除的那个installer从回收站还原.

  2. Hexo的搭建

    Hexo的安装与初始化 1.确保电脑已经安装Node.js,Git 打开GUI Bash,输入以下代码安装Hexo: npm install -g hexo-cli 2.运行以下命令在目标文件夹初始化 ...

  3. RocketMQ 主从同步机制

    主从同步(HA 高可用) 主从同步原理: 为了保证系统的高可用,消息到达主服务器后,需要将消息同步到从服务器.如果主服务器宕机,消费者可用从从服务器拉取消息. 大体步骤: 1.主服务器启动,监听从服务 ...

  4. linux系统编程:cp的另外一种实现方式

    之前,这篇文章:linux系统编程:自己动手写一个cp命令 已经实现过一个版本. 这里再来一个版本,涉及知识点: linux系统编程:open常用参数详解 Linux系统编程:简单文件IO操作 /*= ...

  5. Codeforces292D(SummerTrainingDay06-L 前缀并查集)

    D. Connected Components time limit per test:2 seconds memory limit per test:256 megabytes input:stan ...

  6. Python数据模型

    引言 像大多数人一样,我在对一直传统的面向过程语言C一知半解之后,走进了面向对象的世界,尽管对OOP一无所知,还好Python还保留有函数式编程,这使得我才不那么抵触,直到现在,习惯了面向对象之后,也 ...

  7. linux服务器SSH破解预防方法

    1.linux服务器通过配置 /etc/hosts.deny 禁止对方IP通过SSH登录我的服务器 vim /etc/hosts.deny 2.不用SSH服务的默认端口22,重新设置一个新端口,最好设 ...

  8. html 手机web超出屏幕宽度的内容不换行,并产生横向滚动条

     html 手机web超出屏幕宽度的内容不换行,并产生横向滚动条 white-space: nowrap;overflow-x: scroll;    

  9. JS数组和对象的浅拷贝和深拷贝

    共勉~ 在许多编程语言中,传递参数和赋值是通过值的直接复制或者引用复制完成的.在JavaScript中,对于值是直接进行复制还是引用复制在语法上是没有区别的,完全是根据值的类型来决定的. 在JavaS ...

  10. Spring Boot系列学习文章(二) -- 配置多数据源

    前言: 在上一章中,我们已经搭建好项目,现在来讲一下如何配置数据源. 由于在有的项目中,用的数据源可能会涉及多个,且是不同类型的,我们接下来就讲解多数据源的配置. 情景描述: 现有项目需要访问不同的数 ...