Hook up light tile visibility test

This commit is contained in:
Magnus Norddahl 2024-09-16 01:04:53 +02:00
commit b43f84def6
6 changed files with 36 additions and 26 deletions

View file

@ -699,7 +699,7 @@ public:
}
// Draw level mesh
virtual void DispatchLightTiles() { }
virtual void DispatchLightTiles(const VSMatrix& worldToView, float m5) { }
virtual void DrawLevelMesh(LevelMeshDrawType drawType, bool noFragmentShader) { }
virtual int GetNextQueryIndex() { return 0; }
virtual void BeginQuery() { }

View file

@ -58,11 +58,12 @@ struct LightTilesPushConstants
int additiveCount;
int modulatedCount;
int subtractiveCount;
int padding;
float rcpF;
float rcpFDivAspect;
float twoRcpViewportSizeX;
float twoRcpViewportSizeY;
int padding0;
FVector2 posToViewA;
FVector2 posToViewB;
FVector2 viewportPos;
FVector2 padding1;
VSMatrix worldToView;
};
class VkShaderKey

View file

@ -940,7 +940,7 @@ void VkRenderState::RunZMinMaxPass()
.Execute(cmdbuffer);
}
void VkRenderState::DispatchLightTiles()
void VkRenderState::DispatchLightTiles(const VSMatrix& worldToView, float m5)
{
EndRenderPass();
RunZMinMaxPass();
@ -951,12 +951,24 @@ void VkRenderState::DispatchLightTiles()
.AddBuffer(fb->GetBuffers()->SceneLightTiles.get(), VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_SHADER_WRITE_BIT)
.Execute(cmdbuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
float sceneWidth = (float)fb->GetBuffers()->GetSceneWidth();
float sceneHeight = (float)fb->GetBuffers()->GetSceneHeight();
float aspect = sceneWidth / sceneHeight;
//float tanHalfFovy = tan(fovy * (M_PI / 360.0f));
float tanHalfFovy = 1.0f / m5;
float invFocalLenX = tanHalfFovy * aspect;
float invFocalLenY = tanHalfFovy;
LightTilesPushConstants pushConstants = {};
//auto mesh = fb->GetLevelMesh()->GetMesh();
//pushConstants.normalLightCount = mesh->Mesh.NormalLightCount;
//pushConstants.modulatedLightCount = mesh->Mesh.ModulatedLightCount;
//pushConstants.subtractiveLightCount = mesh->Mesh.SubtractiveLightCount;
pushConstants.posToViewA = { 2.0f * invFocalLenX / sceneWidth, 2.0f * invFocalLenY / sceneHeight };
pushConstants.posToViewB = { -invFocalLenX, -invFocalLenY };
pushConstants.viewportPos = { 0.0f, 0.0f };
pushConstants.worldToView = worldToView;
auto pipelines = fb->GetRenderPassManager();
auto descriptors = fb->GetDescriptorSetManager();
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, pipelines->GetLightTilesPipeline());

View file

@ -57,7 +57,7 @@ public:
void ResetVertices() override;
// Draw level mesh
void DispatchLightTiles() override;
void DispatchLightTiles(const VSMatrix& worldToView, float m5) override;
void DrawLevelMesh(LevelMeshDrawType drawType, bool noFragmentShader) override;
int GetNextQueryIndex() override;
void BeginQuery() override;

View file

@ -443,7 +443,7 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
state.SetColorMask(false);
state.SetCulling(Cull_CW);
state.DrawLevelMesh(LevelMeshDrawType::Opaque, true);
state.DispatchLightTiles();
state.DispatchLightTiles(VPUniforms.mViewMatrix, VPUniforms.mProjectionMatrix.get()[5]);
state.DrawLevelMesh(LevelMeshDrawType::Masked, false); // To do: properly mark wall top/bottom as opaque so we don't need this
if (gl_portals)
{

View file

@ -15,15 +15,17 @@ layout(set = 0, binding = 2) buffer Tiles
vec4 tiles[];
};
layout(push_constant) uniform PushConstants
layout(push_constant) uniform LightTilesPushConstants
{
int additiveCount;
int modulatedCount;
int subtractiveCount;
int padding;
float rcpF;
float rcpFDivAspect;
vec2 twoRcpViewportSize;
int padding0;
vec2 posToViewA;
vec2 posToViewB;
vec2 viewportPos;
vec2 padding1;
mat4 worldToView;
};
struct Tile
@ -57,10 +59,12 @@ void main()
int tileModulatedCount = 0;
int tileSubtractiveCount = 0;
if (isLightVisible(tile, vec3(-316.0, 64.0, 621.0), 200.0))
vec4 testLight = vec4(-316.0, 64.0, 621.0, 200.0);
if (isLightVisible(tile, (worldToView * vec4(testLight.xyz, 1.0)).xyz, testLight.w))
{
vec3 pos = vec3(-316.0, 64.0, 621.0);
float radius = 200.0;
vec3 pos = testLight.xyz;
float radius = testLight.w;
vec3 color = vec3(1.0, 1.0, 1.0);
float shadowIndex = -1025.0;
vec3 spotDir = vec3(0.0);
@ -85,12 +89,9 @@ void main()
bool isLightVisible(Tile tile, vec3 lightPos, float lightRadius)
{
/*
// aabb/sphere test for the light
vec3 e = max(tile.aabbMin - lightPos, 0.0f) + max(lightPos - tile.aabbMax, 0.0f);
return dot(e, e) <= lightRadius * lightRadius;
*/
return true;
}
Tile findTileFrustum(float viewZNear, float viewZFar, uint tileX, uint tileY)
@ -113,9 +114,5 @@ Tile findTileFrustum(float viewZNear, float viewZFar, uint tileX, uint tileY)
vec3 unprojectDirection(vec2 pos)
{
// float f = 1.0f / tan(fovY * 0.5f);
// float rcpF = 1.0f / f;
// float rcpFDivAspect = 1.0f / (f / aspect);
vec2 normalized = vec2(pos * twoRcpViewportSize) - 1.0;
return vec3(normalized.x * rcpFDivAspect, normalized.y * rcpF, 1.0f);
return vec3(posToViewA * (pos - viewportPos) + posToViewB, 1.0f);
}