Merge SurfaceVertex with FFlatVertex and draw the lightmaps

This commit is contained in:
Magnus Norddahl 2023-10-20 04:06:57 +02:00
commit 240d68d7ae
29 changed files with 263 additions and 276 deletions

View file

@ -1,11 +1,11 @@
#pragma once
struct FFlatVertex
struct FFlatVertex // Note: this must always match the SurfaceVertex struct in shaders (std430 layout rules apply)
{
float x, z, y; // world position
float lindex; // lightmap texture index
float u, v; // texture coordinates
float lu, lv; // lightmap texture coordinates
float lindex; // lightmap texture index
void Set(float xx, float zz, float yy, float uu, float vv)
{
@ -22,11 +22,11 @@ struct FFlatVertex
x = xx;
z = zz;
y = yy;
lindex = llindex;
u = uu;
v = vv;
lu = llu;
lv = llv;
lindex = llindex;
}
void SetVertex(float _x, float _y, float _z = 0)
@ -42,4 +42,5 @@ struct FFlatVertex
v = _v;
}
FVector3 fPos() const { return FVector3(x, y, z); }
};

View file

@ -28,7 +28,7 @@
#include <immintrin.h>
#endif
TriangleMeshShape::TriangleMeshShape(const FVector3 *vertices, int num_vertices, const unsigned int *elements, int num_elements)
TriangleMeshShape::TriangleMeshShape(const FFlatVertex *vertices, int num_vertices, const unsigned int *elements, int num_elements)
: vertices(vertices), num_vertices(num_vertices), elements(elements), num_elements(num_elements)
{
int num_triangles = num_elements / 3;
@ -44,7 +44,7 @@ TriangleMeshShape::TriangleMeshShape(const FVector3 *vertices, int num_vertices,
triangles.push_back(i);
int element_index = i * 3;
FVector3 centroid = (vertices[elements[element_index + 0]] + vertices[elements[element_index + 1]] + vertices[elements[element_index + 2]]) * (1.0f / 3.0f);
FVector3 centroid = (vertices[elements[element_index + 0]].fPos() + vertices[elements[element_index + 1]].fPos() + vertices[elements[element_index + 2]].fPos()) * (1.0f / 3.0f);
centroids.push_back(centroid);
}
@ -280,9 +280,9 @@ float TriangleMeshShape::intersect_triangle_ray(TriangleMeshShape *shape, const
FVector3 p[3] =
{
shape->vertices[shape->elements[start_element]],
shape->vertices[shape->elements[start_element + 1]],
shape->vertices[shape->elements[start_element + 2]]
shape->vertices[shape->elements[start_element]].fPos(),
shape->vertices[shape->elements[start_element + 1]].fPos(),
shape->vertices[shape->elements[start_element + 2]].fPos()
};
// MoellerTrumbore ray-triangle intersection algorithm:
@ -356,9 +356,9 @@ float TriangleMeshShape::sweep_intersect_triangle_sphere(TriangleMeshShape *shap
FVector3 p[3] =
{
shape1->vertices[shape1->elements[start_element]],
shape1->vertices[shape1->elements[start_element + 1]],
shape1->vertices[shape1->elements[start_element + 2]]
shape1->vertices[shape1->elements[start_element]].fPos(),
shape1->vertices[shape1->elements[start_element + 1]].fPos(),
shape1->vertices[shape1->elements[start_element + 2]].fPos()
};
FVector3 c = shape2->center;
@ -528,9 +528,9 @@ bool TriangleMeshShape::overlap_triangle_sphere(TriangleMeshShape *shape1, Spher
int element_index = shape1->nodes[shape1_node_index].element_index;
FVector3 P = shape2->center;
FVector3 A = shape1->vertices[shape1->elements[element_index]] - P;
FVector3 B = shape1->vertices[shape1->elements[element_index + 1]] - P;
FVector3 C = shape1->vertices[shape1->elements[element_index + 2]] - P;
FVector3 A = shape1->vertices[shape1->elements[element_index]].fPos() - P;
FVector3 B = shape1->vertices[shape1->elements[element_index + 1]].fPos() - P;
FVector3 C = shape1->vertices[shape1->elements[element_index + 2]].fPos() - P;
float r = shape2->radius;
float rr = r * r;
@ -640,14 +640,14 @@ int TriangleMeshShape::subdivide(int *triangles, int num_triangles, const FVecto
// Find bounding box and median of the triangle centroids
FVector3 median;
FVector3 min, max;
min = vertices[elements[triangles[0] * 3]];
min = vertices[elements[triangles[0] * 3]].fPos();
max = min;
for (int i = 0; i < num_triangles; i++)
{
int element_index = triangles[i] * 3;
for (int j = 0; j < 3; j++)
{
const FVector3 &vertex = vertices[elements[element_index + j]];
const FVector3 &vertex = vertices[elements[element_index + j]].fPos();
min.X = std::min(min.X, vertex.X);
min.Y = std::min(min.Y, vertex.Y);

View file

@ -23,6 +23,7 @@
#pragma once
#include "common/utility/vectors.h"
#include "flatvertices.h"
#include <vector>
#include <cmath>
@ -86,7 +87,7 @@ public:
class TriangleMeshShape
{
public:
TriangleMeshShape(const FVector3 *vertices, int num_vertices, const unsigned int *elements, int num_elements);
TriangleMeshShape(const FFlatVertex *vertices, int num_vertices, const unsigned int *elements, int num_elements);
int get_min_depth() const;
int get_max_depth() const;
@ -121,7 +122,7 @@ public:
int get_root() const { return root; }
private:
const FVector3 *vertices = nullptr;
const FFlatVertex* vertices = nullptr;
const int num_vertices = 0;
const unsigned int *elements = nullptr;
int num_elements = 0;

View file

@ -80,8 +80,6 @@ LevelSubmesh::LevelSubmesh()
MeshVertices.Push({ minval, maxval, maxval });
MeshVertices.Push({ maxval, maxval, maxval });
MeshVertexUVs.Resize(MeshVertices.Size());
for (int i = 0; i < 3 * 4; i++)
MeshElements.Push(i);

View file

@ -9,6 +9,7 @@
#include <memory>
#include <cstring>
#include "textureid.h"
#include "flatvertices.h"
#include <dp_rect_pack.h>
@ -36,7 +37,6 @@ struct LevelMeshSurface
int numVerts = 0;
unsigned int startVertIndex = 0;
unsigned int startUvIndex = 0;
unsigned int startElementIndex = 0;
unsigned int numElements = 0;
FVector4 plane = FVector4(0.0f, 0.0f, 1.0f, 0.0f);
@ -183,8 +183,7 @@ public:
virtual unsigned int GetSurfaceIndex(const LevelMeshSurface* surface) const { return 0xffffffff; }
virtual int GetSurfaceCount() { return 0; }
TArray<FVector3> MeshVertices;
TArray<FVector2> MeshVertexUVs;
TArray<FFlatVertex> MeshVertices;
TArray<uint32_t> MeshElements;
TArray<int> MeshSurfaceIndexes;

View file

@ -13,9 +13,9 @@ void Mesh::Draw(FRenderState& renderstate)
{
static const FVertexBufferAttribute format[] =
{
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) },
{ 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FFlatVertex, lu) },
{ 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FFlatVertex, lu) },
};
mVertexBuffer.reset(screen->CreateVertexBuffer(1, 3, sizeof(FFlatVertex), format));
mVertexBuffer->SetData(mVertices.Size() * sizeof(FFlatVertex), mVertices.Data(), BufferUsageType::Static);

View file

@ -41,10 +41,10 @@ FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe)
{
static const FVertexBufferAttribute format[] =
{
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FModelVertex, x) },
{ 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FModelVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FModelVertex, u) },
{ 0, VATTR_NORMAL, VFmt_Packed_A2R10G10B10, (int)myoffsetof(FModelVertex, packedNormal) },
{ 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FModelVertex, lu) },
{ 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FModelVertex, lu) },
{ 0, VATTR_BONESELECTOR, VFmt_Byte4_UInt, (int)myoffsetof(FModelVertex, boneselector[0])},
{ 0, VATTR_BONEWEIGHT, VFmt_Byte4, (int)myoffsetof(FModelVertex, boneweight[0]) },
{ 1, VATTR_VERTEX2, VFmt_Float3, (int)myoffsetof(FModelVertex, x) },

View file

@ -124,10 +124,10 @@ FSkyVertexBuffer::FSkyVertexBuffer(DFrameBuffer* fb) : fb(fb)
CreateDome();
static const FVertexBufferAttribute format[] = {
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FSkyVertex, x) },
{ 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FSkyVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FSkyVertex, u) },
{ 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(FSkyVertex, color) },
{ 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FSkyVertex, lu) },
{ 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FSkyVertex, lu) },
};
mVertexBuffer = fb->CreateVertexBuffer(1, 4, sizeof(FSkyVertex), format);
mVertexBuffer->SetData(mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], BufferUsageType::Static);

View file

@ -17,7 +17,7 @@ const int skyoffsetfactor = 57;
struct FSkyVertex
{
float x, y, z, u, v, lu, lv, lindex;
float x, y, z, lindex, u, v, lu, lv;
PalEntry color;
void Set(float xx, float zz, float yy, float uu=0, float vv=0, PalEntry col=0xffffffff)

View file

@ -6,10 +6,10 @@
struct FModelVertex
{
float x, y, z; // world position
float lindex; // lightmap texture index
float u, v; // texture coordinates
unsigned packedNormal; // normal vector as GL_INT_2_10_10_10_REV.
float lu, lv; // lightmap texture coordinates
float lindex; // lightmap texture index
uint8_t boneselector[4];
uint8_t boneweight[4];

View file

@ -201,9 +201,9 @@ void VkLightmap::Render()
pc.TextureSize = (float)bakeImageSize;
pc.TileWidth = (float)targetSurface->AtlasTile.Width;
pc.TileHeight = (float)targetSurface->AtlasTile.Height;
pc.WorldToLocal = targetSurface->translateWorldToLocal;
pc.ProjLocalToU = targetSurface->projLocalToU;
pc.ProjLocalToV = targetSurface->projLocalToV;
pc.WorldToLocal = SwapYZ(targetSurface->translateWorldToLocal);
pc.ProjLocalToU = SwapYZ(targetSurface->projLocalToU);
pc.ProjLocalToV = SwapYZ(targetSurface->projLocalToV);
bool buffersFull = false;
@ -229,13 +229,13 @@ void VkLightmap::Render()
for (int i = 0; i < lightCount; i++)
{
const LevelMeshLight* light = &templightlist[i];
lightinfo->Origin = light->Origin;
lightinfo->RelativeOrigin = light->RelativeOrigin;
lightinfo->Origin = SwapYZ(light->Origin);
lightinfo->RelativeOrigin = SwapYZ(light->RelativeOrigin);
lightinfo->Radius = light->Radius;
lightinfo->Intensity = light->Intensity;
lightinfo->InnerAngleCos = light->InnerAngleCos;
lightinfo->OuterAngleCos = light->OuterAngleCos;
lightinfo->SpotDir = light->SpotDir;
lightinfo->SpotDir = SwapYZ(light->SpotDir);
lightinfo->Color = light->Color;
lightinfo++;
}
@ -294,7 +294,7 @@ void VkLightmap::Render()
void VkLightmap::UploadUniforms()
{
Uniforms values = {};
values.SunDir = mesh->SunDirection;
values.SunDir = SwapYZ(mesh->SunDirection);
values.SunColor = mesh->SunColor;
values.SunIntensity = 1.0f;
@ -760,7 +760,7 @@ void VkLightmap::CreateRaytracePipeline()
.RenderPass(raytrace.renderPass.get())
.AddVertexShader(shaders.vertRaytrace.get())
.AddFragmentShader(shaders.fragRaytrace[i].get())
.AddVertexBufferBinding(0, sizeof(SurfaceVertex))
.AddVertexBufferBinding(0, sizeof(FFlatVertex))
.AddVertexAttribute(0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0)
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT)

View file

@ -158,6 +158,8 @@ private:
static FString LoadPublicShaderLump(const char* lumpname);
static ShaderIncludeResult OnInclude(FString headerName, FString includerName, size_t depth, bool system);
FVector3 SwapYZ(const FVector3& v) { return FVector3(v.X, v.Z, v.Y); }
VulkanRenderDevice* fb = nullptr;
LevelMesh* mesh = nullptr;

View file

@ -141,7 +141,7 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly)
for (unsigned int i = start; i < end; i++)
{
const SubmeshBufferLocation& cur = locations[i];
transferBufferSize += cur.Submesh->MeshVertices.Size() * sizeof(SurfaceVertex);
transferBufferSize += cur.Submesh->MeshVertices.Size() * sizeof(FFlatVertex);
transferBufferSize += cur.Submesh->MeshElements.Size() * sizeof(uint32_t);
transferBufferSize += cur.Submesh->Collision->get_nodes().size() * sizeof(CollisionNode);
transferBufferSize += cur.Submesh->MeshSurfaceIndexes.Size() * sizeof(int);
@ -205,13 +205,10 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly)
const SubmeshBufferLocation& cur = locations[i];
auto submesh = cur.Submesh;
SurfaceVertex* vertices = (SurfaceVertex*)(data + datapos);
for (int j = 0, count = submesh->MeshVertices.Size(); j < count; ++j)
*(vertices++) = { { submesh->MeshVertices[j], 1.0f }, submesh->MeshVertexUVs[j], float(j), j + 10000.0f, FVector3(0.0f, 0.0f, -1.0f), 0.0f};
size_t copysize = submesh->MeshVertices.Size() * sizeof(SurfaceVertex);
size_t copysize = submesh->MeshVertices.Size() * sizeof(FFlatVertex);
memcpy(data + datapos, submesh->MeshVertices.Data(), copysize);
if (copysize > 0)
cmdbuffer->copyBuffer(transferBuffer.get(), VertexBuffer.get(), datapos, cur.VertexOffset * sizeof(SurfaceVertex), copysize);
cmdbuffer->copyBuffer(transferBuffer.get(), VertexBuffer.get(), datapos, cur.VertexOffset * sizeof(FFlatVertex), copysize);
datapos += copysize;
}
@ -283,7 +280,7 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly)
LevelMeshSurface* surface = submesh->GetSurface(j);
SurfaceInfo info;
info.Normal = surface->plane.XYZ();
info.Normal = FVector3(surface->plane.X, surface->plane.Z, surface->plane.Y);
info.PortalIndex = surface->portalIndex;
info.SamplingDistance = (float)surface->sampleDimension;
info.Sky = surface->bSky;
@ -371,7 +368,7 @@ void VkRaytrace::CreateBuffers()
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR : 0) |
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
.Size(GetMaxVertexBufferSize() * sizeof(SurfaceVertex))
.Size(GetMaxVertexBufferSize() * sizeof(FFlatVertex))
.DebugName("VertexBuffer")
.Create(fb->GetDevice());
@ -425,7 +422,7 @@ VkRaytrace::BLAS VkRaytrace::CreateBLAS(LevelSubmesh* submesh, bool preferFastBu
accelStructBLDesc.geometry.triangles = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR };
accelStructBLDesc.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
accelStructBLDesc.geometry.triangles.vertexData.deviceAddress = VertexBuffer->GetDeviceAddress();
accelStructBLDesc.geometry.triangles.vertexStride = sizeof(SurfaceVertex);
accelStructBLDesc.geometry.triangles.vertexStride = sizeof(FFlatVertex);
accelStructBLDesc.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
accelStructBLDesc.geometry.triangles.indexData.deviceAddress = IndexBuffer->GetDeviceAddress() + indexOffset * sizeof(uint32_t);
accelStructBLDesc.geometry.triangles.maxVertex = vertexOffset + submesh->MeshVertices.Size() - 1;

View file

@ -37,15 +37,6 @@ struct SurfaceInfo
float Alpha;
};
struct SurfaceVertex
{
FVector4 pos;
FVector2 uv;
float Padding1, Padding2;
FVector3 lightmap;
float Padding3;
};
struct PortalInfo
{
VSMatrix transformation;
@ -125,7 +116,7 @@ private:
std::unique_ptr<VulkanBuffer> NodeBuffer;
TArray<SurfaceVertex> Vertices;
TArray<FFlatVertex> Vertices;
static const int MaxDynamicVertices = 100'000;
static const int MaxDynamicIndexes = 100'000;
static const int MaxDynamicSurfaces = 100'000;

View file

@ -32,9 +32,9 @@ VkRSBuffers::VkRSBuffers(VulkanRenderDevice* fb)
{
static const FVertexBufferAttribute format[] =
{
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) },
{ 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(FFlatVertex, lu) },
{ 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FFlatVertex, lu) },
};
Flatbuffer.VertexFormat = fb->GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(FFlatVertex), format);

View file

@ -657,11 +657,11 @@ void VulkanRenderDevice::DrawLevelMesh(const HWViewpointUniforms& viewpoint)
static const FVertexBufferAttribute format[] =
{
{ 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(SurfaceVertex, pos.X) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(SurfaceVertex, uv.X) },
{ 0, VATTR_LIGHTMAP, VFmt_Float3, (int)myoffsetof(SurfaceVertex, lightmap.X) },
{ 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FFlatVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) },
{ 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FFlatVertex, lu) },
};
int vertexFormatIndex = GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(SurfaceVertex), format);
int vertexFormatIndex = GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(FFlatVertex), format);
VkBuffer vertexBuffers[2] = { GetRaytrace()->GetVertexBuffer()->buffer, GetRaytrace()->GetVertexBuffer()->buffer };
VkDeviceSize vertexBufferOffsets[] = { 0, 0 };
cmdbuffer->bindVertexBuffers(0, 2, vertexBuffers, vertexBufferOffsets);