//----------------------------------------------------------------------------- // 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]; SSE_sampleLightOutput_t out; FourVectors origin4; FourVectors normal4; origin4.DuplicateVector( origin ); normal4.DuplicateVector( normal ); GatherSampleLightSSE ( out, dl, -1, origin4, &normal4, 1, iThread ); VectorMA( maxcolor[dl->light.style], out.m_flFalloff.m128_f32[0] * out.m_flDot[0].m128_f32[0], dl->light.intensity, maxcolor[dl->light.style] ); } }