void Atmosphere::raymarchEval(lwpp::VolumetricAccess va) { double density = 100.0, falloff = 10.0; double integstart = 0.0, integend = 100.0; double minstepsize = 0.01, maxstepsize = 100.0; double k = 200.0; double fogclr[ 3 ]; int use_lighting = 1, atmos_type = type; double dtau, last_dtau, total_tau, rstep, tau, x, y, h, col[ 4 ], trans; int nsteps = 0; /* record number of integration steps */ double li[ 3 ], last_li[ 3 ]; LWVolumeSample sample; /* differential color & opacity */ // ORIGINALLY LWDVector PP; lwpp::Point3D PP; LWMicropol mp; k *= res; falloff *= fa; density /= den; h = hi - lo; if ( h == 0 ) return; /* if using a texture, initialize the micropolygon */ if ( useTxtr ) { memset( &mp, 0, sizeof( LWMicropol )); mp.gNorm[ 1 ] = mp.wNorm[ 1 ] = 1.0; mp.oAxis = mp.wAxis = 1; mp.oScl[ 0 ] = mp.oScl[ 1 ] = mp.oScl[ 2 ] = 1.0; } /* get the fog color */ if ( bck ) { const double origin[3] = {va.getOrigin().x,va.getOrigin().y, va.getOrigin().z }; backdropinfo->backdrop( time, origin, fogclr ); } else { VCPY( fogclr, this->col ); } /* assume initially that the ray origin is in the fog */ sample.dist = va.getNearClip(); /* below the fog bottom, looking up */ if ( va.getDirection().y > 0 && va.getOrigin().y < lo ) { y = ( lo - va.getOrigin().y ); x = y / va.getDirection().y; sample.dist = sqrt( x * x + y * y ); } /* above the fog top, looking down */ if ( va.getDirection().y < 0 && va.getOrigin().y > hi ) { y = ( hi - va.getOrigin().y ); x = y / va.getDirection().y; sample.dist = sqrt( x * x + y * y ); } /* test if intersection within clipping range */ if ( sample.dist > va.getFarClip() ) return; // ORIGINALLY // VADDS3( PP, va.getOrigin(), va.getDirection(), sample.dist ); PP = ((lwpp::Point3D(va.getOrigin()) + lwpp::Vector3D(va.getDirection())) * sample.dist); y = ( PP.y - lo ) / h; /* test if outside fog */ if (( y > 1 && va.getDirection().y > 0 ) || ( y < 0 && va.getDirection().y < 0 )) return; dtau = density * GADD( va, PP.asLWDVector(), y, falloff, use_lighting, atmos_type, li ); rstep = 1.0 / ( k * dtau + 0.001 ); sample.stride = sample.dist * MAX( MIN( CLAMP( rstep, minstepsize, maxstepsize ), va.getFarClip() - sample.dist ), 0.0005 ); ++nsteps; total_tau = 0; while (( sample.dist <= va.getFarClip() ) && ( total_tau * opa < 300 ) && ( nsteps < 200 )) { last_dtau = dtau; VCPY( last_li, li ); // ORIGINALLY // VADDS3( PP, va.getOrigin(), va.getDirection(), sample.dist ); y = ( upcomp( PP.asLWDVector() ) - lo ) / h; /* test if outside fog */ if (( y > 1 && va.getDirection().y > 0 ) || ( y < 0 && va.getDirection().y < 0 )) return; dtau = density * GADD( va, PP.asLWDVector(), y, falloff, use_lighting, atmos_type, li ); if ( !useTxtr ) { trans = 0; VSCL3( col, fogclr, lum ); } else { trans = evalTexture( &mp, PP.asLWDVector(), sample.stride, col, txtr ); VSCL( col, lum ); } if ( trans != 1.0 ) { tau = 0.5 * sample.stride * ( dtau * ( 1.0 - trans ) + last_dtau ); total_tau += tau; /* color */ sample.color[ 0 ] = 0.5 * col[ 0 ] * sample.stride * ( li[ 0 ] * dtau + last_li[ 0 ] * last_dtau ); sample.color[ 1 ] = 0.5 * col[ 1 ] * sample.stride * ( li[ 1 ] * dtau + last_li[ 1 ] * last_dtau ); sample.color[ 2 ] = 0.5 * col[ 2 ] * sample.stride * ( li[ 2 ] * dtau + last_li[ 2 ] * last_dtau ); /* opacity */ VSET( sample.opacity, tau * opa ); /* add volumetric sample to the ray */ va.addSample( &sample ); } /* new stride = f(dist) */ rstep = 1.0 / ( k * dtau + 0.001 ); sample.stride = sample.dist * MAX( MIN( CLAMP( rstep, minstepsize, maxstepsize ), va.getFarClip() - sample.dist ), 0.0005 ); sample.dist += sample.stride; nsteps += 1; } }
void raymarchEval( const LWVolumeAccess *va, AtmosphereData *dat ) { double density = 100.0, falloff = 10.0; double integstart = 0.0, integend = 100.0; double minstepsize = 0.01, maxstepsize = 100.0; double k = 200.0; double fogclr[ 3 ]; int use_lighting = 1, atmos_type = dat->type; double dtau, last_dtau, total_tau, rstep, tau, x, y, h, col[ 4 ], trans; int nsteps = 0; /* record number of integration steps */ double li[ 3 ], last_li[ 3 ]; LWVolumeSample sample; /* differential color & opacity */ LWDVector PP; LWMicropol mp; k *= dat->res; falloff *= dat->fa; density /= dat->den; h = dat->hi - dat->lo; if ( h == 0 ) return; /* if using a texture, initialize the micropolygon */ if ( dat->useTxtr ) { memset( &mp, 0, sizeof( LWMicropol )); mp.gNorm[ 1 ] = mp.wNorm[ 1 ] = 1.0; mp.oAxis = mp.wAxis = 1; mp.oScl[ 0 ] = mp.oScl[ 1 ] = mp.oScl[ 2 ] = 1.0; } /* get the fog color */ if ( dat->bck ) backdropinfo->backdrop( dat->time, va->dir, fogclr ); else VCPY( fogclr, dat->col ); /* assume initially that the ray origin is in the fog */ sample.dist = va->nearClip; /* below the fog bottom, looking up */ if ( va->dir[ 1 ] > 0 && va->o[ 1 ] < dat->lo ) { y = ( dat->lo - va->o[ 1 ] ); x = y / va->dir[ 1 ]; sample.dist = sqrt( x * x + y * y ); } /* above the fog top, looking down */ if ( va->dir[ 1 ] < 0 && va->o[ 1 ] > dat->hi ) { y = ( dat->hi - va->o[ 1 ] ); x = y / va->dir[ 1 ]; sample.dist = sqrt( x * x + y * y ); } /* test if intersection within clipping range */ if ( sample.dist > va->farClip ) return; VADDS3( PP, va->o, va->dir, sample.dist ); y = ( upcomp( PP ) - dat->lo ) / h; /* test if outside fog */ if (( y > 1 && va->dir[ 1 ] > 0 ) || ( y < 0 && va->dir[ 1 ] < 0 )) return; dtau = density * GADD( va, PP, y, falloff, use_lighting, atmos_type, li ); rstep = 1.0 / ( k * dtau + 0.001 ); sample.stride = sample.dist * MAX( MIN( CLAMP( rstep, minstepsize, maxstepsize ), va->farClip - sample.dist ), 0.0005 ); ++nsteps; total_tau = 0; while (( sample.dist <= va->farClip ) && ( total_tau * dat->opa < 300 ) && ( nsteps < 200 )) { last_dtau = dtau; VCPY( last_li, li ); VADDS3( PP, va->o, va->dir, sample.dist ); y = ( upcomp( PP ) - dat->lo ) / h; /* test if outside fog */ if (( y > 1 && va->dir[ 1 ] > 0 ) || ( y < 0 && va->dir[ 1 ] < 0 )) return; dtau = density * GADD( va, PP, y, falloff, use_lighting, atmos_type, li ); if ( !dat->useTxtr ) { trans = 0; VSCL3( col, fogclr, dat->lum ); } else { trans = evalTexture( &mp, PP, sample.stride, col, dat->txtr ); VSCL( col, dat->lum ); } if ( trans != 1.0 ) { tau = 0.5 * sample.stride * ( dtau * ( 1.0 - trans ) + last_dtau ); total_tau += tau; /* color */ sample.color[ 0 ] = 0.5 * col[ 0 ] * sample.stride * ( li[ 0 ] * dtau + last_li[ 0 ] * last_dtau ); sample.color[ 1 ] = 0.5 * col[ 1 ] * sample.stride * ( li[ 1 ] * dtau + last_li[ 1 ] * last_dtau ); sample.color[ 2 ] = 0.5 * col[ 2 ] * sample.stride * ( li[ 2 ] * dtau + last_li[ 2 ] * last_dtau ); /* opacity */ VSET( sample.opacity, tau * dat->opa ); /* add volumetric sample to the ray */ va->addSample( va->ray, &sample ); } /* new stride = f(dist) */ rstep = 1.0 / ( k * dtau + 0.001 ); sample.stride = sample.dist * MAX( MIN( CLAMP( rstep, minstepsize, maxstepsize ), va->farClip - sample.dist ), 0.0005 ); sample.dist += sample.stride; nsteps += 1; } }