mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-02-03 05:01:00 +00:00
Merge pull request #36 from MrRaveYard/pr_per_surface_sample_size
Customizable sampling distance per surface
This commit is contained in:
commit
cc273c5f38
17 changed files with 104 additions and 43 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -29,7 +29,6 @@ struct CPUTraceState
|
|||
uint32_t PassType;
|
||||
uint32_t LightCount;
|
||||
vec3 SunDir;
|
||||
float SampleDistance;
|
||||
vec3 SunColor;
|
||||
float SunIntensity;
|
||||
vec3 HemisphereVec;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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[]; };
|
||||
|
|
|
@ -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[]; };
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue