mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-02-03 13:11:04 +00:00
- make indirect light bounces optional (--bounce=1 to enable)
This commit is contained in:
parent
4dd0edbd3a
commit
78a3da5b8c
5 changed files with 123 additions and 101 deletions
|
@ -44,7 +44,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int Multisample;
|
extern int Multisample;
|
||||||
extern thread_local Vec3 *colorSamples;
|
extern int LightBounce;
|
||||||
|
|
||||||
LightmapBuilder::LightmapBuilder()
|
LightmapBuilder::LightmapBuilder()
|
||||||
{
|
{
|
||||||
|
@ -59,7 +59,7 @@ void LightmapBuilder::NewTexture()
|
||||||
numTextures++;
|
numTextures++;
|
||||||
|
|
||||||
allocBlocks.push_back(std::vector<int>(textureWidth));
|
allocBlocks.push_back(std::vector<int>(textureWidth));
|
||||||
textures.push_back(std::vector<uint16_t>(textureWidth * textureHeight * 3));
|
textures.push_back(std::make_unique<LightmapTexture>(textureWidth, textureHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines where to map a new block on to the lightmap texture
|
// Determines where to map a new block on to the lightmap texture
|
||||||
|
@ -398,30 +398,22 @@ void LightmapBuilder::BuildSurfaceParams(Surface *surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Steps through each texel and traces a line to the world.
|
// Steps through each texel and traces a line to the world.
|
||||||
// For each non-occluded trace, color is accumulated and saved off into the lightmap texture based on what block is mapped to
|
|
||||||
void LightmapBuilder::TraceSurface(Surface *surface)
|
void LightmapBuilder::TraceSurface(Surface *surface)
|
||||||
{
|
{
|
||||||
int sampleWidth;
|
int sampleWidth = surface->lightmapDims[0];
|
||||||
int sampleHeight;
|
int sampleHeight = surface->lightmapDims[1];
|
||||||
Vec3 normal;
|
|
||||||
Vec3 pos;
|
|
||||||
Vec3 tDelta;
|
|
||||||
int i;
|
|
||||||
int j;
|
|
||||||
uint16_t *currentTexture;
|
|
||||||
bool bShouldLookupTexture = false;
|
|
||||||
|
|
||||||
sampleWidth = surface->lightmapDims[0];
|
Vec3 normal = surface->plane.Normal();
|
||||||
sampleHeight = surface->lightmapDims[1];
|
|
||||||
|
|
||||||
normal = surface->plane.Normal();
|
|
||||||
|
|
||||||
int multisampleCount = Multisample;
|
int multisampleCount = Multisample;
|
||||||
|
|
||||||
|
surface->samples.resize(sampleWidth * sampleHeight);
|
||||||
|
Vec3 *colorSamples = surface->samples.data();
|
||||||
|
|
||||||
// start walking through each texel
|
// start walking through each texel
|
||||||
for (i = 0; i < sampleHeight; i++)
|
for (int i = 0; i < sampleHeight; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < sampleWidth; j++)
|
for (int j = 0; j < sampleWidth; j++)
|
||||||
{
|
{
|
||||||
Vec3 c(0.0f, 0.0f, 0.0f);
|
Vec3 c(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
@ -440,35 +432,65 @@ void LightmapBuilder::TraceSurface(Surface *surface)
|
||||||
|
|
||||||
// convert the texel into world-space coordinates.
|
// convert the texel into world-space coordinates.
|
||||||
// this will be the origin in which a line will be traced from
|
// this will be the origin in which a line will be traced from
|
||||||
pos = surface->lightmapOrigin + normal +
|
Vec3 pos = surface->lightmapOrigin + normal + (surface->lightmapSteps[0] * multisamplePos.x) + (surface->lightmapSteps[1] * multisamplePos.y);
|
||||||
(surface->lightmapSteps[0] * multisamplePos.x) +
|
|
||||||
(surface->lightmapSteps[1] * multisamplePos.y);
|
|
||||||
|
|
||||||
c += LightTexelSample(pos, surface);
|
c += LightTexelSample(pos, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
c /= multisampleCount;
|
c /= multisampleCount;
|
||||||
|
|
||||||
// if nothing at all was traced and color is completely black
|
colorSamples[i * sampleWidth + j] = c;
|
||||||
// then this surface will not go through the extra rendering
|
}
|
||||||
// step in rendering the lightmap
|
}
|
||||||
if (c.x > 0.0f || c.y > 0.0f || c.z > 0.0f)
|
|
||||||
{
|
|
||||||
bShouldLookupTexture = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
colorSamples[i * LIGHTMAP_MAX_SIZE + j] = c;
|
// texture coordinates relative to block
|
||||||
|
for (int i = 0; i < surface->numVerts; i++)
|
||||||
|
{
|
||||||
|
Vec3 tDelta = surface->verts[i] - surface->bounds.min;
|
||||||
|
surface->lightmapCoords[i * 2 + 0] = tDelta.Dot(surface->textureCoords[0]);
|
||||||
|
surface->lightmapCoords[i * 2 + 1] = tDelta.Dot(surface->textureCoords[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LightmapBuilder::FinishSurface(Surface *surface)
|
||||||
|
{
|
||||||
|
int sampleWidth = surface->lightmapDims[0];
|
||||||
|
int sampleHeight = surface->lightmapDims[1];
|
||||||
|
Vec3 *colorSamples = surface->samples.data();
|
||||||
|
|
||||||
|
if (!surface->indirect.empty())
|
||||||
|
{
|
||||||
|
Vec3 *indirect = surface->indirect.data();
|
||||||
|
for (int i = 0; i < sampleHeight; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < sampleWidth; j++)
|
||||||
|
{
|
||||||
|
colorSamples[i * sampleWidth + j] += indirect[i * sampleWidth + j] * 0.5f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SVE redraws the scene for lightmaps, so for optimizations,
|
// SVE redraws the scene for lightmaps, so for optimizations,
|
||||||
// tell the engine to ignore this surface if completely black
|
// tell the engine to ignore this surface if completely black
|
||||||
/*if (bShouldLookupTexture == false)
|
bool bShouldLookupTexture = false;
|
||||||
|
for (int i = 0; i < sampleHeight; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < sampleWidth; j++)
|
||||||
|
{
|
||||||
|
const auto &c = colorSamples[i * sampleWidth + j];
|
||||||
|
if (c.x > 0.0f || c.y > 0.0f || c.z > 0.0f)
|
||||||
|
{
|
||||||
|
bShouldLookupTexture = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bShouldLookupTexture == false)
|
||||||
{
|
{
|
||||||
surface->lightmapNum = -1;
|
surface->lightmapNum = -1;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else*/
|
else
|
||||||
{
|
{
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
int width = surface->lightmapDims[0];
|
int width = surface->lightmapDims[0];
|
||||||
|
@ -490,38 +512,34 @@ void LightmapBuilder::TraceSurface(Surface *surface)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t *currentTexture = textures[surface->lightmapNum]->Pixels();
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
// calculate texture coordinates
|
// calculate texture coordinates
|
||||||
for (i = 0; i < surface->numVerts; i++)
|
for (int i = 0; i < surface->numVerts; i++)
|
||||||
{
|
{
|
||||||
tDelta = surface->verts[i] - surface->bounds.min;
|
Vec3 tDelta = surface->verts[i] - surface->bounds.min;
|
||||||
surface->lightmapCoords[i * 2 + 0] =
|
surface->lightmapCoords[i * 2 + 0] = (tDelta.Dot(surface->textureCoords[0]) + x + 0.5f) / (float)textureWidth;
|
||||||
(tDelta.Dot(surface->textureCoords[0]) + x + 0.5f) / (float)textureWidth;
|
surface->lightmapCoords[i * 2 + 1] = (tDelta.Dot(surface->textureCoords[1]) + y + 0.5f) / (float)textureHeight;
|
||||||
surface->lightmapCoords[i * 2 + 1] =
|
|
||||||
(tDelta.Dot(surface->textureCoords[1]) + y + 0.5f) / (float)textureHeight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->lightmapOffs[0] = x;
|
surface->lightmapOffs[0] = x;
|
||||||
surface->lightmapOffs[1] = y;
|
surface->lightmapOffs[1] = y;
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lock(mutex);
|
// store results to lightmap texture
|
||||||
currentTexture = textures[surface->lightmapNum].data();
|
for (int i = 0; i < sampleHeight; i++)
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
// store results to lightmap texture
|
|
||||||
for (i = 0; i < sampleHeight; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < sampleWidth; j++)
|
|
||||||
{
|
{
|
||||||
// get texture offset
|
for (int j = 0; j < sampleWidth; j++)
|
||||||
int offs = (((textureWidth * (i + surface->lightmapOffs[1])) + surface->lightmapOffs[0]) * 3);
|
{
|
||||||
|
// get texture offset
|
||||||
|
int offs = (((textureWidth * (i + surface->lightmapOffs[1])) + surface->lightmapOffs[0]) * 3);
|
||||||
|
|
||||||
// convert RGB to bytes
|
// convert RGB to bytes
|
||||||
currentTexture[offs + j * 3 + 0] = floatToHalf(colorSamples[i * LIGHTMAP_MAX_SIZE + j].x);
|
currentTexture[offs + j * 3 + 0] = floatToHalf(colorSamples[i * sampleWidth + j].x);
|
||||||
currentTexture[offs + j * 3 + 1] = floatToHalf(colorSamples[i * LIGHTMAP_MAX_SIZE + j].y);
|
currentTexture[offs + j * 3 + 1] = floatToHalf(colorSamples[i * sampleWidth + j].y);
|
||||||
currentTexture[offs + j * 3 + 2] = floatToHalf(colorSamples[i * LIGHTMAP_MAX_SIZE + j].z);
|
currentTexture[offs + j * 3 + 2] = floatToHalf(colorSamples[i * sampleWidth + j].z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,15 +581,13 @@ static Vec3 ImportanceSampleGGX(Vec2 Xi, Vec3 N, float roughness)
|
||||||
|
|
||||||
void LightmapBuilder::TraceIndirectLight(Surface *surface)
|
void LightmapBuilder::TraceIndirectLight(Surface *surface)
|
||||||
{
|
{
|
||||||
if (surface->lightmapNum == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int sampleWidth = surface->lightmapDims[0];
|
int sampleWidth = surface->lightmapDims[0];
|
||||||
int sampleHeight = surface->lightmapDims[1];
|
int sampleHeight = surface->lightmapDims[1];
|
||||||
|
|
||||||
Vec3 normal = surface->plane.Normal();
|
Vec3 normal = surface->plane.Normal();
|
||||||
|
|
||||||
uint16_t *currentTexture = &indirectoutput[surface->lightmapNum * textureWidth * textureHeight * 3];
|
surface->indirect.resize(sampleWidth * sampleHeight);
|
||||||
|
Vec3 *indirect = surface->indirect.data();
|
||||||
|
|
||||||
for (int i = 0; i < sampleHeight; i++)
|
for (int i = 0; i < sampleHeight; i++)
|
||||||
{
|
{
|
||||||
|
@ -616,16 +632,14 @@ void LightmapBuilder::TraceIndirectLight(Surface *surface)
|
||||||
hit.hitSurface->lightmapCoords[hit.indices[1] * 2 + 1] * hit.b +
|
hit.hitSurface->lightmapCoords[hit.indices[1] * 2 + 1] * hit.b +
|
||||||
hit.hitSurface->lightmapCoords[hit.indices[2] * 2 + 1] * hit.c;
|
hit.hitSurface->lightmapCoords[hit.indices[2] * 2 + 1] * hit.c;
|
||||||
|
|
||||||
int hitTexelX = clamp((int)(u * textureWidth + 0.5f), 0, textureWidth - 1);
|
int hitTexelX = clamp((int)(u + 0.5f), 0, hit.hitSurface->lightmapDims[0] - 1);
|
||||||
int hitTexelY = clamp((int)(v * textureHeight + 0.5f), 0, textureHeight - 1);
|
int hitTexelY = clamp((int)(v + 0.5f), 0, hit.hitSurface->lightmapDims[1] - 1);
|
||||||
|
|
||||||
uint16_t *hitTexture = textures[hit.hitSurface->lightmapNum].data();
|
Vec3 *hitTexture = hit.hitSurface->samples.data();
|
||||||
uint16_t *hitPixel = hitTexture + (hitTexelX + hitTexelY * textureWidth) * 3;
|
const Vec3 &hitPixel = hitTexture[hitTexelX + hitTexelY * hit.hitSurface->lightmapDims[0]];
|
||||||
|
|
||||||
float attenuation = (1.0f - hit.fraction);
|
float attenuation = (1.0f - hit.fraction);
|
||||||
surfaceLight.x = halfToFloat(hitPixel[0]) * attenuation;
|
surfaceLight = hitPixel * attenuation;
|
||||||
surfaceLight.y = halfToFloat(hitPixel[1]) * attenuation;
|
|
||||||
surfaceLight.z = halfToFloat(hitPixel[2]) * attenuation;
|
|
||||||
}
|
}
|
||||||
c += surfaceLight * NdotL;
|
c += surfaceLight * NdotL;
|
||||||
}
|
}
|
||||||
|
@ -635,13 +649,7 @@ void LightmapBuilder::TraceIndirectLight(Surface *surface)
|
||||||
|
|
||||||
c = c / totalWeight;
|
c = c / totalWeight;
|
||||||
|
|
||||||
// convert RGB to bytes
|
indirect[i * sampleWidth + j] = c;
|
||||||
int tx = j + surface->lightmapOffs[0];
|
|
||||||
int ty = i + surface->lightmapOffs[1];
|
|
||||||
uint16_t *pixel = currentTexture + (tx + ty * textureWidth) * 3;
|
|
||||||
pixel[0] = floatToHalf(c.x);
|
|
||||||
pixel[1] = floatToHalf(c.y);
|
|
||||||
pixel[2] = floatToHalf(c.z);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -752,28 +760,23 @@ void LightmapBuilder::CreateLightmaps(FLevel &doomMap, int sampleDistance, int t
|
||||||
|
|
||||||
printf("Texels traced: %i \n\n", tracedTexels);
|
printf("Texels traced: %i \n\n", tracedTexels);
|
||||||
|
|
||||||
printf("------------- Tracing indirect -------------\n");
|
if (LightBounce > 0)
|
||||||
|
|
||||||
indirectoutput.resize(textures.size() * textureWidth * textureHeight * 3);
|
|
||||||
|
|
||||||
tracedTexels = 0;
|
|
||||||
processed = 0;
|
|
||||||
Worker::RunJob(mesh->surfaces.size(), [=](int id) {
|
|
||||||
LightIndirect(id);
|
|
||||||
});
|
|
||||||
|
|
||||||
for (size_t i = 0; i < textures.size(); i++)
|
|
||||||
{
|
{
|
||||||
uint16_t *tex = textures[i].data();
|
printf("------------- Tracing indirect -------------\n");
|
||||||
uint16_t *indirect = &indirectoutput[i * textureWidth * textureHeight * 3];
|
|
||||||
int count = textureWidth * textureHeight * 3;
|
tracedTexels = 0;
|
||||||
for (int j = 0; j < count; j++)
|
processed = 0;
|
||||||
{
|
Worker::RunJob(mesh->surfaces.size(), [=](int id) {
|
||||||
tex[j] = floatToHalf(halfToFloat(tex[j]) + halfToFloat(indirect[j]));
|
LightIndirect(id);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Texels traced: %i \n\n", tracedTexels);
|
printf("Texels traced: %i \n\n", tracedTexels);
|
||||||
|
|
||||||
|
for (auto &surf : mesh->surfaces)
|
||||||
|
{
|
||||||
|
FinishSurface(surf.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightmapBuilder::SetupLightCellGrid()
|
void LightmapBuilder::SetupLightCellGrid()
|
||||||
|
@ -1012,9 +1015,10 @@ void LightmapBuilder::AddLightmapLump(FWadWriter &wadFile)
|
||||||
for (size_t i = 0; i < textures.size(); i++)
|
for (size_t i = 0; i < textures.size(); i++)
|
||||||
{
|
{
|
||||||
unsigned int count = (textureWidth * textureHeight) * 3;
|
unsigned int count = (textureWidth * textureHeight) * 3;
|
||||||
|
uint16_t *pixels = textures[i]->Pixels();
|
||||||
for (unsigned int j = 0; j < count; j++)
|
for (unsigned int j = 0; j < count; j++)
|
||||||
{
|
{
|
||||||
lumpFile.Write16(textures[i][j]);
|
lumpFile.Write16(pixels[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
#include "framework/tarray.h"
|
#include "framework/tarray.h"
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#define LIGHTMAP_MAX_SIZE 1024
|
|
||||||
|
|
||||||
#define LIGHTCELL_SIZE 64
|
#define LIGHTCELL_SIZE 64
|
||||||
#define LIGHTCELL_BLOCK_SIZE 16
|
#define LIGHTCELL_BLOCK_SIZE 16
|
||||||
|
|
||||||
|
@ -55,6 +53,20 @@ public:
|
||||||
std::vector<LightCellBlock> blocks;
|
std::vector<LightCellBlock> blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LightmapTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LightmapTexture(int width, int height)
|
||||||
|
{
|
||||||
|
mPixels.resize(width * height * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t *Pixels() { return mPixels.data(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<uint16_t> mPixels;
|
||||||
|
};
|
||||||
|
|
||||||
class LightmapBuilder
|
class LightmapBuilder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -74,6 +86,7 @@ private:
|
||||||
void BuildSurfaceParams(Surface *surface);
|
void BuildSurfaceParams(Surface *surface);
|
||||||
void TraceSurface(Surface *surface);
|
void TraceSurface(Surface *surface);
|
||||||
void TraceIndirectLight(Surface *surface);
|
void TraceIndirectLight(Surface *surface);
|
||||||
|
void FinishSurface(Surface *surface);
|
||||||
void SetupLightCellGrid();
|
void SetupLightCellGrid();
|
||||||
void LightBlock(int blockid);
|
void LightBlock(int blockid);
|
||||||
void LightSurface(const int surfid);
|
void LightSurface(const int surfid);
|
||||||
|
@ -88,8 +101,7 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<LevelMesh> mesh;
|
std::unique_ptr<LevelMesh> mesh;
|
||||||
std::vector<std::unique_ptr<SurfaceLight>> surfaceLights;
|
std::vector<std::unique_ptr<SurfaceLight>> surfaceLights;
|
||||||
std::vector<std::vector<uint16_t>> textures;
|
std::vector<std::unique_ptr<LightmapTexture>> textures;
|
||||||
std::vector<uint16_t> indirectoutput;
|
|
||||||
std::vector<std::vector<int>> allocBlocks;
|
std::vector<std::vector<int>> allocBlocks;
|
||||||
int numTextures = 0;
|
int numTextures = 0;
|
||||||
int extraSamples = 2;
|
int extraSamples = 2;
|
||||||
|
|
|
@ -61,6 +61,8 @@ struct Surface
|
||||||
int numVerts;
|
int numVerts;
|
||||||
std::vector<Vec3> verts;
|
std::vector<Vec3> verts;
|
||||||
std::vector<float> lightmapCoords;
|
std::vector<float> lightmapCoords;
|
||||||
|
std::vector<Vec3> samples;
|
||||||
|
std::vector<Vec3> indirect;
|
||||||
SurfaceType type;
|
SurfaceType type;
|
||||||
int typeIndex;
|
int typeIndex;
|
||||||
IntSector *controlSector;
|
IntSector *controlSector;
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
|
|
||||||
extern int NumThreads;
|
extern int NumThreads;
|
||||||
|
|
||||||
thread_local Vec3 *colorSamples;
|
|
||||||
|
|
||||||
void Worker::RunJob(int count, std::function<void(int)> callback)
|
void Worker::RunJob(int count, std::function<void(int)> callback)
|
||||||
{
|
{
|
||||||
int numThreads = NumThreads;
|
int numThreads = NumThreads;
|
||||||
|
@ -25,9 +23,6 @@ void Worker::RunJob(int count, std::function<void(int)> callback)
|
||||||
{
|
{
|
||||||
threads.push_back(std::thread([=]() {
|
threads.push_back(std::thread([=]() {
|
||||||
|
|
||||||
std::vector<Vec3> samples(LIGHTMAP_MAX_SIZE * LIGHTMAP_MAX_SIZE);
|
|
||||||
colorSamples = samples.data();
|
|
||||||
|
|
||||||
int start = threadIndex * count / numThreads;
|
int start = threadIndex * count / numThreads;
|
||||||
int end = std::min((threadIndex + 1) * count / numThreads, count);
|
int end = std::min((threadIndex + 1) * count / numThreads, count);
|
||||||
for (int i = start; i < end; i++)
|
for (int i = start; i < end; i++)
|
||||||
|
|
13
src/main.cpp
13
src/main.cpp
|
@ -114,9 +114,10 @@ bool V5GLNodes = false;
|
||||||
bool HaveSSE1, HaveSSE2;
|
bool HaveSSE1, HaveSSE2;
|
||||||
int SSELevel;
|
int SSELevel;
|
||||||
int NumThreads = 0;
|
int NumThreads = 0;
|
||||||
int LMDims = LIGHTMAP_MAX_SIZE;
|
int LMDims = 1024;
|
||||||
int Samples = 8;
|
int Samples = 8;
|
||||||
int Multisample = 1;
|
int Multisample = 1;
|
||||||
|
int LightBounce = 0;
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
|
||||||
|
@ -155,6 +156,7 @@ static option long_opts[] =
|
||||||
{"samples", required_argument, 0, 'Q'},
|
{"samples", required_argument, 0, 'Q'},
|
||||||
{"size", required_argument, 0, 'S'},
|
{"size", required_argument, 0, 'S'},
|
||||||
{"multisample", required_argument, 0, 'M'},
|
{"multisample", required_argument, 0, 'M'},
|
||||||
|
{"bounce", required_argument, 0, 'B'},
|
||||||
{0,0,0,0}
|
{0,0,0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -442,7 +444,7 @@ static void ParseArgs(int argc, char **argv)
|
||||||
case 'S':
|
case 'S':
|
||||||
LMDims = atoi(optarg);
|
LMDims = atoi(optarg);
|
||||||
if (LMDims <= 0) LMDims = 1;
|
if (LMDims <= 0) LMDims = 1;
|
||||||
if (LMDims > LIGHTMAP_MAX_SIZE) LMDims = LIGHTMAP_MAX_SIZE;
|
if (LMDims > 1024) LMDims = 1024;
|
||||||
LMDims = Math::RoundPowerOfTwo(LMDims);
|
LMDims = Math::RoundPowerOfTwo(LMDims);
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
|
@ -450,6 +452,11 @@ static void ParseArgs(int argc, char **argv)
|
||||||
if (Multisample <= 0) Multisample = 1;
|
if (Multisample <= 0) Multisample = 1;
|
||||||
if (Multisample > 64) Multisample = 64;
|
if (Multisample > 64) Multisample = 64;
|
||||||
break;
|
break;
|
||||||
|
case 'B':
|
||||||
|
LightBounce = atoi(optarg);
|
||||||
|
if (LightBounce < 0) LightBounce = 0;
|
||||||
|
if (LightBounce > 1) LightBounce = 1;
|
||||||
|
break;
|
||||||
case 1000:
|
case 1000:
|
||||||
ShowUsage();
|
ShowUsage();
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -497,6 +504,7 @@ static void ShowUsage()
|
||||||
" -S, --size=NNN lightmap texture dimensions for width and height\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"
|
" 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"
|
" -M, --multisample=NNN Number of samples to use per texel (default %d)\n"
|
||||||
|
" -B, --bounce=NNN Number of indirect light bounces (default %d, max 1)\n"
|
||||||
" -w, --warn Show warning messages\n"
|
" -w, --warn Show warning messages\n"
|
||||||
#if HAVE_TIMING
|
#if HAVE_TIMING
|
||||||
" -t, --no-timing Suppress timing information\n"
|
" -t, --no-timing Suppress timing information\n"
|
||||||
|
@ -511,6 +519,7 @@ static void ShowUsage()
|
||||||
, AAPreference
|
, AAPreference
|
||||||
, (int)std::thread::hardware_concurrency()
|
, (int)std::thread::hardware_concurrency()
|
||||||
, Multisample
|
, Multisample
|
||||||
|
, LightBounce
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue