Support customizable sampling distance per surface

- Fix sampleDistance UDMF

- Refactoring code

- Handle 3D floors sides via lm_sampledist_mid per each wall in the
  applied sector
This commit is contained in:
RaveYard 2022-06-15 19:02:53 +02:00
parent e822dc36e3
commit 0479d4fce3
17 changed files with 104 additions and 43 deletions

View file

@ -60,6 +60,15 @@ struct IntSideDef
IntLineDef *line;
int sampleDistance;
int sampleDistanceTop;
int sampleDistanceMiddle;
int sampleDistanceBottom;
inline int GetSampleDistanceTop() const { return sampleDistanceTop ? sampleDistanceTop : sampleDistance; }
inline int GetSampleDistanceMiddle() const { return sampleDistanceMiddle ? sampleDistanceMiddle : sampleDistance; }
inline int GetSampleDistanceBottom() const { return sampleDistanceBottom ? sampleDistanceBottom : sampleDistance; }
TArray<UDMFKey> props;
};
@ -119,6 +128,9 @@ struct IntSector
Plane ceilingplane;
Plane floorplane;
int sampleDistanceCeiling;
int sampleDistanceFloor;
int floorlightdef;
int ceilinglightdef;
@ -396,7 +408,7 @@ struct FLevel
vec3 defaultSunColor;
vec3 defaultSunDirection;
int Samples;
int DefaultSamples;
int LightBounce;
float GridSize;

View file

@ -694,7 +694,7 @@ void FProcessor::BuildNodes()
void FProcessor::BuildLightmaps()
{
Level.SetupLights();
LightmapMesh = std::make_unique<LevelMesh>(Level, Level.Samples, LMDims);
LightmapMesh = std::make_unique<LevelMesh>(Level, Level.DefaultSamples, LMDims);
std::unique_ptr<GPURaytracer> gpuraytracer;
if (!CPURaytrace)

View file

@ -87,7 +87,7 @@ void FLevel::SetupLights()
// GG to whoever memset'ed FLevel
defaultSunColor = vec3(1, 1, 1);
defaultSunDirection = vec3(0.45f, 0.3f, 0.9f);
Samples = 8;
DefaultSamples = 8;
LightBounce = 0;
GridSize = 32.0f;
@ -128,10 +128,10 @@ void FLevel::SetupLights()
}
else if (!stricmp(key.key, "lm_sampledistance"))
{
Samples = atoi(key.value);
if (Samples < 8) Samples = 8;
if (Samples > 128) Samples = 128;
Samples = Math::RoundPowerOfTwo(Samples);
DefaultSamples = atoi(key.value);
if (DefaultSamples < 8) DefaultSamples = 8;
if (DefaultSamples > 128) DefaultSamples = 128;
DefaultSamples = Math::RoundPowerOfTwo(DefaultSamples);
}
/*
// light bounces temporarily disabled

View file

@ -365,6 +365,10 @@ void FProcessor::ParseSidedef(IntSideDef *sd)
sd->midtexture[1] = 0;
sd->bottomtexture[0] = '-';
sd->bottomtexture[1] = 0;
sd->sampleDistance = 0;
sd->sampleDistanceTop = 0;
sd->sampleDistanceMiddle = 0;
sd->sampleDistanceBottom = 0;
while (!SC_CheckString("}"))
{
const char *value;
@ -396,6 +400,22 @@ void FProcessor::ParseSidedef(IntSideDef *sd)
{
sd->rowoffset = CheckInt(key);
}
else if (stricmp(key, "lm_sampledist") == 0)
{
sd->sampleDistance = CheckInt(key);
}
else if (stricmp(key, "lm_sampledist_top") == 0)
{
sd->sampleDistanceTop = CheckInt(key);
}
else if (stricmp(key, "lm_sampledist_mid") == 0)
{
sd->sampleDistanceMiddle = CheckInt(key);
}
else if (stricmp(key, "lm_sampledist_bot") == 0)
{
sd->sampleDistanceBottom = CheckInt(key);
}
// now store the key in its unprocessed form
UDMFKey k = {key, value};
@ -414,6 +434,8 @@ void FProcessor::ParseSector(IntSector *sec)
std::vector<int> moreids;
memset(&sec->data, 0, sizeof(sec->data));
sec->data.lightlevel = 160;
sec->sampleDistanceCeiling = 0;
sec->sampleDistanceFloor = 0;
int ceilingplane = 0, floorplane = 0;
@ -514,6 +536,14 @@ void FProcessor::ParseSector(IntSector *sec)
free(workstring);
}
}
else if (stricmp(key, "lm_sampledist_floor") == 0)
{
sec->sampleDistanceFloor = CheckInt(key);
}
else if (stricmp(key, "lm_sampledist_ceiling") == 0)
{
sec->sampleDistanceCeiling = CheckInt(key);
}
// now store the key in its unprocessed form
UDMFKey k = {key, value};

View file

@ -87,7 +87,6 @@ void CPURaytracer::RaytraceTask(const CPUTraceTask& task)
state.StartSurface = nullptr;
}
state.SampleDistance = (float)mesh->samples;
state.LightCount = mesh->map->ThingLights.Size();
state.SunDir = mesh->map->GetSunDirection();
state.SunColor = mesh->map->GetSunColor();
@ -260,7 +259,7 @@ void CPURaytracer::RunLightTrace(CPUTraceState& state)
for (uint32_t i = 0; i < state.SampleCount; i++)
{
vec2 offset = (Hammersley(i, state.SampleCount) - 0.5f) * state.SampleDistance;
vec2 offset = (Hammersley(i, state.SampleCount) - 0.5f) * float(surface->sampleDimension);
vec3 origin2 = origin + e0 * offset.x + e1 * offset.y;
vec3 start = origin2;
@ -316,7 +315,7 @@ void CPURaytracer::RunLightTrace(CPUTraceState& state)
e0 = cross(normal, e1);
for (uint32_t i = 0; i < state.SampleCount; i++)
{
vec2 offset = (Hammersley(i, state.SampleCount) - 0.5f) * state.SampleDistance;
vec2 offset = (Hammersley(i, state.SampleCount) - 0.5f) * float(surface->sampleDimension);
vec3 origin2 = origin + e0 * offset.x + e1 * offset.y;
LevelTraceHit hit = Trace(origin2, light.Origin);

View file

@ -29,7 +29,6 @@ struct CPUTraceState
uint32_t PassType;
uint32_t LightCount;
vec3 SunDir;
float SampleDistance;
vec3 SunColor;
float SunIntensity;
vec3 HemisphereVec;

View file

@ -17,7 +17,8 @@ struct SurfaceInfo
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float Padding0, Padding1, Padding2;
float SamplingDistance;
float Padding1, Padding2;
};
layout(location = 0) rayPayloadInEXT hitPayload payload;

View file

@ -17,7 +17,8 @@ struct SurfaceInfo
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float Padding0, Padding1, Padding2;
float SamplingDistance;
float Padding1, Padding2;
};
layout(location = 0) rayPayloadInEXT hitPayload payload;

View file

@ -17,7 +17,8 @@ struct SurfaceInfo
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float Padding0, Padding1, Padding2;
float SamplingDistance;
float Padding1, Padding2;
};
layout(location = 0) rayPayloadInEXT hitPayload payload;

View file

@ -17,7 +17,8 @@ struct SurfaceInfo
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float Padding0, Padding1, Padding2;
float SamplingDistance;
float Padding1, Padding2;
};
layout(location = 0) rayPayloadInEXT hitPayload payload;

View file

@ -24,11 +24,11 @@ layout(set = 0, binding = 4) uniform Uniforms
uint PassType;
uint Padding0;
vec3 SunDir;
float SampleDistance;
float Padding1;
vec3 SunColor;
float SunIntensity;
vec3 HemisphereVec;
float Padding1;
float Padding2;
};
struct SurfaceInfo
@ -38,7 +38,8 @@ struct SurfaceInfo
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float Padding0, Padding1, Padding2;
float SamplingDistance;
float Padding1, Padding2;
};
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };

View file

@ -24,11 +24,11 @@ layout(set = 0, binding = 4) uniform Uniforms
uint PassType;
uint Padding0;
vec3 SunDir;
float SampleDistance;
float Padding1;
vec3 SunColor;
float SunIntensity;
vec3 HemisphereVec;
float Padding1;
float Padding2;
};
struct SurfaceInfo
@ -38,7 +38,8 @@ struct SurfaceInfo
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float Padding0, Padding1, Padding2;
float SamplingDistance;
float Padding1, Padding2;
};
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };

View file

@ -24,11 +24,11 @@ layout(set = 0, binding = 4) uniform Uniforms
uint PassType;
uint Padding0;
vec3 SunDir;
float SampleDistance;
float Padding1;
vec3 SunColor;
float SunIntensity;
vec3 HemisphereVec;
float Padding1;
float Padding2;
};
struct SurfaceInfo
@ -38,7 +38,8 @@ struct SurfaceInfo
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float Padding0, Padding1, Padding2;
float SamplingDistance;
float Padding1, Padding2;
};
struct LightInfo
@ -100,7 +101,7 @@ void main()
for (uint i = 0; i < SampleCount; i++)
{
vec2 offset = (Hammersley(i, SampleCount) - 0.5) * SampleDistance;
vec2 offset = (Hammersley(i, SampleCount) - 0.5) * surfaces[surfaceIndex].SamplingDistance;
vec3 origin2 = origin + offset.x * e0 + offset.y * e1;
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 2, 0, 2, origin2, minDistance, SunDir, dist, 0);
@ -151,7 +152,7 @@ void main()
e0 = cross(normal, e1);
for (uint i = 0; i < SampleCount; i++)
{
vec2 offset = (Hammersley(i, SampleCount) - 0.5) * SampleDistance;
vec2 offset = (Hammersley(i, SampleCount) - 0.5) * surfaces[surfaceIndex].SamplingDistance;
vec3 origin2 = origin + offset.x * e0 + offset.y * e1;
float dist2 = distance(light.Origin, origin2);

View file

@ -103,7 +103,6 @@ void GPURaytracer::Raytrace(LevelMesh* level)
BeginTracing();
Uniforms uniforms = {};
uniforms.SampleDistance = (float)mesh->samples;
uniforms.SunDir = mesh->map->GetSunDirection();
uniforms.SunColor = mesh->map->GetSunColor();
uniforms.SunIntensity = 1.0f;
@ -403,6 +402,8 @@ void GPURaytracer::CreateVertexAndIndexBuffers()
info.EmissiveIntensity = 0.0f;
info.EmissiveColor = vec3(0.0f, 0.0f, 0.0f);
}
info.SamplingDistance = surface->sampleDimension;
surfaces.push_back(info);
}

View file

@ -13,11 +13,11 @@ struct Uniforms
uint32_t PassType;
uint32_t Padding0;
vec3 SunDir;
float SampleDistance;
float Padding1;
vec3 SunColor;
float SunIntensity;
vec3 HemisphereVec;
float Padding1;
float Padding2;
};
struct PushConstants
@ -34,7 +34,8 @@ struct SurfaceInfo
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float Padding0, Padding1, Padding2;
float SamplingDistance;
float Padding1, Padding2;
};
struct LightInfo

View file

@ -42,7 +42,7 @@
LevelMesh::LevelMesh(FLevel &doomMap, int sampleDistance, int textureSize)
{
map = &doomMap;
samples = sampleDistance;
defaultSamples = sampleDistance;
textureWidth = textureSize;
textureHeight = textureSize;
@ -132,13 +132,16 @@ void LevelMesh::BuildSurfaceParams(Surface* surface)
plane = &surface->plane;
bounds = GetBoundsFromSurface(surface);
if (surface->sampleDimension < 0) surface->sampleDimension = 1;
surface->sampleDimension = Math::RoundPowerOfTwo(surface->sampleDimension);
// round off dimentions
for (i = 0; i < 3; i++)
{
bounds.min[i] = samples * (Math::Floor(bounds.min[i] / samples) - 1);
bounds.max[i] = samples * (Math::Ceil(bounds.max[i] / samples) + 1);
bounds.min[i] = surface->sampleDimension * (Math::Floor(bounds.min[i] / surface->sampleDimension) - 1);
bounds.max[i] = surface->sampleDimension * (Math::Ceil(bounds.max[i] / surface->sampleDimension) + 1);
roundedSize[i] = (bounds.max[i] - bounds.min[i]) / samples;
roundedSize[i] = (bounds.max[i] - bounds.min[i]) / surface->sampleDimension;
}
tCoords[0] = vec3(0.0f);
@ -151,22 +154,22 @@ void LevelMesh::BuildSurfaceParams(Surface* surface)
case Plane::AXIS_YZ:
width = (int)roundedSize.y;
height = (int)roundedSize.z;
tCoords[0].y = 1.0f / samples;
tCoords[1].z = 1.0f / samples;
tCoords[0].y = 1.0f / surface->sampleDimension;
tCoords[1].z = 1.0f / surface->sampleDimension;
break;
case Plane::AXIS_XZ:
width = (int)roundedSize.x;
height = (int)roundedSize.z;
tCoords[0].x = 1.0f / samples;
tCoords[1].z = 1.0f / samples;
tCoords[0].x = 1.0f / surface->sampleDimension;
tCoords[1].z = 1.0f / surface->sampleDimension;
break;
case Plane::AXIS_XY:
width = (int)roundedSize.x;
height = (int)roundedSize.y;
tCoords[0].x = 1.0f / samples;
tCoords[1].y = 1.0f / samples;
tCoords[0].x = 1.0f / surface->sampleDimension;
tCoords[1].y = 1.0f / surface->sampleDimension;
break;
}
@ -231,8 +234,8 @@ void LevelMesh::BuildSurfaceParams(Surface* surface)
surface->lightmapDims[0] = width;
surface->lightmapDims[1] = height;
surface->lightmapOrigin = tOrigin;
surface->lightmapSteps[0] = tCoords[0] * (float)samples;
surface->lightmapSteps[1] = tCoords[1] * (float)samples;
surface->lightmapSteps[0] = tCoords[0] * (float)surface->sampleDimension;
surface->lightmapSteps[1] = tCoords[1] * (float)surface->sampleDimension;
surface->samples.resize(width * height);
surface->indirect.resize(width * height);
@ -518,11 +521,14 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side)
float texWidth = 128.0f;
float texHeight = 128.0f;
IntSideDef* otherSide = &doomMap.Sides[side->line->sidenum[0]] == side ? &doomMap.Sides[side->line->sidenum[1]] : &doomMap.Sides[side->line->sidenum[0]];
auto surf = std::make_unique<Surface>();
surf->material = "texture";
surf->type = ST_MIDDLESIDE;
surf->typeIndex = typeIndex;
surf->controlSector = xfloor;
surf->sampleDimension = (surf->sampleDimension = otherSide->GetSampleDistanceMiddle()) ? surf->sampleDimension : defaultSamples;
surf->numVerts = 4;
surf->verts.resize(4);
surf->verts[0].x = surf->verts[2].x = v2.x;
@ -588,6 +594,7 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side)
surf->type = ST_LOWERSIDE;
surf->typeIndex = typeIndex;
surf->controlSector = nullptr;
surf->sampleDimension = (surf->sampleDimension = side->GetSampleDistanceBottom()) ? surf->sampleDimension : defaultSamples;
float texZ = surf->verts[0].z;
@ -646,6 +653,7 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side)
surf->typeIndex = typeIndex;
surf->bSky = bSky;
surf->controlSector = nullptr;
surf->sampleDimension = (surf->sampleDimension = side->GetSampleDistanceTop()) ? surf->sampleDimension : defaultSamples;
float texZ = surf->verts[0].z;
@ -692,6 +700,7 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side)
surf->type = ST_MIDDLESIDE;
surf->typeIndex = typeIndex;
surf->controlSector = nullptr;
surf->sampleDimension = (surf->sampleDimension = side->GetSampleDistanceMiddle()) ? surf->sampleDimension : defaultSamples;
float texZ = surf->verts[0].z;
@ -712,6 +721,7 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side)
void LevelMesh::CreateFloorSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSector *sector, int typeIndex, bool is3DFloor)
{
auto surf = std::make_unique<Surface>();
surf->sampleDimension = sector->sampleDistanceFloor ? sector->sampleDistanceFloor : defaultSamples;
surf->material = sector->data.floorpic;
surf->numVerts = sub->numlines;
surf->verts.resize(surf->numVerts);
@ -750,6 +760,7 @@ void LevelMesh::CreateCeilingSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSe
{
auto surf = std::make_unique<Surface>();
surf->material = sector->data.ceilingpic;
surf->sampleDimension = sector->sampleDistanceCeiling ? sector->sampleDistanceCeiling : defaultSamples;
surf->numVerts = sub->numlines;
surf->verts.resize(surf->numVerts);
surf->uvs.resize(surf->numVerts);

View file

@ -74,6 +74,7 @@ struct Surface
bool bSky;
std::vector<vec2> uvs;
std::string material;
int sampleDimension;
};
class LightProbeSample
@ -99,7 +100,7 @@ public:
std::vector<std::unique_ptr<LightmapTexture>> textures;
int samples = 16;
int defaultSamples = 16;
int textureWidth = 128;
int textureHeight = 128;