WorldWind源码剖析系列:大气层散射球类AtmosphericScatteringSphere
大氣層散射球類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)函數調用。
轉載于:https://www.cnblogs.com/rainbow70626/p/4584201.html
總結
以上是生活随笔為你收集整理的WorldWind源码剖析系列:大气层散射球类AtmosphericScatteringSphere的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多谐振荡器工作周期分析
- 下一篇: SLAM知识图谱(知识树/技能树)