static MetaClass classlnstance;
} ;
Метод getOpacity для этого класса выглядит следующим образом:
OI
float LinearFog :: getOpacity ( const Vector3D& from,
const Vector3D& to, Plane * clipPlane ) const
{
Ray ray ( from, to - from ); // ray to sample fog
float tl, t2; // points of entering
// and leaving
float t; tl = 0;
t2 = from.distance ( to );
if ( !traceRay ( ray, tl, t2 ) ) return 0;
// now clip segment [tl, t2] to clipPlane if ( clipPlane != NULL &&
clipPlane -> intersectByRay ( ray.getOrigin(),
ray.getDir (), t ) )
{
bool clipFlag = clipPlane ->
classify ( from ) == IN_FRONT; ,
if ( clipFlag ) // ray is entering clipPlane
{
if ( t > tl )
tl = t;
}
else
{
if ( t < t2 )
t2 = t;
}
}
float densl = (ray.point ( tl ) & grad) + offs;
// density at point tl float dens2 = (ray.point ( t2 ) & grad) + offs;
// density at point t2
// now integrate density using trapzoid rule float opacity = 0.5f * (densl + dens2) * (t2 - tl) ;
return (opacity > l.Of ? l.Of : opacity);
}
Обратите внимание на то, что данный подход может некорректно обрабатывать полупрозрачные грани, находящиеся в тумане, - грани, видимые сквозь полупрозрачные грани, будут "затуманены" дважды: один раз при их выводе и еще один раз при выводе полупрозрачной грани.
Для поддержки объемного тумана следует внести изменение в класс SubScene - внутри каждой комнаты должен теперь храниться указатель на туман (объект класса Fog) и метод drawPoly должен при наличии тумана для каждого многоугольника вызывать метод drawFogPoly. Мы считаем, что внутри комнаты может находиться не более одного объекта, задающего объемный туман.
Добавляем эффекты
Для задания объемного тумана также понадобится введение дополнительных команд в формат описания сцены. Для этого добавим две новые команды fog и linear-fog, которые могут использоваться внутри комнаты для задания тумана с постоянной плотностью и тумана с линейно изменяющейся плотностью соответственно. Первая из них имеет вид