Некоторое время назад я реализовал симуляцию цвета неба, следуя учебному пособию по созданию пикселя: https://www.scratchapixel.com/lessons/procedural-generation-virtual-worlds/simulating-sky
Я адаптировал его к фактическому положению солнца и могу получить реалистичные цвета неба в течение дня. Тем не менее, я заметил, что после заката / до восхода солнца цвета становятся сероватыми, когда они должны быть темно-синими. После изучения этого я прочитал, что это связано с отсутствием поглощения озона в моей модели.
Я использовал коэффициенты вымирания: (3.426,8.298,0.356) * 0.06e-5 -> найдено на https://media.contentapi.ea.com/content/dam/eacom/frostbite/files/s2016-pbs-frostbite-sky-clouds-new.pdf
а также прочитайте, что, поскольку озон не рассеивается, его следует добавить только к значению коэффициента пропускания.
Уравнение
Поэтому я изменил код с нуля следующим образом:
for (uint32_t i = 0; i < numSamples; ++i) {
vec3 samplePosition = ray_in2.origin() + (tCurrent +
segmentLength * 0.5f) * ray_in2.direction();
float height = samplePosition.length() - atmosphere.earthRadius;
// compute optical depth for light
float hr = exp(-height / atmosphere.Hr) * segmentLength;
float hm = exp(-height / atmosphere.Hm) * segmentLength;
float ho = exp(-height / atmosphere.Hr)* segmentLength*(6e-7);
opticalDepthR += hr;
opticalDepthM += hm;
opticalDepthO += ho;
// light optical depth
float t0Light, t1Light;
...
for (j = 0; j < numSamplesLight; ++j) {
vec3 samplePositionLight = samplePosition + (tCurrentLight +
segmentLengthLight * 0.5f) * sunDir;
float heightLight = samplePositionLight.length() -
atmosphere.earthRadius;
if (heightLight < 0) break;
opticalDepthLightR += exp(-heightLight / atmosphere.Hr) *
segmentLengthLight;
opticalDepthLightM += exp(-heightLight / atmosphere.Hm) *
segmentLengthLight;
opticalDepthLightO += exp(-heightLight / atmosphere.Hr) *
segmentLengthLight*(6e-7); ;
tCurrentLight += segmentLengthLight;
}
if (j == numSamplesLight) {
vec3 tau = (betaR) * (opticalDepthR + opticalDepthLightR) +
betaM * 1.1f * (opticalDepthM + opticalDepthLightM)+ betaO*
(opticalDepthO + opticalDepthLightO);
vec3 attenuation(exp(-tau.x()), exp(-tau.y()), exp(-
tau.z()));
Резюме:
Проблема в том, что я не вижу разницы в цвете моего неба до и после
добавление озона. Может кто-нибудь подсказать мне, что я делаю не так?
Задача ещё не решена.
Других решений пока нет …