Пример #1
0
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;
   }
}
Пример #2
0
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;
   }
}