Exemple #1
0
//-----------------------------------------------------------------------------
// Trace from a vertex to each direct light source, accumulating its contribution.
//-----------------------------------------------------------------------------
void ComputeDirectLightingAtPoint( Vector &position, Vector &normal, Vector &outColor, int iThread,
								   int static_prop_id_to_skip=-1)
{
	sampleLightOutput_t	sampleOutput;

	outColor.Init();

	// Iterate over all direct lights and accumulate their contribution
	int cluster = ClusterFromPoint( position );
	for ( directlight_t *dl = activelights; dl != NULL; dl = dl->next )
	{
		if ( dl->light.style )
		{
			// skip lights with style
			continue;
		}

		// is this lights cluster visible?
		if ( !PVSCheck( dl->pvs, cluster ) )
			continue;

		// push the vertex towards the light to avoid surface acne
		Vector adjusted_pos = position;
		Vector fudge=dl->light.origin-position;
		VectorNormalize( fudge );
		fudge *= 1.0;
		adjusted_pos += fudge;

		if ( !GatherSampleLight(
				 sampleOutput, dl, -1, adjusted_pos, &normal, 1, iThread, true,
				 static_prop_id_to_skip ) )
			continue;
		
		VectorMA( outColor, sampleOutput.falloff * sampleOutput.dot[0], dl->light.intensity, outColor );
	}
}
//-----------------------------------------------------------------------------
// Computes max direct lighting for a single detal prop
//-----------------------------------------------------------------------------
static void ComputeMaxDirectLighting( DetailObjectLump_t& prop, Vector* maxcolor, int iThread )
{
	// The max direct lighting must be along the direction to one
	// of the static lights....

	Vector origin, normal;
	ComputeWorldCenter( prop, origin, normal );

	if ( !origin.IsValid() || !normal.IsValid() )
	{
		static bool s_Warned = false;
		if ( !s_Warned )
		{
			Warning("WARNING: Bogus detail props encountered!\n" );
			s_Warned = true;
		}

		// fill with debug color
		for ( int i = 0; i < MAX_LIGHTSTYLES; ++i)
		{
			maxcolor[i].Init(1,0,0);
		}
		return;
	}

	int cluster = ClusterFromPoint(origin);

	Vector delta;
	CUtlVector< directlight_t* >	lights;
	CUtlVector< Vector >			directions;

	directlight_t* dl;
	for (dl = activelights; dl != 0; dl = dl->next)
	{
		// skyambient doesn't affect dlights..
		if (dl->light.type == emit_skyambient)
			continue;

		// is this lights cluster visible?
		if ( PVSCheck( dl->pvs, cluster ) )
		{
			lights.AddToTail(dl);
			VectorSubtract( dl->light.origin, origin, delta );
			VectorNormalize( delta );
			directions.AddToTail( delta );
		}
	}

	// Find the max illumination
	int i;
	for ( i = 0; i < MAX_LIGHTSTYLES; ++i)
	{
		maxcolor[i].Init(0,0,0);
	}

	// NOTE: See version 10 for a method where we choose a normal based on whichever
	// one produces the maximum possible illumination. This appeared to work better on
	// e3_town, so I'm trying it now; hopefully it'll be good for all cases.
	int j;
	for ( j = 0; j < lights.Count(); ++j)
	{
		dl = lights[j];

		sampleLightOutput_t out;
		if ( GatherSampleLight( out, dl, -1, origin, &normal, 1, iThread ) )
		{
			// The first sample is for non-bumped lighting.
			// The other sample are for bumpmapping.
			VectorMA( maxcolor[dl->light.style], out.falloff * out.dot[0], dl->light.intensity, maxcolor[dl->light.style] );
		}
	}
}
Exemple #3
0
/**
 * @brief
 * @sa FinalLightFace
 */
void BuildFacelights (unsigned int facenum)
{
	dBspSurface_t* face;
	dBspPlane_t* plane;
	dBspTexinfo_t* tex;
	float* center;
	float* sdir, *tdir;
	vec3_t normal, binormal;
	vec4_t tangent;
	lightinfo_t li;
	float scale;
	int i, j, numsamples;
	facelight_t* fl;
	int* headhints;
	const int grid_type = config.soft ? 1 : 0;

	if (facenum >= MAX_MAP_FACES) {
		Com_Printf("MAX_MAP_FACES hit\n");
		return;
	}

	face = &curTile->faces[facenum];
	plane = &curTile->planes[face->planenum];
	tex = &curTile->texinfo[face->texinfo];

	if (tex->surfaceFlags & SURF_WARP)
		return;		/* non-lit texture */

	sdir = tex->vecs[0];
	tdir = tex->vecs[1];

	/* lighting -extra antialiasing */
	if (config.extrasamples)
		numsamples = config.soft ? SOFT_SAMPLES : MAX_SAMPLES;
	else
		numsamples = 1;

	OBJZERO(li);

	scale = 1.0 / numsamples; /* each sample contributes this much */

	li.face = face;
	li.facedist = plane->dist;
	VectorCopy(plane->normal, li.facenormal);
	/* negate the normal and dist */
	if (face->side) {
		VectorNegate(li.facenormal, li.facenormal);
		li.facedist = -li.facedist;
	}

	/* get the origin offset for rotating bmodels */
	VectorCopy(face_offset[facenum], li.modelorg);

	/* calculate lightmap texture mins and maxs */
	CalcLightinfoExtents(&li);

	/* and the lightmap texture vectors */
	CalcLightinfoVectors(&li);

	/* now generate all of the sample points */
	CalcPoints(&li, 0, 0);

	fl = &facelight[config.compile_for_day][facenum];
	fl->numsamples = li.numsurfpt;
	fl->samples    = Mem_AllocTypeN(vec3_t, fl->numsamples);
	fl->directions = Mem_AllocTypeN(vec3_t, fl->numsamples);

	center = face_extents[facenum].center;  /* center of the face */

	/* Also setup the hints.  Each hint is specific to each light source, including sunlight. */
	headhints = Mem_AllocTypeN(int, (numlights[config.compile_for_day] + 1));

	/* calculate light for each sample */
	for (i = 0; i < fl->numsamples; i++) {
		float* const sample    = fl->samples[i];    /* accumulate lighting here */
		float* const direction = fl->directions[i]; /* accumulate direction here */

		if (tex->surfaceFlags & SURF_PHONG)
			/* interpolated normal */
			SampleNormal(&li, li.surfpt[i], normal);
		else
			/* or just plane normal */
			VectorCopy(li.facenormal, normal);

		for (j = 0; j < numsamples; j++) {  /* with antialiasing */
			vec3_t pos;

			/* add offset for supersampling */
			VectorMA(li.surfpt[i], sampleofs[grid_type][j][0] * li.step, li.textoworld[0], pos);
			VectorMA(pos, sampleofs[grid_type][j][1] * li.step, li.textoworld[1], pos);

			NudgeSamplePosition(pos, normal, center, pos);

			GatherSampleLight(pos, normal, sample, direction, scale, headhints);
		}
		if (VectorNotEmpty(direction)) {
			vec3_t dir;

			/* normalize it */
			VectorNormalize(direction);

			/* finalize the lighting direction for the sample */
			TangentVectors(normal, sdir, tdir, tangent, binormal);

			dir[0] = DotProduct(direction, tangent);
			dir[1] = DotProduct(direction, binormal);
			dir[2] = DotProduct(direction, normal);

			VectorCopy(dir, direction);
		}
	}

	/* Free the hints. */
	Mem_Free(headhints);

	for (i = 0; i < fl->numsamples; i++) {  /* pad them */
		float* const direction = fl->directions[i];
		if (VectorEmpty(direction))
			VectorSet(direction, 0.0, 0.0, 1.0);
	}

	/* free the sample positions for the face */
	Mem_Free(li.surfpt);
}