Пример #1
0
//-----------------------------------------------------------------------------
// Computes ambient lighting along a specified ray.
//-----------------------------------------------------------------------------
void CalcRayAmbientLighting(
	const Vector &vStart,
	const Vector &vEnd,
	Vector color[MAX_LIGHTSTYLES],
	Vector &colorSum )
{
	Ray_t ray;
	ray.Init( vStart, vEnd, vec3_origin, vec3_origin );

	directlight_t *pSkyLight = FindAmbientSkyLight();

	colorSum.Init();

	CLightSurface surfEnum;
	if (!surfEnum.FindIntersection( ray ))
		return;

	// This is the faster path; it looks slightly different though
	if (surfEnum.m_pSurface->dispinfo == -1)
	{
		ComputeLightmapColorFromAverage( surfEnum.m_pSurface, pSkyLight, color, colorSum );
	}
	else
	{
		ComputeLightmapColorDisplacement( surfEnum.m_pSurface, pSkyLight, surfEnum.m_LuxelCoord, color, colorSum );
	}
}
Пример #2
0
//-----------------------------------------------------------------------------
// Tests a particular surface
//-----------------------------------------------------------------------------
static bool FASTCALL FindIntersectionAtSurface( int surfID, float f, 
	Vector& c, LightVecState_t& state )
{
	// no lightmaps on this surface? punt...
	// FIXME: should be water surface?
	if (MSurf_Flags( surfID ) & SURFDRAW_NOLIGHT)
		return false;	

	// Compute the actual point
	Vector pt;
	VectorMA( state.m_Ray.m_Start, f, state.m_Ray.m_Delta, pt );

	mtexinfo_t* pTex = MSurf_TexInfo( surfID );
	
	// See where in lightmap space our intersection point is 
	float s, t;
	s = DotProduct (pt, pTex->lightmapVecsLuxelsPerWorldUnits[0].AsVector3D()) + 
		pTex->lightmapVecsLuxelsPerWorldUnits[0][3];
	t = DotProduct (pt, pTex->lightmapVecsLuxelsPerWorldUnits[1].AsVector3D()) + 
		pTex->lightmapVecsLuxelsPerWorldUnits[1][3];

	// Not in the bounds of our lightmap? punt...
	msurfacelighting_t *pLighting = SurfaceLighting( surfID );
	if( s < pLighting->m_pLightmapMins[0] || 
		t < pLighting->m_pLightmapMins[1] )
		return false;	
	
	// assuming a square lightmap (FIXME: which ain't always the case),
	// lets see if it lies in that rectangle. If not, punt...
	float ds = s - pLighting->m_pLightmapMins[0];
	float dt = t - pLighting->m_pLightmapMins[1];
	if( ds > pLighting->m_pLightmapExtents[0] || dt > pLighting->m_pLightmapExtents[1] )
		return false;	

	// Store off the hit distance...
	state.m_HitFrac = f;

	// You heard the man!
	ComputeTextureCoordsAtIntersection( pTex, pt, state.m_pTextureS, state.m_pTextureT );

#ifdef USE_CONVARS
	if( 1 )
#else
	if (r_avglight.GetInt())
#endif
	{
		// This is the faster path; it looks slightly different though
		ComputeLightmapColorFromAverage( pLighting, state.m_bUseLightStyles, c );
	}
	else
	{
		// Compute lightmap coords
		ComputeLightmapCoordsAtIntersection( pLighting, ds, dt, state.m_pLightmapS, state.m_pLightmapT );
		
		// Check out the value of the lightmap at the intersection point
		ComputeLightmapColor( surfID, (int)ds, (int)dt, state.m_bUseLightStyles, c );
	}

	return true;
}
Пример #3
0
//-----------------------------------------------------------------------------
// Computes ambient lighting along a specified ray.  
// Ray represents a cone, tanTheta is the tan of the inner cone angle
//-----------------------------------------------------------------------------
void CalcRayAmbientLighting( int iThread, const Vector &vStart, const Vector &vEnd, float tanTheta, Vector color[MAX_LIGHTSTYLES] )
{
	Ray_t ray;
	ray.Init( vStart, vEnd, vec3_origin, vec3_origin );

	directlight_t *pSkyLight = FindAmbientSkyLight();

	CLightSurface surfEnum(iThread);
	if (!surfEnum.FindIntersection( ray ))
		return;

	// compute the approximate radius of a circle centered around the intersection point
	float dist = ray.m_Delta.Length() * tanTheta * surfEnum.m_HitFrac;

	// until 20" we use the point sample, then blend in the average until we're covering 40"
	// This is attempting to model the ray as a cone - in the ideal case we'd simply sample all
	// luxels in the intersection of the cone with the surface.  Since we don't have surface 
	// neighbor information computed we'll just approximate that sampling with a blend between
	// a point sample and the face average.
	// This yields results that are similar in that aliasing is reduced at distance while 
	// point samples provide accuracy for intersections with near geometry
	float scaleAvg = RemapValClamped( dist, 20, 40, 0.0f, 1.0f );

	if ( !surfEnum.m_bHasLuxel )
	{
		// don't have luxel UV, so just use average sample
		scaleAvg = 1.0;
	}
	float scaleSample = 1.0f - scaleAvg;

	if (scaleAvg != 0)
	{
		ComputeLightmapColorFromAverage( surfEnum.m_pSurface, pSkyLight, scaleAvg, color );
	}
	if (scaleSample != 0)
	{
		ComputeLightmapColorPointSample( surfEnum.m_pSurface, pSkyLight, surfEnum.m_LuxelCoord, scaleSample, color );
	}
}
Пример #4
0
//-----------------------------------------------------------------------------
// Tests a particular surface
//-----------------------------------------------------------------------------
static bool FASTCALL FindIntersectionAtSurface( SurfaceHandle_t surfID, float f, 
	Vector& c, LightVecState_t& state )
{
	// no lightmaps on this surface? punt...
	// FIXME: should be water surface?
	if (MSurf_Flags( surfID ) & SURFDRAW_NOLIGHT)
		return false;	

	// Compute the actual point
	Vector pt;
	VectorMA( state.m_Ray.m_Start, f, state.m_Ray.m_Delta, pt );

	mtexinfo_t* pTex = MSurf_TexInfo( surfID );
	
	// See where in lightmap space our intersection point is 
	float s, t;
	s = DotProduct (pt, pTex->lightmapVecsLuxelsPerWorldUnits[0].AsVector3D()) + 
		pTex->lightmapVecsLuxelsPerWorldUnits[0][3];
	t = DotProduct (pt, pTex->lightmapVecsLuxelsPerWorldUnits[1].AsVector3D()) + 
		pTex->lightmapVecsLuxelsPerWorldUnits[1][3];

	// Not in the bounds of our lightmap? punt...
	msurfacelighting_t *pLighting = SurfaceLighting( surfID );
	if( s < pLighting->m_LightmapMins[0] || 
		t < pLighting->m_LightmapMins[1] )
		return false;	
	
	// assuming a square lightmap (FIXME: which ain't always the case),
	// lets see if it lies in that rectangle. If not, punt...
	float ds = s - pLighting->m_LightmapMins[0];
	float dt = t - pLighting->m_LightmapMins[1];
	if ( !pLighting->m_LightmapExtents[0] && !pLighting->m_LightmapExtents[1] )
	{
		worldbrushdata_t *pBrushData = host_state.worldbrush;

		// 
		float	lightMaxs[2];
		lightMaxs[ 0 ] = pLighting->m_LightmapMins[0];
		lightMaxs[ 1 ] = pLighting->m_LightmapMins[1];
		int i;
		for (i=0 ; i<MSurf_VertCount( surfID ); i++)
		{
			int e = pBrushData->vertindices[MSurf_FirstVertIndex( surfID )+i];
			mvertex_t *v = &pBrushData->vertexes[e];
			
			int j;
			for ( j=0 ; j<2 ; j++)
			{
				float sextent, textent;
				sextent = DotProduct (v->position, pTex->lightmapVecsLuxelsPerWorldUnits[0].AsVector3D()) + 
					pTex->lightmapVecsLuxelsPerWorldUnits[0][3] - pLighting->m_LightmapMins[0];
				textent = DotProduct (v->position, pTex->lightmapVecsLuxelsPerWorldUnits[1].AsVector3D()) + 
					pTex->lightmapVecsLuxelsPerWorldUnits[1][3] - pLighting->m_LightmapMins[1];

				if ( sextent > lightMaxs[ 0 ] )
				{
					lightMaxs[ 0 ] = sextent;
				}
				if ( textent > lightMaxs[ 1 ] )
				{
					lightMaxs[ 1 ] = textent;
				}
			}
		}
		if( ds > lightMaxs[0] || dt > lightMaxs[1] )
			return false;	
	}
	else
	{
		if( ds > pLighting->m_LightmapExtents[0] || dt > pLighting->m_LightmapExtents[1] )
			return false;	
	}

	// Store off the hit distance...
	state.m_HitFrac = f;

	// You heard the man!
	ComputeTextureCoordsAtIntersection( pTex, pt, state.m_pTextureS, state.m_pTextureT );

#ifdef USE_CONVARS
	if ( r_avglight.GetInt() )
#else
	if ( 1 )
#endif
	{
		// This is the faster path; it looks slightly different though
		ComputeLightmapColorFromAverage( pLighting, state.m_bUseLightStyles, c );
	}
	else
	{
		// Compute lightmap coords
		ComputeLightmapCoordsAtIntersection( pLighting, ds, dt, state.m_pLightmapS, state.m_pLightmapT );
		
		// Check out the value of the lightmap at the intersection point
		ComputeLightmapColor( surfID, (int)ds, (int)dt, state.m_bUseLightStyles, c );
	}

	return true;
}