Move vertex transform to the GPU

This commit is contained in:
Magnus Norddahl 2023-09-18 02:42:12 +02:00 committed by Christoph Oelckers
parent 472440f073
commit ec94204a28
8 changed files with 116 additions and 101 deletions

View file

@ -205,10 +205,17 @@ void VkLightmap::RenderBakeImage()
LightmapPushConstants pc;
pc.LightStart = firstLight;
pc.LightEnd = firstLight + lightCount;
pc.TileX = selectedSurface.X;
pc.TileY = selectedSurface.Y;
pc.SurfaceIndex = mesh->GetSurfaceIndex(targetSurface);
pc.LightmapOrigin = targetSurface->worldOrigin - targetSurface->worldStepX - targetSurface->worldStepY;
pc.LightmapStepX = targetSurface->worldStepX * viewport.width;
pc.LightmapStepY = targetSurface->worldStepY * viewport.height;
pc.TileWidth = targetSurface->texWidth;
pc.TileHeight = targetSurface->texHeight;
pc.WorldToLocal = targetSurface->translateWorldToLocal;
pc.ProjLocalToU = targetSurface->projLocalToU;
pc.ProjLocalToV = targetSurface->projLocalToV;
fb->GetCommands()->GetTransferCommands()->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapPushConstants), &pc);
SceneVertex* vertex = &vertices.Vertices[firstVertex];
@ -217,15 +224,15 @@ void VkLightmap::RenderBakeImage()
{
for (int idx = 0; idx < vertexCount; idx++)
{
(vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + idx], targetSurface);
(vertex++)->Position = mesh->MeshVertices[surface->startVertIndex + idx];
}
}
else
{
(vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 0], targetSurface);
(vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 2], targetSurface);
(vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 3], targetSurface);
(vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 1], targetSurface);
(vertex++)->Position = mesh->MeshVertices[surface->startVertIndex + 0];
(vertex++)->Position = mesh->MeshVertices[surface->startVertIndex + 2];
(vertex++)->Position = mesh->MeshVertices[surface->startVertIndex + 3];
(vertex++)->Position = mesh->MeshVertices[surface->startVertIndex + 1];
}
fb->GetCommands()->GetTransferCommands()->draw(vertexCount, 1, firstVertex, 0);
@ -290,24 +297,7 @@ void VkLightmap::ResolveBakeImage()
viewport.height = (float)bakeImage.maxY;
cmdbuffer->setViewport(0, 1, &viewport);
LightmapPushConstants pc;
pc.LightStart = 0;
pc.LightEnd = 0;
pc.SurfaceIndex = 0;
pc.LightmapOrigin = FVector3(0.0f, 0.0f, 0.0f);
pc.LightmapStepX = FVector3(0.0f, 0.0f, 0.0f);
pc.LightmapStepY = FVector3(0.0f, 0.0f, 0.0f);
cmdbuffer->pushConstants(resolve.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(LightmapPushConstants), &pc);
int firstVertex = vertices.Pos;
int vertexCount = 4;
vertices.Pos += vertexCount;
SceneVertex* vertex = &vertices.Vertices[firstVertex];
vertex[0].Position = FVector2(0.0f, 0.0f);
vertex[1].Position = FVector2(1.0f, 0.0f);
vertex[2].Position = FVector2(1.0f, 1.0f);
vertex[3].Position = FVector2(0.0f, 1.0f);
cmdbuffer->draw(vertexCount, 1, firstVertex, 0);
cmdbuffer->draw(3, 1, 0, 0);
cmdbuffer->endRenderPass();
}
@ -339,24 +329,7 @@ void VkLightmap::BlurBakeImage()
viewport.height = (float)bakeImage.maxY;
cmdbuffer->setViewport(0, 1, &viewport);
LightmapPushConstants pc;
pc.LightStart = 0;
pc.LightEnd = 0;
pc.SurfaceIndex = 0;
pc.LightmapOrigin = FVector3(0.0f, 0.0f, 0.0f);
pc.LightmapStepX = FVector3(0.0f, 0.0f, 0.0f);
pc.LightmapStepY = FVector3(0.0f, 0.0f, 0.0f);
cmdbuffer->pushConstants(blur.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(LightmapPushConstants), &pc);
int firstVertex = vertices.Pos;
int vertexCount = 4;
vertices.Pos += vertexCount;
SceneVertex* vertex = &vertices.Vertices[firstVertex];
vertex[0].Position = FVector2(0.0f, 0.0f);
vertex[1].Position = FVector2(1.0f, 0.0f);
vertex[2].Position = FVector2(1.0f, 1.0f);
vertex[3].Position = FVector2(0.0f, 1.0f);
cmdbuffer->draw(vertexCount, 1, firstVertex, 0);
cmdbuffer->draw(3, 1, 0, 0);
cmdbuffer->endRenderPass();
}
@ -384,24 +357,7 @@ void VkLightmap::BlurBakeImage()
viewport.height = (float)bakeImage.maxY;
cmdbuffer->setViewport(0, 1, &viewport);
LightmapPushConstants pc;
pc.LightStart = 0;
pc.LightEnd = 0;
pc.SurfaceIndex = 0;
pc.LightmapOrigin = FVector3(0.0f, 0.0f, 0.0f);
pc.LightmapStepX = FVector3(0.0f, 0.0f, 0.0f);
pc.LightmapStepY = FVector3(0.0f, 0.0f, 0.0f);
cmdbuffer->pushConstants(blur.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(LightmapPushConstants), &pc);
int firstVertex = vertices.Pos;
int vertexCount = 4;
vertices.Pos += vertexCount;
SceneVertex* vertex = &vertices.Vertices[firstVertex];
vertex[0].Position = FVector2(0.0f, 0.0f);
vertex[1].Position = FVector2(1.0f, 0.0f);
vertex[2].Position = FVector2(1.0f, 1.0f);
vertex[3].Position = FVector2(0.0f, 1.0f);
cmdbuffer->draw(vertexCount, 1, firstVertex, 0);
cmdbuffer->draw(3, 1, 0, 0);
cmdbuffer->endRenderPass();
}
@ -480,17 +436,24 @@ void VkLightmap::CreateShaders()
traceprefix += "#define USE_RAYQUERY\r\n";
}
shaders.vert = ShaderBuilder()
shaders.vertRaytrace = ShaderBuilder()
.Type(ShaderType::Vertex)
.AddSource("VersionBlock", prefix)
.AddSource("vert.glsl", LoadPrivateShaderLump("shaders/lightmap/vert.glsl").GetChars())
.DebugName("VkLightmap.Vert")
.Create("VkLightmap.Vert", fb->GetDevice());
.AddSource("vert_raytrace.glsl", LoadPrivateShaderLump("shaders/lightmap/vert_raytrace.glsl").GetChars())
.DebugName("VkLightmap.VertRaytrace")
.Create("VkLightmap.VertRaytrace", fb->GetDevice());
shaders.vertScreenquad = ShaderBuilder()
.Type(ShaderType::Vertex)
.AddSource("VersionBlock", prefix)
.AddSource("vert_screenquad.glsl", LoadPrivateShaderLump("shaders/lightmap/vert_screenquad.glsl").GetChars())
.DebugName("VkLightmap.VertScreenquad")
.Create("VkLightmap.VertScreenquad", fb->GetDevice());
shaders.fragRaytrace = ShaderBuilder()
.Type(ShaderType::Fragment)
.AddSource("VersionBlock", traceprefix)
.AddSource("frag.glsl", LoadPrivateShaderLump("shaders/lightmap/frag.glsl").GetChars())
.AddSource("frag.glsl", LoadPrivateShaderLump("shaders/lightmap/frag_raytrace.glsl").GetChars())
.DebugName("VkLightmap.FragRaytrace")
.Create("VkLightmap.FragRaytrace", fb->GetDevice());
@ -579,10 +542,10 @@ void VkLightmap::CreateRaytracePipeline()
raytrace.pipeline = GraphicsPipelineBuilder()
.Layout(raytrace.pipelineLayout.get())
.RenderPass(raytrace.renderPass.get())
.AddVertexShader(shaders.vert.get())
.AddVertexShader(shaders.vertRaytrace.get())
.AddFragmentShader(shaders.fragRaytrace.get())
.AddVertexBufferBinding(0, sizeof(SceneVertex))
.AddVertexAttribute(0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(SceneVertex, Position))
.AddVertexAttribute(0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(SceneVertex, Position))
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN)
.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT)
.RasterizationSamples(VK_SAMPLE_COUNT_4_BIT)
@ -683,11 +646,9 @@ void VkLightmap::CreateResolvePipeline()
resolve.pipeline = GraphicsPipelineBuilder()
.Layout(resolve.pipelineLayout.get())
.RenderPass(resolve.renderPass.get())
.AddVertexShader(shaders.vert.get())
.AddVertexShader(shaders.vertScreenquad.get())
.AddFragmentShader(shaders.fragResolve.get())
.AddVertexBufferBinding(0, sizeof(SceneVertex))
.AddVertexAttribute(0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(SceneVertex, Position))
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN)
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT)
.Viewport(0.0f, 0.0f, 0.0f, 0.0f)
.Scissor(0, 0, 4096, 4096)
@ -741,11 +702,9 @@ void VkLightmap::CreateBlurPipeline()
blur.pipeline[i] = GraphicsPipelineBuilder()
.Layout(blur.pipelineLayout.get())
.RenderPass(blur.renderPass.get())
.AddVertexShader(shaders.vert.get())
.AddVertexShader(shaders.vertScreenquad.get())
.AddFragmentShader(shaders.fragBlur[i].get())
.AddVertexBufferBinding(0, sizeof(SceneVertex))
.AddVertexAttribute(0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(SceneVertex, Position))
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN)
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT)
.Viewport(0.0f, 0.0f, 0.0f, 0.0f)
.Scissor(0, 0, 4096, 4096)

View file

@ -29,6 +29,16 @@ struct LightmapPushConstants
float PushPadding3;
FVector3 LightmapStepY;
float PushPadding4;
FVector3 WorldToLocal;
float PushPadding5;
FVector3 ProjLocalToU;
float PushPadding6;
FVector3 ProjLocalToV;
float PushPadding7;
int32_t TileX;
int32_t TileY;
int32_t TileWidth;
int32_t TileHeight;
};
struct LightmapBakeImage
@ -63,7 +73,7 @@ struct LightmapBakeImage
struct SceneVertex
{
FVector2 Position;
FVector3 Position;
};
struct LightInfo
@ -161,7 +171,8 @@ private:
struct
{
std::unique_ptr<VulkanShader> vert;
std::unique_ptr<VulkanShader> vertRaytrace;
std::unique_ptr<VulkanShader> vertScreenquad;
std::unique_ptr<VulkanShader> fragRaytrace;
std::unique_ptr<VulkanShader> fragResolve;
std::unique_ptr<VulkanShader> fragBlur[2];

View file

@ -1,7 +1,7 @@
layout(set = 0, binding = 0) uniform sampler2D tex;
layout(location = 0) in vec3 worldpos;
layout(location = 0) in vec2 TexCoord;
layout(location = 0) out vec4 fragcolor;
vec4 centerFragColor;

View file

@ -80,6 +80,16 @@ layout(push_constant) uniform PushConstants
float PushPadding3;
vec3 LightmapStepY;
float PushPadding4;
vec3 WorldToLocal;
float PushPadding5;
vec3 ProjLocalToU;
float PushPadding6;
vec3 ProjLocalToV;
float PushPadding7;
int TileX;
int TileY;
int TileWidth;
int TileHeight;
};
layout(location = 0) centroid in vec3 worldpos;

View file

@ -1,7 +1,7 @@
layout(set = 0, binding = 0) uniform sampler2DMS tex;
layout(location = 0) in vec3 worldpos;
layout(location = 0) in vec2 TexCoord;
layout(location = 0) out vec4 fragcolor;
vec4 samplePixel(ivec2 pos, int count)

View file

@ -1,23 +0,0 @@
layout(push_constant) uniform PushConstants
{
uint LightStart;
uint LightEnd;
int SurfaceIndex;
int PushPadding1;
vec3 LightmapOrigin;
float PushPadding2;
vec3 LightmapStepX;
float PushPadding3;
vec3 LightmapStepY;
float PushPadding4;
};
layout(location = 0) in vec2 aPosition;
layout(location = 0) out vec3 worldpos;
void main()
{
worldpos = LightmapOrigin + LightmapStepX * aPosition.x + LightmapStepY * aPosition.y;
gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);
}

View file

@ -0,0 +1,38 @@
layout(push_constant) uniform PushConstants
{
uint LightStart;
uint LightEnd;
int SurfaceIndex;
int PushPadding1;
vec3 LightmapOrigin;
float PushPadding2;
vec3 LightmapStepX;
float PushPadding3;
vec3 LightmapStepY;
float PushPadding4;
vec3 WorldToLocal;
float PushPadding5;
vec3 ProjLocalToU;
float PushPadding6;
vec3 ProjLocalToV;
float PushPadding7;
int TileX;
int TileY;
int TileWidth;
int TileHeight;
};
layout(location = 0) in vec3 aPosition;
layout(location = 0) out vec3 worldpos;
void main()
{
vec3 localPos = aPosition - WorldToLocal;
float u = (1.0f + dot(localPos, ProjLocalToU)) / float(TileWidth + 2);
float v = (1.0f + dot(localPos, ProjLocalToV)) / float(TileHeight + 2);
worldpos = LightmapOrigin + LightmapStepX * u + LightmapStepY * v;
gl_Position = vec4(vec2(u, v) * 2.0 - 1.0, 0.0, 1.0);
}

View file

@ -0,0 +1,20 @@
layout(location = 0) out vec2 TexCoord;
vec2 positions[3] = vec2[](
vec2(-1.0, -1.0),
vec2( 3.0, -1.0),
vec2(-1.0, 3.0)
);
vec2 uvs[3] = vec2[](
vec2(0.0, 0.0),
vec2(2.0, 0.0),
vec2(0.0, 2.0)
);
void main()
{
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
TexCoord = uvs[gl_VertexIndex];
}