diff --git a/src/lightmap/lightmap.cpp b/src/lightmap/lightmap.cpp index 4c00982..4d4f3f5 100644 --- a/src/lightmap/lightmap.cpp +++ b/src/lightmap/lightmap.cpp @@ -42,6 +42,8 @@ #include #include +extern int Multisample; + const kexVec3 kexLightmapBuilder::gridSize(64, 64, 128); // @@ -474,19 +476,38 @@ void kexLightmapBuilder::TraceSurface(surface_t *surface) normal = surface->plane.Normal(); + int multisampleCount = Multisample; + // start walking through each texel for(i = 0; i < sampleHeight; i++) { for(j = 0; j < sampleWidth; j++) { - // convert the texel into world-space coordinates. - // this will be the origin in which a line will be traced from - pos = surface->lightmapOrigin + normal + - (surface->lightmapSteps[0] * (float)j) + - (surface->lightmapSteps[1] * (float)i); + kexVec3 c(0.0f, 0.0f, 0.0f); - kexVec3 c = LightTexelSample(trace, pos, surface); - kexMath::Clamp(c, 0, 1); + for (int k = 0; k < multisampleCount; k++) + { + kexVec2 multisamplePos((float)j, (float)i); + if (k > 0) + { + multisamplePos.x += rand() / (float)RAND_MAX - 0.5f; + multisamplePos.y += rand() / (float)RAND_MAX - 0.5f; + multisamplePos.x = max(multisamplePos.x, 0.0f); + multisamplePos.y = max(multisamplePos.y, 0.0f); + multisamplePos.x = min(multisamplePos.x, (float)sampleWidth); + multisamplePos.y = min(multisamplePos.y, (float)sampleHeight); + } + + // convert the texel into world-space coordinates. + // this will be the origin in which a line will be traced from + pos = surface->lightmapOrigin + normal + + (surface->lightmapSteps[0] * multisamplePos.x) + + (surface->lightmapSteps[1] * multisamplePos.y); + + c += LightTexelSample(trace, pos, surface); + } + + c /= multisampleCount; // if nothing at all was traced and color is completely black // then this surface will not go through the extra rendering @@ -496,6 +517,7 @@ void kexLightmapBuilder::TraceSurface(surface_t *surface) bShouldLookupTexture = true; } + kexMath::Clamp(c, 0, 1); colorSamples[i * 1024 + j] = c; } } diff --git a/src/main.cpp b/src/main.cpp index f4a9bf1..3d26ed5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -117,6 +117,7 @@ int SSELevel; int NumThreads = 0; int LMDims = LIGHTMAP_MAX_SIZE; int Samples = 8; +int Multisample = 1; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -155,6 +156,7 @@ static option long_opts[] = {"threads", required_argument, 0, 'j'}, {"samples", required_argument, 0, 'Q'}, {"size", required_argument, 0, 'S'}, + {"multisample", required_argument, 0, 'M'}, {0,0,0,0} }; @@ -448,6 +450,11 @@ static void ParseArgs(int argc, char **argv) if (LMDims > LIGHTMAP_MAX_SIZE) LMDims = LIGHTMAP_MAX_SIZE; LMDims = kexMath::RoundPowerOfTwo(LMDims); break; + case 'M': + Multisample = atoi(optarg); + if (Multisample <= 0) Multisample = 1; + if (Multisample > 64) Multisample = 64; + break; case 1000: ShowUsage(); exit(0); @@ -493,6 +500,7 @@ static void ShowUsage() " slow compile time) must be in powers of two\n" " -S, --size=NNN lightmap texture dimensions for width and height\n" " must be in powers of two (1, 2, 4, 8, 16, etc)\n" + " -M, --multisample=NNN Number of samples to use per texel (default %d)\n" #ifdef _WIN32 " -v, --view View the nodes\n" #endif @@ -509,6 +517,7 @@ static void ShowUsage() , SplitCost , AAPreference , (int)std::thread::hardware_concurrency() + , Multisample ); }