void ComputePerLeafAmbientLighting() { // Figure out which lights should go in the per-leaf ambient cubes. int nInAmbientCube = 0; int nSurfaceLights = 0; for ( int i=0; i < *pNumworldlights; i++ ) { dworldlight_t *wl = &dworldlights[i]; if ( IsLeafAmbientSurfaceLight( wl ) ) wl->flags |= DWL_FLAGS_INAMBIENTCUBE; else wl->flags &= ~DWL_FLAGS_INAMBIENTCUBE; if ( wl->type == emit_surface ) ++nSurfaceLights; if ( wl->flags & DWL_FLAGS_INAMBIENTCUBE ) ++nInAmbientCube; } Msg( "%d of %d (%d%% of) surface lights went in leaf ambient cubes.\n", nInAmbientCube, nSurfaceLights, nSurfaceLights ? ((nInAmbientCube*100) / nSurfaceLights) : 0 ); g_pLeafAmbientLighting->SetCount( numleafs ); StartPacifier( "ComputePerLeafAmbientLighting: " ); for ( int leafID = 0; leafID < numleafs; leafID++ ) { dleaf_t *pLeaf = &dleafs[leafID]; Vector cube[6]; Vector center = ( Vector( pLeaf->mins[0], pLeaf->mins[1], pLeaf->mins[2] ) + Vector( pLeaf->maxs[0], pLeaf->maxs[1], pLeaf->maxs[2] ) ) * 0.5f; #if MAKE_LIGHT_BELOW_WATER_MATCH_LIGHT_ABOVE_WATER if (pLeaf->contents & CONTENTS_WATER) { center.z=pLeaf->maxs[2]+1; int above_leaf=PointLeafnum( center); dleaf_t *pLeaf = &dleafs[above_leaf]; center = ( Vector( pLeaf->mins[0], pLeaf->mins[1], pLeaf->mins[2] ) + Vector( pLeaf->maxs[0], pLeaf->maxs[1], pLeaf->maxs[2] ) ) * 0.5f; } #endif ComputeAmbientFromSphericalSamples( center, cube ); for ( int i = 0; i < 6; i++ ) { VectorToColorRGBExp32( cube[i], (*g_pLeafAmbientLighting)[leafID].m_Color[i] ); } UpdatePacifier( (float)leafID / numleafs ); } EndPacifier( true ); }
void ComputePerLeafAmbientLighting() { // Figure out which lights should go in the per-leaf ambient cubes. int nInAmbientCube = 0; int nSurfaceLights = 0; for ( int i=0; i < *pNumworldlights; i++ ) { dworldlight_t *wl = &dworldlights[i]; if ( IsLeafAmbientSurfaceLight( wl ) ) wl->flags |= DWL_FLAGS_INAMBIENTCUBE; else wl->flags &= ~DWL_FLAGS_INAMBIENTCUBE; if ( wl->type == emit_surface ) ++nSurfaceLights; if ( wl->flags & DWL_FLAGS_INAMBIENTCUBE ) ++nInAmbientCube; } Msg( "%d of %d (%d%% of) surface lights went in leaf ambient cubes.\n", nInAmbientCube, nSurfaceLights, nSurfaceLights ? ((nInAmbientCube*100) / nSurfaceLights) : 0 ); g_LeafAmbientSamples.SetCount(numleafs); if ( g_bUseMPI ) { // Distribute the work among the workers. VMPI_SetCurrentStage( "ComputeLeafAmbientLighting" ); DistributeWork( numleafs, VMPI_DISTRIBUTEWORK_PACKETID, VMPI_ProcessLeafAmbient, VMPI_ReceiveLeafAmbientResults ); } else { RunThreadsOn(numleafs, true, ThreadComputeLeafAmbient); } // now write out the data Msg("Writing leaf ambient..."); g_pLeafAmbientIndex->RemoveAll(); g_pLeafAmbientLighting->RemoveAll(); g_pLeafAmbientIndex->SetCount( numleafs ); g_pLeafAmbientLighting->EnsureCapacity( numleafs*4 ); for ( int leafID = 0; leafID < numleafs; leafID++ ) { const CUtlVector<ambientsample_t> &list = g_LeafAmbientSamples[leafID]; g_pLeafAmbientIndex->Element(leafID).ambientSampleCount = list.Count(); if ( !list.Count() ) { g_pLeafAmbientIndex->Element(leafID).firstAmbientSample = 0; } else { g_pLeafAmbientIndex->Element(leafID).firstAmbientSample = g_pLeafAmbientLighting->Count(); // compute the samples in disk format. Encode the positions in 8-bits using leaf bounds fractions for ( int i = 0; i < list.Count(); i++ ) { int outIndex = g_pLeafAmbientLighting->AddToTail(); dleafambientlighting_t &light = g_pLeafAmbientLighting->Element(outIndex); light.x = Fixed8Fraction( list[i].pos.x, dleafs[leafID].mins[0], dleafs[leafID].maxs[0] ); light.y = Fixed8Fraction( list[i].pos.y, dleafs[leafID].mins[1], dleafs[leafID].maxs[1] ); light.z = Fixed8Fraction( list[i].pos.z, dleafs[leafID].mins[2], dleafs[leafID].maxs[2] ); light.pad = 0; for ( int side = 0; side < 6; side++ ) { VectorToColorRGBExp32( list[i].cube[side], light.cube.m_Color[side] ); } } } } for ( int i = 0; i < numleafs; i++ ) { // UNDONE: Do this dynamically in the engine instead. This will allow us to sample across leaf // boundaries always which should improve the quality of lighting in general if ( g_pLeafAmbientIndex->Element(i).ambientSampleCount == 0 ) { if ( !(dleafs[i].contents & CONTENTS_SOLID) ) { Msg("Bad leaf ambient for leaf %d\n", i ); } int refLeaf = NearestNeighborWithLight(i); g_pLeafAmbientIndex->Element(i).ambientSampleCount = 0; g_pLeafAmbientIndex->Element(i).firstAmbientSample = refLeaf; } } Msg("done\n"); }