mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-25 05:11:20 +00:00
Sort surfaces into smoothing groups and render the entire group into a surface tile
Extend the raytracing of a surface tile by one to get better transitions Fix Plane.Distance(point) not actually returning the distance to the point!
This commit is contained in:
parent
9c43d0336d
commit
941cf6228a
7 changed files with 128 additions and 113 deletions
|
@ -48,8 +48,6 @@ layout(push_constant) uniform PushConstants
|
||||||
uint LightEnd;
|
uint LightEnd;
|
||||||
int SurfaceIndex;
|
int SurfaceIndex;
|
||||||
int PushPadding1;
|
int PushPadding1;
|
||||||
vec2 TileTL;
|
|
||||||
vec2 TileBR;
|
|
||||||
vec3 LightmapOrigin;
|
vec3 LightmapOrigin;
|
||||||
float PushPadding2;
|
float PushPadding2;
|
||||||
vec3 LightmapStepX;
|
vec3 LightmapStepX;
|
||||||
|
|
|
@ -8,8 +8,6 @@ layout(push_constant) uniform PushConstants
|
||||||
uint LightEnd;
|
uint LightEnd;
|
||||||
int SurfaceIndex;
|
int SurfaceIndex;
|
||||||
int PushPadding1;
|
int PushPadding1;
|
||||||
vec2 TileTL;
|
|
||||||
vec2 TileBR;
|
|
||||||
vec3 LightmapOrigin;
|
vec3 LightmapOrigin;
|
||||||
float PushPadding2;
|
float PushPadding2;
|
||||||
vec3 LightmapStepX;
|
vec3 LightmapStepX;
|
||||||
|
|
|
@ -59,16 +59,17 @@ void GPURaytracer2::Raytrace(LevelMesh* level)
|
||||||
.AddBuffer(uniformBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
|
.AddBuffer(uniformBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT)
|
||||||
.Execute(cmdbuffer.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
.Execute(cmdbuffer.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
|
||||||
const int atlasImageSize = 512;
|
const int atlasImageSize = 2048;
|
||||||
RectPacker packer(atlasImageSize, atlasImageSize, RectPacker::Spacing(0));
|
const int spacing = 3; // Note: the spacing is here to avoid that the resolve sampler finds data from other surface tiles
|
||||||
|
RectPacker packer(atlasImageSize, atlasImageSize, RectPacker::Spacing(spacing));
|
||||||
|
|
||||||
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
||||||
{
|
{
|
||||||
Surface* surface = mesh->surfaces[i].get();
|
Surface* surface = mesh->surfaces[i].get();
|
||||||
|
|
||||||
auto result = packer.insert(surface->texWidth, surface->texHeight);
|
auto result = packer.insert(surface->texWidth + 2, surface->texHeight + 2);
|
||||||
surface->atlasX = result.pos.x;
|
surface->atlasX = result.pos.x + 1;
|
||||||
surface->atlasY = result.pos.y;
|
surface->atlasY = result.pos.y + 1;
|
||||||
surface->atlasPageIndex = (int)result.pageIndex;
|
surface->atlasPageIndex = (int)result.pageIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,114 +96,81 @@ void GPURaytracer2::Raytrace(LevelMesh* level)
|
||||||
|
|
||||||
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
for (size_t i = 0; i < mesh->surfaces.size(); i++)
|
||||||
{
|
{
|
||||||
Surface* surface = mesh->surfaces[i].get();
|
Surface* targetSurface = mesh->surfaces[i].get();
|
||||||
if (surface->atlasPageIndex != pageIndex)
|
if (targetSurface->atlasPageIndex != pageIndex)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int sampleWidth = surface->texWidth;
|
|
||||||
int sampleHeight = surface->texHeight;
|
|
||||||
|
|
||||||
int firstLight = sceneLightPos;
|
|
||||||
int lightCount = (int)surface->LightList.size();
|
|
||||||
sceneLightPos += lightCount;
|
|
||||||
|
|
||||||
LightInfo2* lightinfo = &sceneLights[firstLight];
|
|
||||||
for (ThingLight* light : surface->LightList)
|
|
||||||
{
|
|
||||||
lightinfo->Origin = light->LightOrigin();
|
|
||||||
lightinfo->Radius = light->LightRadius();
|
|
||||||
lightinfo->Intensity = light->intensity;
|
|
||||||
lightinfo->InnerAngleCos = light->innerAngleCos;
|
|
||||||
lightinfo->OuterAngleCos = light->outerAngleCos;
|
|
||||||
lightinfo->SpotDir = light->SpotDir();
|
|
||||||
lightinfo->Color = light->rgb;
|
|
||||||
lightinfo++;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkViewport viewport = {};
|
VkViewport viewport = {};
|
||||||
viewport.maxDepth = 1;
|
viewport.maxDepth = 1;
|
||||||
viewport.x = (float)surface->atlasX;
|
viewport.x = (float)targetSurface->atlasX - 1;
|
||||||
viewport.y = (float)surface->atlasY;
|
viewport.y = (float)targetSurface->atlasY - 1;
|
||||||
viewport.width = (float)sampleWidth;
|
viewport.width = (float)(targetSurface->texWidth + 2);
|
||||||
viewport.height = (float)sampleHeight;
|
viewport.height = (float)(targetSurface->texHeight + 2);
|
||||||
cmdbuffer->setViewport(0, 1, &viewport);
|
cmdbuffer->setViewport(0, 1, &viewport);
|
||||||
|
|
||||||
PushConstants2 pc;
|
// Paint all surfaces part of the smoothing group into the surface
|
||||||
pc.LightStart = firstLight;
|
for (const auto& surface : mesh->surfaces)
|
||||||
pc.LightEnd = firstLight + lightCount;
|
|
||||||
pc.SurfaceIndex = (int32_t)i;
|
|
||||||
pc.TileTL = vec2(0.0f);
|
|
||||||
pc.TileBR = vec2(1.0f);
|
|
||||||
pc.LightmapOrigin = surface->worldOrigin;
|
|
||||||
pc.LightmapStepX = surface->worldStepX * (float)sampleWidth;
|
|
||||||
pc.LightmapStepY = surface->worldStepY * (float)sampleHeight;
|
|
||||||
cmdbuffer->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants2), &pc);
|
|
||||||
|
|
||||||
if (vertexList.size() < surface->lightUV.size())
|
|
||||||
vertexList.resize(surface->lightUV.size());
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
// Draw tile
|
|
||||||
int firstVertex = sceneVertexPos;
|
|
||||||
int vertexCount = 4;
|
|
||||||
sceneVertexPos += vertexCount;
|
|
||||||
|
|
||||||
SceneVertex* vertex = &sceneVertices[firstVertex];
|
|
||||||
vertex[0].Position = vec2(0.0f, 0.0f);
|
|
||||||
vertex[1].Position = vec2(1.0f, 0.0f);
|
|
||||||
vertex[2].Position = vec2(1.0f, 1.0f);
|
|
||||||
vertex[3].Position = vec2(0.0f, 1.0f);
|
|
||||||
|
|
||||||
cmdbuffer->draw(vertexCount, 1, firstVertex, 0);
|
|
||||||
#else
|
|
||||||
// Convert to triangle fan and correct orientation
|
|
||||||
int vertexCount = (int)surface->lightUV.size();
|
|
||||||
if (surface->type == ST_FLOOR || surface->type == ST_CEILING)
|
|
||||||
{
|
{
|
||||||
if (IsNegativelyOriented(surface->lightUV[0], surface->lightUV[1], surface->lightUV[2]))
|
if (surface->smoothingGroupIndex != targetSurface->smoothingGroupIndex)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vec2 minUV = ToUV(surface->bounds.min, targetSurface);
|
||||||
|
vec2 maxUV = ToUV(surface->bounds.max, targetSurface);
|
||||||
|
if (surface.get() != targetSurface && (maxUV.x < 0.0f || maxUV.y < 0.0f || minUV.x > 1.0f || minUV.y > 1.0f))
|
||||||
|
continue; // Bounding box not visible
|
||||||
|
|
||||||
|
int firstLight = sceneLightPos;
|
||||||
|
int lightCount = (int)surface->LightList.size();
|
||||||
|
if (sceneLightPos + lightCount > SceneLightBufferSize)
|
||||||
|
throw std::runtime_error("SceneLightBuffer is too small!");
|
||||||
|
sceneLightPos += lightCount;
|
||||||
|
|
||||||
|
LightInfo2* lightinfo = &sceneLights[firstLight];
|
||||||
|
for (ThingLight* light : surface->LightList)
|
||||||
|
{
|
||||||
|
lightinfo->Origin = light->LightOrigin();
|
||||||
|
lightinfo->Radius = light->LightRadius();
|
||||||
|
lightinfo->Intensity = light->intensity;
|
||||||
|
lightinfo->InnerAngleCos = light->innerAngleCos;
|
||||||
|
lightinfo->OuterAngleCos = light->outerAngleCos;
|
||||||
|
lightinfo->SpotDir = light->SpotDir();
|
||||||
|
lightinfo->Color = light->rgb;
|
||||||
|
lightinfo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PushConstants2 pc;
|
||||||
|
pc.LightStart = firstLight;
|
||||||
|
pc.LightEnd = firstLight + lightCount;
|
||||||
|
pc.SurfaceIndex = (int32_t)i;
|
||||||
|
pc.LightmapOrigin = targetSurface->worldOrigin - targetSurface->worldStepX - targetSurface->worldStepY;
|
||||||
|
pc.LightmapStepX = targetSurface->worldStepX * viewport.width;
|
||||||
|
pc.LightmapStepY = targetSurface->worldStepY * viewport.height;
|
||||||
|
cmdbuffer->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants2), &pc);
|
||||||
|
|
||||||
|
int firstVertex = sceneVertexPos;
|
||||||
|
int vertexCount = (int)surface->verts.size();
|
||||||
|
if (sceneVertexPos + vertexCount > SceneVertexBufferSize)
|
||||||
|
throw std::runtime_error("SceneVertexBuffer is too small!");
|
||||||
|
sceneVertexPos += vertexCount;
|
||||||
|
SceneVertex* vertex = &sceneVertices[firstVertex];
|
||||||
|
|
||||||
|
if (surface->type == ST_FLOOR || surface->type == ST_CEILING)
|
||||||
{
|
{
|
||||||
for (int idx = 0; idx < vertexCount; idx++)
|
for (int idx = 0; idx < vertexCount; idx++)
|
||||||
{
|
{
|
||||||
vertexList[idx] = surface->lightUV[idx];
|
(vertex++)->Position = ToUV(surface->verts[idx], targetSurface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int idx = 0; idx < vertexCount; idx++)
|
(vertex++)->Position = ToUV(surface->verts[0], targetSurface);
|
||||||
{
|
(vertex++)->Position = ToUV(surface->verts[2], targetSurface);
|
||||||
vertexList[idx] = surface->lightUV[vertexCount - 1 - idx];
|
(vertex++)->Position = ToUV(surface->verts[3], targetSurface);
|
||||||
}
|
(vertex++)->Position = ToUV(surface->verts[1], targetSurface);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (IsNegativelyOriented(surface->lightUV[0], surface->lightUV[2], surface->lightUV[3]))
|
|
||||||
{
|
|
||||||
vertexList[0] = surface->lightUV[0];
|
|
||||||
vertexList[1] = surface->lightUV[2];
|
|
||||||
vertexList[2] = surface->lightUV[3];
|
|
||||||
vertexList[3] = surface->lightUV[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vertexList[0] = surface->lightUV[1];
|
|
||||||
vertexList[1] = surface->lightUV[3];
|
|
||||||
vertexList[2] = surface->lightUV[2];
|
|
||||||
vertexList[3] = surface->lightUV[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw polygon
|
cmdbuffer->draw(vertexCount, 1, firstVertex, 0);
|
||||||
int firstVertex = sceneVertexPos;
|
|
||||||
sceneVertexPos += vertexCount;
|
|
||||||
SceneVertex* vertex = &sceneVertices[firstVertex];
|
|
||||||
for (int idx = 0; idx < vertexCount; idx++)
|
|
||||||
{
|
|
||||||
auto& uv = vertexList[idx];
|
|
||||||
(vertex++)->Position = vec2(uv.x / sampleWidth, uv.y / sampleHeight);
|
|
||||||
}
|
}
|
||||||
cmdbuffer->draw(vertexCount, 1, firstVertex, 0);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
cmdbuffer->endRenderPass();
|
cmdbuffer->endRenderPass();
|
||||||
}
|
}
|
||||||
|
@ -243,8 +211,6 @@ void GPURaytracer2::Raytrace(LevelMesh* level)
|
||||||
pc.LightStart = 0;
|
pc.LightStart = 0;
|
||||||
pc.LightEnd = 0;
|
pc.LightEnd = 0;
|
||||||
pc.SurfaceIndex = 0;
|
pc.SurfaceIndex = 0;
|
||||||
pc.TileTL = vec2(0.0f);
|
|
||||||
pc.TileBR = vec2(1.0f);
|
|
||||||
pc.LightmapOrigin = vec3(0.0f);
|
pc.LightmapOrigin = vec3(0.0f);
|
||||||
pc.LightmapStepX = vec3(0.0f);
|
pc.LightmapStepX = vec3(0.0f);
|
||||||
pc.LightmapStepY = vec3(0.0f);
|
pc.LightmapStepY = vec3(0.0f);
|
||||||
|
@ -330,6 +296,14 @@ void GPURaytracer2::Raytrace(LevelMesh* level)
|
||||||
printf("Ray trace complete\n");
|
printf("Ray trace complete\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 GPURaytracer2::ToUV(const vec3& vert, const Surface* targetSurface)
|
||||||
|
{
|
||||||
|
vec3 localPos = vert - targetSurface->translateWorldToLocal;
|
||||||
|
float u = (1.0f + dot(localPos, targetSurface->projLocalToU)) / (targetSurface->texWidth + 2);
|
||||||
|
float v = (1.0f + dot(localPos, targetSurface->projLocalToV)) / (targetSurface->texHeight + 2);
|
||||||
|
return vec2(u, v);
|
||||||
|
}
|
||||||
|
|
||||||
void GPURaytracer2::CreateVulkanObjects()
|
void GPURaytracer2::CreateVulkanObjects()
|
||||||
{
|
{
|
||||||
submitFence = std::make_unique<VulkanFence>(device.get());
|
submitFence = std::make_unique<VulkanFence>(device.get());
|
||||||
|
|
|
@ -20,8 +20,6 @@ struct PushConstants2
|
||||||
uint32_t LightEnd;
|
uint32_t LightEnd;
|
||||||
int32_t SurfaceIndex;
|
int32_t SurfaceIndex;
|
||||||
int32_t PushPadding1;
|
int32_t PushPadding1;
|
||||||
vec2 TileTL;
|
|
||||||
vec2 TileBR;
|
|
||||||
vec3 LightmapOrigin;
|
vec3 LightmapOrigin;
|
||||||
float PushPadding2;
|
float PushPadding2;
|
||||||
vec3 LightmapStepX;
|
vec3 LightmapStepX;
|
||||||
|
@ -108,6 +106,7 @@ private:
|
||||||
|
|
||||||
std::vector<SurfaceInfo2> CreateSurfaceInfo();
|
std::vector<SurfaceInfo2> CreateSurfaceInfo();
|
||||||
|
|
||||||
|
static vec2 ToUV(const vec3& vert, const Surface* targetSurface);
|
||||||
static bool IsNegativelyOriented(const vec2& v1, const vec2& v2, const vec2& v3);
|
static bool IsNegativelyOriented(const vec2& v1, const vec2& v2, const vec2& v3);
|
||||||
|
|
||||||
LevelMesh* mesh = nullptr;
|
LevelMesh* mesh = nullptr;
|
||||||
|
@ -124,7 +123,7 @@ private:
|
||||||
SceneVertex* sceneVertices = nullptr;
|
SceneVertex* sceneVertices = nullptr;
|
||||||
int sceneVertexPos = 0;
|
int sceneVertexPos = 0;
|
||||||
|
|
||||||
static const int SceneLightBufferSize = 1 * 1024 * 1024;
|
static const int SceneLightBufferSize = 2 * 1024 * 1024;
|
||||||
std::unique_ptr<VulkanBuffer> sceneLightBuffer;
|
std::unique_ptr<VulkanBuffer> sceneLightBuffer;
|
||||||
LightInfo2* sceneLights = nullptr;
|
LightInfo2* sceneLights = nullptr;
|
||||||
int sceneLightPos = 0;
|
int sceneLightPos = 0;
|
||||||
|
@ -176,6 +175,4 @@ private:
|
||||||
std::unique_ptr<VulkanFence> submitFence;
|
std::unique_ptr<VulkanFence> submitFence;
|
||||||
std::unique_ptr<VulkanCommandPool> cmdpool;
|
std::unique_ptr<VulkanCommandPool> cmdpool;
|
||||||
std::unique_ptr<VulkanCommandBuffer> cmdbuffer;
|
std::unique_ptr<VulkanCommandBuffer> cmdbuffer;
|
||||||
|
|
||||||
std::vector<vec2> vertexList;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -113,6 +113,38 @@ LevelMesh::LevelMesh(FLevel &doomMap, int sampleDistance, int textureSize)
|
||||||
BuildSurfaceParams(surfaces[i].get());
|
BuildSurfaceParams(surfaces[i].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Finding smoothing groups...\n\n");
|
||||||
|
|
||||||
|
for (size_t i = 0; i < surfaces.size(); i++)
|
||||||
|
{
|
||||||
|
// Is this surface in the same plane as an existing smoothing group?
|
||||||
|
int smoothingGroupIndex = -1;
|
||||||
|
for (size_t j = 0; j < smoothingGroups.size(); j++)
|
||||||
|
{
|
||||||
|
float direction = std::abs(dot(smoothingGroups[j].Normal(), surfaces[i]->plane.Normal()));
|
||||||
|
if (direction >= 0.9999f && direction <= 1.001f)
|
||||||
|
{
|
||||||
|
float dist = std::abs(smoothingGroups[j].Distance(surfaces[i]->plane.Normal() * surfaces[i]->plane.d));
|
||||||
|
if (dist <= 0.01f)
|
||||||
|
{
|
||||||
|
smoothingGroupIndex = (int)j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Surface is in a new plane. Create a smoothing group for it
|
||||||
|
if (smoothingGroupIndex == -1)
|
||||||
|
{
|
||||||
|
smoothingGroupIndex = smoothingGroups.size();
|
||||||
|
smoothingGroups.push_back(surfaces[i]->plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
surfaces[i]->smoothingGroupIndex = smoothingGroupIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Created %d smoothing groups for %d surfaces\n\n", (int)smoothingGroups.size(), (int)surfaces.size());
|
||||||
|
|
||||||
printf("Building collision data...\n\n");
|
printf("Building collision data...\n\n");
|
||||||
|
|
||||||
Collision = std::make_unique<TriangleMeshShape>(MeshVertices.Data(), MeshVertices.Size(), MeshElements.Data(), MeshElements.Size());
|
Collision = std::make_unique<TriangleMeshShape>(MeshVertices.Data(), MeshVertices.Size(), MeshElements.Data(), MeshElements.Size());
|
||||||
|
@ -160,6 +192,7 @@ void LevelMesh::BuildSurfaceParams(Surface* surface)
|
||||||
|
|
||||||
plane = &surface->plane;
|
plane = &surface->plane;
|
||||||
bounds = GetBoundsFromSurface(surface);
|
bounds = GetBoundsFromSurface(surface);
|
||||||
|
surface->bounds = bounds;
|
||||||
|
|
||||||
if (surface->sampleDimension < 0) surface->sampleDimension = 1;
|
if (surface->sampleDimension < 0) surface->sampleDimension = 1;
|
||||||
surface->sampleDimension = Math::RoundPowerOfTwo(surface->sampleDimension);
|
surface->sampleDimension = Math::RoundPowerOfTwo(surface->sampleDimension);
|
||||||
|
@ -216,24 +249,28 @@ void LevelMesh::BuildSurfaceParams(Surface* surface)
|
||||||
height = (textureHeight - 2);
|
height = (textureHeight - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
surface->translateWorldToLocal = bounds.min;
|
||||||
|
surface->projLocalToU = tCoords[0];
|
||||||
|
surface->projLocalToV = tCoords[1];
|
||||||
|
|
||||||
surface->lightUV.resize(surface->verts.size());
|
surface->lightUV.resize(surface->verts.size());
|
||||||
for (i = 0; i < (int)surface->verts.size(); i++)
|
for (i = 0; i < (int)surface->verts.size(); i++)
|
||||||
{
|
{
|
||||||
vec3 tDelta = surface->verts[i] - bounds.min;
|
vec3 tDelta = surface->verts[i] - surface->translateWorldToLocal;
|
||||||
surface->lightUV[i].x = dot(tDelta, tCoords[0]);
|
surface->lightUV[i].x = dot(tDelta, surface->projLocalToU);
|
||||||
surface->lightUV[i].y = dot(tDelta, tCoords[1]);
|
surface->lightUV[i].y = dot(tDelta, surface->projLocalToV);
|
||||||
}
|
}
|
||||||
|
|
||||||
tOrigin = bounds.min;
|
tOrigin = bounds.min;
|
||||||
|
|
||||||
// project tOrigin and tCoords so they lie on the plane
|
// project tOrigin and tCoords so they lie on the plane
|
||||||
d = (plane->Distance(bounds.min) - plane->d) / plane->Normal()[axis];
|
d = (plane->Distance(bounds.min)) / plane->Normal()[axis];
|
||||||
tOrigin[axis] -= d;
|
tOrigin[axis] -= d;
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
tCoords[i] = normalize(tCoords[i]);
|
tCoords[i] = normalize(tCoords[i]);
|
||||||
d = plane->Distance(tCoords[i]) / plane->Normal()[axis];
|
d = dot(tCoords[i], plane->Normal()) / plane->Normal()[axis];
|
||||||
tCoords[i][axis] -= d;
|
tCoords[i][axis] -= d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ struct Surface
|
||||||
SurfaceType type = ST_UNKNOWN;
|
SurfaceType type = ST_UNKNOWN;
|
||||||
std::vector<vec3> verts;
|
std::vector<vec3> verts;
|
||||||
Plane plane;
|
Plane plane;
|
||||||
|
BBox bounds;
|
||||||
|
|
||||||
// Surface material
|
// Surface material
|
||||||
std::string material;
|
std::string material;
|
||||||
|
@ -84,6 +85,11 @@ struct Surface
|
||||||
vec3 worldStepX = { 0.0f };
|
vec3 worldStepX = { 0.0f };
|
||||||
vec3 worldStepY = { 0.0f };
|
vec3 worldStepY = { 0.0f };
|
||||||
|
|
||||||
|
// Calculate world coordinates to UV coordinates
|
||||||
|
vec3 translateWorldToLocal = { 0.0f };
|
||||||
|
vec3 projLocalToU = { 0.0f };
|
||||||
|
vec3 projLocalToV = { 0.0f };
|
||||||
|
|
||||||
// Output lightmap for the surface
|
// Output lightmap for the surface
|
||||||
int texWidth = 0;
|
int texWidth = 0;
|
||||||
int texHeight = 0;
|
int texHeight = 0;
|
||||||
|
@ -96,6 +102,9 @@ struct Surface
|
||||||
int atlasPageIndex = -1;
|
int atlasPageIndex = -1;
|
||||||
int atlasX = 0;
|
int atlasX = 0;
|
||||||
int atlasY = 0;
|
int atlasY = 0;
|
||||||
|
|
||||||
|
// Smoothing group surface is to be rendered with
|
||||||
|
int smoothingGroupIndex = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LightProbeSample
|
class LightProbeSample
|
||||||
|
@ -121,6 +130,8 @@ public:
|
||||||
|
|
||||||
std::vector<std::unique_ptr<LightmapTexture>> textures;
|
std::vector<std::unique_ptr<LightmapTexture>> textures;
|
||||||
|
|
||||||
|
std::vector<Plane> smoothingGroups;
|
||||||
|
|
||||||
int defaultSamples = 16;
|
int defaultSamples = 16;
|
||||||
int textureWidth = 128;
|
int textureWidth = 128;
|
||||||
int textureHeight = 128;
|
int textureHeight = 128;
|
||||||
|
|
|
@ -129,7 +129,7 @@ vec3 &Plane::Normal()
|
||||||
|
|
||||||
float Plane::Distance(const vec3 &point)
|
float Plane::Distance(const vec3 &point)
|
||||||
{
|
{
|
||||||
return dot(point, Normal());
|
return dot(point, Normal()) - d;
|
||||||
}
|
}
|
||||||
|
|
||||||
Plane &Plane::SetDistance(const vec3 &point)
|
Plane &Plane::SetDistance(const vec3 &point)
|
||||||
|
|
Loading…
Reference in a new issue