r712 - trunk/code/renderer

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Thu Apr 20 00:43:44 EDT 2006


Author: thilo
Date: 2006-04-20 00:43:43 -0400 (Thu, 20 Apr 2006)
New Revision: 712

Modified:
   trunk/code/renderer/tr_flares.c
   trunk/code/renderer/tr_init.c
   trunk/code/renderer/tr_local.h
   trunk/code/renderer/tr_shader.c
   trunk/code/renderer/tr_surface.c
Log:
Fix for flares. Can be enabled by setting r_flares 1


Modified: trunk/code/renderer/tr_flares.c
===================================================================
--- trunk/code/renderer/tr_flares.c	2006-04-19 23:01:48 UTC (rev 711)
+++ trunk/code/renderer/tr_flares.c	2006-04-20 04:43:43 UTC (rev 712)
@@ -75,6 +75,7 @@
 	int			windowX, windowY;
 	float		eyeZ;
 
+	vec3_t		origin;
 	vec3_t		color;
 } flare_t;
 
@@ -83,6 +84,8 @@
 flare_t		r_flareStructs[MAX_FLARES];
 flare_t		*r_activeFlares, *r_inactiveFlares;
 
+int flareCoeff;
+
 /*
 ==================
 R_ClearFlares
@@ -113,11 +116,22 @@
 	int				i;
 	flare_t			*f, *oldest;
 	vec3_t			local;
-	float			d;
+	float			d = 1;
 	vec4_t			eye, clip, normalized, window;
 
 	backEnd.pc.c_flareAdds++;
 
+	if(normal && (normal[0] || normal[1] || normal[2]))
+	{
+		VectorSubtract( backEnd.viewParms.or.origin, point, local );
+		VectorNormalizeFast(local);
+		d = DotProduct(local, normal);
+
+		// If the viewer is behind the flare don't add it.
+		if(d < 0)
+			return;
+	}
+
 	// if the point is off the screen, don't bother adding it
 	// calculate screen coordinates and depth
 	R_TransformModelToClip( point, backEnd.or.modelMatrix, 
@@ -171,16 +185,12 @@
 	f->addedFrame = backEnd.viewParms.frameCount;
 	f->fogNum = fogNum;
 
+	VectorCopy(point, f->origin);
 	VectorCopy( color, f->color );
 
 	// fade the intensity of the flare down as the
 	// light surface turns away from the viewer
-	if ( normal ) {
-		VectorSubtract( backEnd.viewParms.or.origin, point, local );
-		VectorNormalizeFast( local );
-		d = DotProduct( local, normal );
-		VectorScale( f->color, d, f->color ); 
-	}
+	VectorScale( f->color, d, f->color ); 
 
 	// save info needed to test
 	f->windowX = backEnd.viewParms.viewportX + window[0];
@@ -197,31 +207,39 @@
 void RB_AddDlightFlares( void ) {
 	dlight_t		*l;
 	int				i, j, k;
-	fog_t			*fog;
+	fog_t			*fog = NULL;
 
 	if ( !r_flares->integer ) {
 		return;
 	}
 
 	l = backEnd.refdef.dlights;
-	fog = tr.world->fogs;
+
+	if(tr.world)
+		fog = tr.world->fogs;
+
 	for (i=0 ; i<backEnd.refdef.num_dlights ; i++, l++) {
 
-		// find which fog volume the light is in 
-		for ( j = 1 ; j < tr.world->numfogs ; j++ ) {
-			fog = &tr.world->fogs[j];
-			for ( k = 0 ; k < 3 ; k++ ) {
-				if ( l->origin[k] < fog->bounds[0][k] || l->origin[k] > fog->bounds[1][k] ) {
+		if(fog)
+		{
+			// find which fog volume the light is in 
+			for ( j = 1 ; j < tr.world->numfogs ; j++ ) {
+				fog = &tr.world->fogs[j];
+				for ( k = 0 ; k < 3 ; k++ ) {
+					if ( l->origin[k] < fog->bounds[0][k] || l->origin[k] > fog->bounds[1][k] ) {
+						break;
+					}
+				}
+				if ( k == 3 ) {
 					break;
 				}
 			}
-			if ( k == 3 ) {
-				break;
+			if ( j == tr.world->numfogs ) {
+				j = 0;
 			}
 		}
-		if ( j == tr.world->numfogs ) {
+		else
 			j = 0;
-		}
 
 		RB_AddFlare( (void *)l, j, l->origin, l->color, NULL );
 	}
@@ -294,16 +312,61 @@
 	float			size;
 	vec3_t			color;
 	int				iColor[3];
+	float distance, intensity, factor;
+	byte fogFactors[3] = {255, 255, 255};
 
 	backEnd.pc.c_flareRenders++;
 
-	VectorScale( f->color, f->drawIntensity*tr.identityLight, color );
-	iColor[0] = color[0] * 255;
-	iColor[1] = color[1] * 255;
-	iColor[2] = color[2] * 255;
+	// We don't want too big values anyways when dividing by distance.
+	if(f->eyeZ > -1.0f)
+		distance = 1.0f;
+	else
+		distance = -f->eyeZ;
 
-	size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / -f->eyeZ );
+	// calculate the flare size..
+	size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / distance );
 
+/*
+ * This is an alternative to intensity scaling. It changes the size of the flare on screen instead
+ * with growing distance. See in the description at the top why this is not the way to go.
+	// size will change ~ 1/r.
+	size = backEnd.viewParms.viewportWidth * (r_flareSize->value / (distance * -2.0f));
+*/
+
+/*
+ * As flare sizes stay nearly constant with increasing distance we must decrease the intensity
+ * to achieve a reasonable visual result. The intensity is ~ (size^2 / distance^2) which can be
+ * got by considering the ratio of
+ * (flaresurface on screen) : (Surface of sphere defined by flare origin and distance from flare)
+ * An important requirement is:
+ * intensity <= 1 for all distances.
+ *
+ * The formula used here to compute the intensity is as follows:
+ * intensity = flareCoeff * size^2 / (distance + size*sqrt(flareCoeff))^2
+ * As you can see, the intensity will have a max. of 1 when the distance is 0.
+ * The coefficient flareCoeff will determine the falloff speed with increasing distance.
+ */
+
+	factor = distance + size * sqrt(flareCoeff);
+	
+	intensity = flareCoeff * size * size / (factor * factor);
+
+	VectorScale(f->color, f->drawIntensity * tr.identityLight * intensity, color);
+
+// Calculations for fogging
+	if(f->fogNum)
+	{
+		tess.numVertexes = 1;
+		VectorCopy(f->origin, tess.xyz[0]);
+		tess.fogNum = f->fogNum;
+	
+		RB_CalcModulateColorsByFog(fogFactors);
+	}
+
+	iColor[0] = color[0] * fogFactors[0];
+	iColor[1] = color[1] * fogFactors[1];
+	iColor[2] = color[2] * fogFactors[2];
+	
 	RB_BeginSurface( tr.flareShader, f->fogNum );
 
 	// FIXME: use quadstamp?
@@ -382,6 +445,21 @@
 		return;
 	}
 
+	if(r_flareCoeff->modified)
+	{
+		if(r_flareCoeff->value == 0.0f)
+			flareCoeff = atof(FLARE_STDCOEFF);
+		else
+			flareCoeff = r_flareCoeff->value;
+			
+		r_flareCoeff->modified = qfalse;
+	}
+
+	// Reset currentEntity to world so that any previously referenced entities
+	// don't have influence on the rendering of these flares (i.e. RF_ renderer flags).
+	backEnd.currentEntity = &tr.worldEntity;
+	backEnd.or = backEnd.viewParms.world;
+
 //	RB_AddDlightFlares();
 
 	// perform z buffer readback on each flare in this view

Modified: trunk/code/renderer/tr_init.c
===================================================================
--- trunk/code/renderer/tr_init.c	2006-04-19 23:01:48 UTC (rev 711)
+++ trunk/code/renderer/tr_init.c	2006-04-20 04:43:43 UTC (rev 712)
@@ -30,6 +30,7 @@
 
 cvar_t	*r_flareSize;
 cvar_t	*r_flareFade;
+cvar_t	*r_flareCoeff;
 
 cvar_t	*r_railWidth;
 cvar_t	*r_railCoreWidth;
@@ -997,6 +998,7 @@
 
 	r_flareSize = ri.Cvar_Get ("r_flareSize", "40", CVAR_CHEAT);
 	r_flareFade = ri.Cvar_Get ("r_flareFade", "7", CVAR_CHEAT);
+	r_flareCoeff = ri.Cvar_Get ("r_flareCoeff", FLARE_STDCOEFF, CVAR_CHEAT);
 
 	r_showSmp = ri.Cvar_Get ("r_showSmp", "0", CVAR_CHEAT);
 	r_skipBackEnd = ri.Cvar_Get ("r_skipBackEnd", "0", CVAR_CHEAT);

Modified: trunk/code/renderer/tr_local.h
===================================================================
--- trunk/code/renderer/tr_local.h	2006-04-19 23:01:48 UTC (rev 711)
+++ trunk/code/renderer/tr_local.h	2006-04-20 04:43:43 UTC (rev 712)
@@ -976,6 +976,9 @@
 //
 extern cvar_t	*r_flareSize;
 extern cvar_t	*r_flareFade;
+// coefficient for the flare intensity falloff function.
+#define FLARE_STDCOEFF "150"
+extern cvar_t	*r_flareCoeff;
 
 extern cvar_t	*r_railWidth;
 extern cvar_t	*r_railCoreWidth;

Modified: trunk/code/renderer/tr_shader.c
===================================================================
--- trunk/code/renderer/tr_shader.c	2006-04-19 23:01:48 UTC (rev 711)
+++ trunk/code/renderer/tr_shader.c	2006-04-20 04:43:43 UTC (rev 712)
@@ -3010,6 +3010,17 @@
 static void CreateExternalShaders( void ) {
 	tr.projectionShadowShader = R_FindShader( "projectionShadow", LIGHTMAP_NONE, qtrue );
 	tr.flareShader = R_FindShader( "flareShader", LIGHTMAP_NONE, qtrue );
+
+	// Hack to make fogging work correctly on flares. Fog colors are calculated
+	// in tr_flare.c already.
+	if(!tr.flareShader->defaultShader)
+	{
+		int index;
+		
+		for(index = 0; index < tr.flareShader->numUnfoggedPasses; index++)
+			tr.flareShader->stages[index]->adjustColorsForFog = ACFF_NONE;
+	}
+
 	tr.sunShader = R_FindShader( "sun", LIGHTMAP_NONE, qtrue );
 }
 

Modified: trunk/code/renderer/tr_surface.c
===================================================================
--- trunk/code/renderer/tr_surface.c	2006-04-19 23:01:48 UTC (rev 711)
+++ trunk/code/renderer/tr_surface.c	2006-04-20 04:43:43 UTC (rev 712)
@@ -1214,71 +1214,12 @@
 	ri.Printf( PRINT_ALL, "Bad surface tesselated.\n" );
 }
 
-#if 0
-
-void RB_SurfaceFlare( srfFlare_t *surf ) {
-	vec3_t		left, up;
-	float		radius;
-	byte		color[4];
-	vec3_t		dir;
-	vec3_t		origin;
-	float		d;
-
-	// calculate the xyz locations for the four corners
-	radius = 30;
-	VectorScale( backEnd.viewParms.or.axis[1], radius, left );
-	VectorScale( backEnd.viewParms.or.axis[2], radius, up );
-	if ( backEnd.viewParms.isMirror ) {
-		VectorSubtract( vec3_origin, left, left );
-	}
-
-	color[0] = color[1] = color[2] = color[3] = 255;
-
-	VectorMA( surf->origin, 3, surf->normal, origin );
-	VectorSubtract( origin, backEnd.viewParms.or.origin, dir );
-	VectorNormalize( dir );
-	VectorMA( origin, r_ignore->value, dir, origin );
-
-	d = -DotProduct( dir, surf->normal );
-	if ( d < 0 ) {
-		return;
-	}
-#if 0
-	color[0] *= d;
-	color[1] *= d;
-	color[2] *= d;
-#endif
-
-	RB_AddQuadStamp( origin, left, up, color );
+void RB_SurfaceFlare(srfFlare_t *surf)
+{
+	if (r_flares->integer)
+		RB_AddFlare(surf, tess.fogNum, surf->origin, surf->color, surf->normal);
 }
 
-#else
-
-void RB_SurfaceFlare( srfFlare_t *surf ) {
-#if 0
-	vec3_t		left, up;
-	byte		color[4];
-
-	color[0] = surf->color[0] * 255;
-	color[1] = surf->color[1] * 255;
-	color[2] = surf->color[2] * 255;
-	color[3] = 255;
-
-	VectorClear( left );
-	VectorClear( up );
-
-	left[0] = r_ignore->value;
-
-	up[1] = r_ignore->value;
-	
-	RB_AddQuadStampExt( surf->origin, left, up, color, 0, 0, 1, 1 );
-#endif
-}
-
-#endif
-
-
-
 void RB_SurfaceDisplayList( srfDisplayList_t *surf ) {
 	// all apropriate state must be set in RB_BeginSurface
 	// this isn't implemented yet...




More information about the quake3-commits mailing list