由于做全球體積云效果的需要,再來研究下大氣散射效果
和體積云類似,關于大氣散射顏色計算的過程也僅發生在這兩個球體之間。如圖所示。
?
計算從相機出發的視線與球殼的交點,如果不相交,則該視線方向上不會發生大氣散射,直接返回透明色。
// 檢查與大氣外層球體的相交vec2 atmo_intersect = raySphereIntersect(start, dir, dynamic_atmo_radius);vec2 planet_intersect = raySphereIntersect(start, dir, planet_radius);// 如果不相交大氣層,直接返回
if (atmo_intersect.x < 0.0) return scene_color;
?這段代碼是大氣散射物理模型的核心部分,用于模擬光線在大氣中的散射行為。
學術解釋:真實物理現象的數學建模,不是簡單的視覺效果,而是基于光學理論的準確模擬。
簡單來說:
- 瑞利散射:讓天空變藍
- 米氏散射:讓太陽周圍發光
- mu:決定你看向太陽的角度對散射強度的影響
// 散射計算
float mu = dot(dir, light_dir);// 瑞利散射相函數
float phase_ray = 0.75 * (1.0 + mu * mu);// 米氏散射相函數 (簡化)
float phase_mie = 1.5 * ((1.0 - 0.9 * 0.9) / (2.0 + 0.9 * 0.9)) * (1.0 + mu * mu) / pow(1.0 + 0.9 * 0.9 - 2.0 * 0.9 * mu, 1.5);
?最重要的一步 就是光線步進
for (int i = 0; i < MARCH_STEPS; i++) {// 當前采樣點位置float t = ray_start + (float(i) + 0.5) * step_size;vec3 sample_pos = start + dir * t;// 計算當前高度和大氣密度float height = length(sample_pos) - planet_radius;float density_ray = exp(-height / 8000.0); // 瑞利散射標度高度:8kmfloat density_mie = exp(-height / 1200.0); // 米氏散射標度高度:1.2km// 計算光學深度(光線衰減)float optical_depth_step = (density_ray + density_mie) * step_size;total_optical_depth += optical_depth_step;// 計算透射率(光線在大氣中的衰減)float transmittance = exp(-total_optical_depth * 0.00001); // 衰減系數// 🌟 太陽光到當前點的衰減(次級光線步進 - 簡化版)float sun_optical_depth = 0.0;vec2 sun_intersect = raySphereIntersect(sample_pos, light_dir, dynamic_atmo_radius);if (sun_intersect.y > 0.0) {float sun_ray_length = sun_intersect.y;// 簡化的太陽光衰減計算float avg_height = height + sun_ray_length * 0.5 * light_dir.y;sun_optical_depth = exp(-avg_height / 8000.0) * sun_ray_length;}float sun_transmittance = exp(-sun_optical_depth * 0.00001);// 計算當前步的散射貢獻vec3 step_ray_scattering = beta_ray * density_ray * phase_ray * transmittance * sun_transmittance * step_size;vec3 step_mie_scattering = beta_mie * density_mie * phase_mie * transmittance * sun_transmittance * step_size;// 累積散射total_ray_scattering += step_ray_scattering;total_mie_scattering += step_mie_scattering;}
?最終效果如圖所示 左側為沒有處理的,ceisum自帶的大氣效果,右側為添加散射的效果
其實只看圖片的話,可能大部分人會覺得太陽都看不清楚有什么必要加,但這個散射在體積云中效果就很明顯了,場景也明細更加貼近顯示大氣效果。
todo:將大氣和全球體積云效果融合