Add tile world position information to lightmapper copy pass
This commit is contained in:
parent
8faa4e65bc
commit
1efa5b19cd
7 changed files with 99 additions and 13 deletions
|
|
@ -48,6 +48,14 @@ struct LightmapTile
|
|||
FVector3 ProjLocalToV = { 0.0f, 0.0f, 0.0f };
|
||||
} Transform;
|
||||
|
||||
// Calculate world coordinates from UV coordinates
|
||||
struct
|
||||
{
|
||||
FVector3 WorldOrigin;
|
||||
FVector3 WorldU;
|
||||
FVector3 WorldV;
|
||||
} InverseTransform;
|
||||
|
||||
int UseCount = 0;
|
||||
bool AddedThisFrame = false;
|
||||
|
||||
|
|
@ -180,14 +188,43 @@ struct LightmapTile
|
|||
height = textureSize;
|
||||
}
|
||||
|
||||
Transform.TranslateWorldToLocal.X = uvMin.X * SampleDimension + 0.1f;
|
||||
Transform.TranslateWorldToLocal.Y = uvMin.Y * SampleDimension + 0.1f;
|
||||
Transform.TranslateWorldToLocal.Z = uvMin.Z * SampleDimension + 0.1f;
|
||||
uvMin *= (float)SampleDimension;
|
||||
uvMax *= (float)SampleDimension;
|
||||
|
||||
Transform.TranslateWorldToLocal.X = uvMin.X + 0.1f;
|
||||
Transform.TranslateWorldToLocal.Y = uvMin.Y + 0.1f;
|
||||
Transform.TranslateWorldToLocal.Z = uvMin.Z + 0.1f;
|
||||
|
||||
Transform.ProjLocalToU = tCoords[0];
|
||||
Transform.ProjLocalToV = tCoords[1];
|
||||
|
||||
switch (planeAxis)
|
||||
{
|
||||
default:
|
||||
case AXIS_YZ:
|
||||
InverseTransform.WorldOrigin = PointAtYZ(uvMin.Y, uvMin.Z);
|
||||
InverseTransform.WorldU = PointAtYZ(uvMax.Y, uvMin.Z);
|
||||
InverseTransform.WorldV = PointAtYZ(uvMin.Y, uvMax.Z);
|
||||
break;
|
||||
|
||||
case AXIS_XZ:
|
||||
InverseTransform.WorldOrigin = PointAtXZ(uvMin.X, uvMin.Z);
|
||||
InverseTransform.WorldU = PointAtXZ(uvMax.X, uvMin.Z);
|
||||
InverseTransform.WorldV = PointAtXZ(uvMin.X, uvMax.Z);
|
||||
break;
|
||||
|
||||
case AXIS_XY:
|
||||
InverseTransform.WorldOrigin = PointAtXY(uvMin.X, uvMin.Y);
|
||||
InverseTransform.WorldU = PointAtXY(uvMax.X, uvMin.Y);
|
||||
InverseTransform.WorldV = PointAtXY(uvMin.X, uvMax.Y);
|
||||
break;
|
||||
}
|
||||
|
||||
AtlasLocation.Width = width;
|
||||
AtlasLocation.Height = height;
|
||||
}
|
||||
|
||||
FVector3 PointAtYZ(float y, float z) const { return FVector3(-(Plane.Y * y + Plane.Z * z + Plane.W) / Plane.X, y, z); }
|
||||
FVector3 PointAtXZ(float x, float z) const { return FVector3(x, -(Plane.X * x + Plane.Z * z + Plane.W) / Plane.Y, z); }
|
||||
FVector3 PointAtXY(float x, float y) const { return FVector3(x, y, -(Plane.X * x + Plane.Y * y + Plane.W) / Plane.Z); }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -414,7 +414,10 @@ void VkLightmapper::CopyResult()
|
|||
for (unsigned int i = 0, count = copylists.Size(); i < count; i++)
|
||||
{
|
||||
if (copylists[i].Size() > 0)
|
||||
{
|
||||
barrier0.AddImage(destTexture[i].Light.Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
|
||||
barrier0.AddImage(destTexture[i].Probe.Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
|
||||
}
|
||||
}
|
||||
barrier0.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
|
|
@ -433,20 +436,31 @@ void VkLightmapper::CopyResult()
|
|||
auto& framebuffer = destTexture[i].Light.LMFramebuffer;
|
||||
if (!framebuffer)
|
||||
{
|
||||
auto& view = destTexture[i].Light.LMView;
|
||||
if (!view)
|
||||
auto& lightView = destTexture[i].Light.LMView;
|
||||
if (!lightView)
|
||||
{
|
||||
view = ImageViewBuilder()
|
||||
lightView = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_2D)
|
||||
.Image(destTexture[i].Light.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1, 1)
|
||||
.DebugName("LMView")
|
||||
.DebugName("LMLightView")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
auto& probeView = destTexture[i].Probe.LMView;
|
||||
if (!probeView)
|
||||
{
|
||||
probeView = ImageViewBuilder()
|
||||
.Type(VK_IMAGE_VIEW_TYPE_2D)
|
||||
.Image(destTexture[i].Probe.Image.get(), VK_FORMAT_R16_UINT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1, 1)
|
||||
.DebugName("LMProbeView")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
framebuffer = FramebufferBuilder()
|
||||
.RenderPass(copy.renderPass.get())
|
||||
.Size(destSize, destSize)
|
||||
.AddAttachment(view.get())
|
||||
.AddAttachment(lightView.get())
|
||||
.AddAttachment(probeView.get())
|
||||
.DebugName("LMFramebuffer")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
|
@ -464,6 +478,9 @@ void VkLightmapper::CopyResult()
|
|||
copyinfo->DestPosY = tile->AtlasLocation.Y;
|
||||
copyinfo->TileWidth = tile->AtlasLocation.Width;
|
||||
copyinfo->TileHeight = tile->AtlasLocation.Height;
|
||||
copyinfo->WorldOrigin = tile->InverseTransform.WorldOrigin;
|
||||
copyinfo->WorldU = tile->InverseTransform.WorldU;
|
||||
copyinfo->WorldV = tile->InverseTransform.WorldV;
|
||||
}
|
||||
|
||||
// Draw the tiles. One instance per tile.
|
||||
|
|
@ -499,7 +516,10 @@ void VkLightmapper::CopyResult()
|
|||
for (unsigned int i = 0, count = copylists.Size(); i < count; i++)
|
||||
{
|
||||
if (copylists[i].Size() > 0)
|
||||
{
|
||||
barrier1.AddImage(destTexture[i].Light.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
|
||||
barrier1.AddImage(destTexture[i].Probe.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
|
||||
}
|
||||
}
|
||||
barrier1.Execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
|
|
@ -883,8 +903,16 @@ void VkLightmapper::CreateCopyPipeline()
|
|||
VK_ATTACHMENT_STORE_OP_STORE,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.AddAttachment(
|
||||
VK_FORMAT_R16_UINT,
|
||||
VK_SAMPLE_COUNT_1_BIT,
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
VK_ATTACHMENT_STORE_OP_STORE,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.AddSubpass()
|
||||
.AddSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.AddSubpassColorAttachmentRef(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.AddExternalSubpassDependency(
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
|
|
@ -900,6 +928,8 @@ void VkLightmapper::CreateCopyPipeline()
|
|||
.AddFragmentShader(shaders.fragCopy)
|
||||
.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
|
||||
.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT)
|
||||
.AddColorBlendAttachment(ColorBlendAttachmentBuilder().Create())
|
||||
.AddColorBlendAttachment(ColorBlendAttachmentBuilder().Create())
|
||||
.Viewport(0.0f, 0.0f, 0.0f, 0.0f)
|
||||
.Scissor(0, 0, 4096, 4096)
|
||||
.DebugName("copy.pipeline")
|
||||
|
|
|
|||
|
|
@ -95,10 +95,14 @@ struct CopyTileInfo
|
|||
int TileHeight;
|
||||
int Padding1;
|
||||
int Padding2;
|
||||
FVector3 WorldOrigin;
|
||||
float Padding3;
|
||||
FVector3 WorldU;
|
||||
float Padding4;
|
||||
FVector3 WorldV;
|
||||
float Padding5;
|
||||
};
|
||||
|
||||
static_assert(sizeof(CopyTileInfo) == sizeof(int32_t) * 8);
|
||||
|
||||
class VkLightmapper
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -2,9 +2,15 @@
|
|||
layout(set = 0, binding = 0) uniform sampler2D Tex;
|
||||
|
||||
layout(location = 0) in vec2 TexCoord;
|
||||
layout(location = 1) in vec3 WorldPos;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 1) out uvec4 FragProbe;
|
||||
|
||||
void main()
|
||||
{
|
||||
uint probeIndex = 0;
|
||||
|
||||
FragColor = texture(Tex, TexCoord);
|
||||
FragProbe.x = probeIndex;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,12 @@ struct TileCopy
|
|||
ivec2 DestPos;
|
||||
ivec2 TileSize;
|
||||
int Padding1, Padding2;
|
||||
vec3 WorldOrigin;
|
||||
float Padding3;
|
||||
vec3 WorldU;
|
||||
float Padding4;
|
||||
vec3 WorldV;
|
||||
float Padding5;
|
||||
};
|
||||
|
||||
layout(std430, set = 0, binding = 1) buffer readonly CopyBuffer
|
||||
|
|
@ -21,6 +27,7 @@ layout(std430, set = 0, binding = 1) buffer readonly CopyBuffer
|
|||
};
|
||||
|
||||
layout(location = 0) out vec2 TexCoord;
|
||||
layout(location = 1) out vec3 WorldPos;
|
||||
|
||||
vec2 positions[4] = vec2[](
|
||||
vec2(0.0, 0.0),
|
||||
|
|
@ -38,4 +45,5 @@ void main()
|
|||
|
||||
gl_Position = vec4(dest * 2.0 - 1.0, 0.0, 1.0);
|
||||
TexCoord = src;
|
||||
WorldPos = tile.WorldOrigin + tile.WorldU * uv.x + tile.WorldV * uv.y;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
layout(set = 2, binding = 0) uniform sampler2D textures[];
|
||||
layout(set = 2, binding = 0) uniform samplerCube cubeTextures[];
|
||||
layout(set = 2, binding = 0) uniform usampler2D uintTextures[];
|
||||
|
||||
const int tex = 0;
|
||||
const int texture2 = 1;
|
||||
|
|
|
|||
|
|
@ -176,11 +176,11 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight, float sunlightAt
|
|||
|
||||
vec3 irradiance, prefilteredColor;
|
||||
|
||||
/*if (vLightmapIndex != -1)
|
||||
if (vLightmapIndex != -1)
|
||||
{
|
||||
uvec4 probeIndexes = textureGather(uintTextures[nonuniformEXT(vLightmapIndex + 1)], vLightmap.xy);
|
||||
|
||||
vec2 t = frac(vLightmap.xy);
|
||||
vec2 t = fract(vLightmap.xy);
|
||||
vec2 invt = 1.0 - t;
|
||||
float t00 = invt.x * invt.y;
|
||||
float t10 = t.x * invt.y;
|
||||
|
|
@ -200,7 +200,7 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight, float sunlightAt
|
|||
irradiance = irradiance0 * t00 + irradiance1 * t10 + irradiance2 * t01 + irradiance3 * t11;
|
||||
prefilteredColor = prefilteredColor0 * t00 + prefilteredColor1 * t10 + prefilteredColor2 * t01 + prefilteredColor3 * t11;
|
||||
}
|
||||
else*/
|
||||
else
|
||||
{
|
||||
irradiance = texture(cubeTextures[uLightProbeIndex], N).rgb;
|
||||
prefilteredColor = textureLod(cubeTextures[uLightProbeIndex + 1], R, roughness * MAX_REFLECTION_LOD).rgb;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue