Skip to content

Commit

Permalink
Vsm point lights (#703)
Browse files Browse the repository at this point in the history
* omni light processing initial

* refactor

* packing omni lights data

* page allocation for omni lights initial

* CI

* omni shadow draw in progress

* virtual omni shadows: rendering

* flip depth-range for omni shadows

* vsm omni shadow in progress

* testing: reduce cube-face resolution

* CI

* enable vsm point-light shading

* fixup

* fixup validation

* variable omni page resolution

* refactor

* fixup

* better vsm omni lighting culling

* separate post-process job for cube-shadow pages

* change bitpacking to support more lights

* zCVobLight: on/off flag; clamp range

* CI

* heuristic to disable garbage/lightmap lights

* fixup

* alternative page allocator (wip)
  • Loading branch information
Try authored Dec 12, 2024
1 parent 24f6df1 commit 54a8c77
Show file tree
Hide file tree
Showing 44 changed files with 1,274 additions and 497 deletions.
39 changes: 15 additions & 24 deletions game/graphics/drawcommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,10 @@ void DrawCommands::updateTasksUniforms() {
i.desc.set(T_HiZ, *scene.hiZ);
} else {
i.desc.set(T_Payload, views[i.viewport].vsmClusters); //unsorted clusters
i.desc.set(T_Lights, *scene.lights);
i.desc.set(T_HiZ, *scene.vsmPageHiZ);
i.desc.set(T_VsmPages, *scene.vsmPageList);
i.desc.set(8, scene.vsmDbg);
i.desc.set(9, scene.vsmDbg);
// i.desc.set(T_PkgOffsets, views[i.viewport].pkgOffsets);
}
}
Expand All @@ -271,7 +272,7 @@ void DrawCommands::updateTasksUniforms() {
v.descPackDraw1.set(4, *scene.vsmPageList);
}

updateVsmUniforms();
updatsSwrUniforms();
}

void DrawCommands::updateCommandUniforms() {
Expand Down Expand Up @@ -349,17 +350,10 @@ void DrawCommands::updateCommandUniforms() {
desc[v].set(L_GDepth, *scene.sceneDepth, smp);
}

if(v==SceneGlobals::V_Vsm && scene.vsmPageDataCs->w()>1) {
// atomic
desc[v].set(L_CmdOffsets, views[v].indirectCmd);
desc[v].set(L_VsmPages, *scene.vsmPageList);
desc[v].set(L_VsmTbl, *scene.vsmPageTbl);
desc[v].set(L_VsmData, *scene.vsmPageDataCs);
}
else if(v==SceneGlobals::V_Vsm) {
// raster
if(v==SceneGlobals::V_Vsm) {
desc[v].set(L_CmdOffsets, views[v].indirectCmd);
desc[v].set(L_VsmPages, *scene.vsmPageList);
desc[v].set(L_Lights, *scene.lights);
}
}

Expand All @@ -368,11 +362,17 @@ void DrawCommands::updateCommandUniforms() {
}
}

updateVsmUniforms();
updatsSwrUniforms();
}

void DrawCommands::updateLigtsUniforms() {
//NOTE: causes dev-idle, need to rework
updateCommandUniforms();
updateTasksUniforms();
}

void DrawCommands::updateVsmUniforms() {
if(Gothic::options().swRenderingPreset==0 && Gothic::options().doVirtualShadow==false)
void DrawCommands::updatsSwrUniforms() {
if(Gothic::options().swRenderingPreset==0)
return;

auto& device = Resources::device();
Expand Down Expand Up @@ -431,15 +431,6 @@ void DrawCommands::updateVsmUniforms() {
}
}

void DrawCommands::prepareUniforms() {
// updateTasksUniforms();
updateCommandUniforms();
}

void DrawCommands::prepareLigtsUniforms() {
updateVsmUniforms();
}

void DrawCommands::updateUniforms(uint8_t fId) {
for(auto& cx:cmd) {
if(cx.isBindless())
Expand Down Expand Up @@ -517,7 +508,7 @@ void DrawCommands::visibilityVsm(Encoder<CommandBuffer>& cmd, uint8_t fId) {
auto* pso = &Shaders::inst().vsmClusterTask;
cmd.setUniforms(*pso, i.desc, &push, sizeof(push));
#if 1
cmd.dispatchThreads(push.meshletCount, size_t(scene.vsmPageTbl->d()));
cmd.dispatchThreads(push.meshletCount, size_t(scene.vsmPageTbl->d() + 1));
#else
cmd.dispatch(push.meshletCount);
#endif
Expand Down
20 changes: 9 additions & 11 deletions game/graphics/drawcommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ class DrawCommands {
uint16_t commandId(const Material& m, Type type, uint32_t bucketId);
void addClusters(uint16_t cmdId, uint32_t meshletCount);

void prepareUniforms();
void prepareLigtsUniforms();

void updateUniforms(uint8_t fId);
void updateTasksUniforms();
void updateCommandUniforms();
void updateLigtsUniforms();

void updatsSwrUniforms();

void visibilityPass(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fId, int pass);
void visibilityVsm(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fId);
Expand All @@ -80,9 +81,10 @@ class DrawCommands {
T_Bucket = 3,
T_Indirect = 4,
T_Clusters = 5,
T_HiZ = 6,
T_VsmPages = 7,
T_CmdOffsets = 8,
T_Lights = 6,
T_HiZ = 7,
T_VsmPages = 8,
T_CmdOffsets = 9,
};

enum UboLinkpackage : uint8_t {
Expand All @@ -103,8 +105,7 @@ class DrawCommands {
L_GDepth = 13,
L_CmdOffsets = 14,
L_VsmPages = L_Shadow0,
L_VsmTbl = L_Shadow1,
L_VsmData = 15,
L_Lights = L_Shadow1,
};

struct IndirectCmd {
Expand Down Expand Up @@ -132,9 +133,6 @@ class DrawCommands {
bool isEnabled() const;
};

void updateCommandUniforms();
void updateVsmUniforms();

VisualObjects& owner;
DrawBuckets& buckets;
DrawClusters& clusters;
Expand Down
90 changes: 20 additions & 70 deletions game/graphics/lightgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

using namespace Tempest;

static float clampRange(float r) {
return std::min(r, 2000.f);
//return r;
}

LightGroup::Light::Light(LightGroup::Light&& oth):owner(oth.owner), id(oth.id) {
oth.owner = nullptr;
}
Expand Down Expand Up @@ -44,14 +49,25 @@ void LightGroup::Light::setPosition(const Vec3& p) {
owner->markAsDurty(id);
}

void LightGroup::Light::setEnabled(bool e) {
if(owner==nullptr)
return;
auto& data = owner->lightSourceDesc[id];
data.setEnabled(e);

auto& ssbo = owner->lightSourceData[id];
ssbo.range = 0;
owner->markAsDurty(id);
}

void LightGroup::Light::setRange(float r) {
if(owner==nullptr)
return;
auto& data = owner->lightSourceDesc[id];
data.setRange(r);

auto& ssbo = owner->lightSourceData[id];
ssbo.range = r;
ssbo.range = data.isEnabled() ? clampRange(r) : 0;
owner->markAsDurty(id);
}

Expand Down Expand Up @@ -98,16 +114,6 @@ LightGroup::LightGroup(const SceneGlobals& scene)
descPatch[i] = device.descriptors(Shaders::inst().patch);
}

static const uint16_t index[] = {
0, 1, 2, 0, 2, 3,
4, 6, 5, 4, 7, 6,
1, 5, 2, 2, 5, 6,
4, 0, 7, 7, 0, 3,
3, 2, 7, 7, 2, 6,
4, 5, 0, 0, 5, 1
};
ibo = device.ibo(index, sizeof(index)/sizeof(index[0]));

try {
auto filename = Gothic::nestedPath({u"_work", u"Data", u"Presets", u"LIGHTPRESETS.ZEN"}, Dir::FT_File);
auto buf = zenkit::Read::from(filename);
Expand Down Expand Up @@ -155,7 +161,7 @@ LightGroup::Light LightGroup::add(const zenkit::LightPreset& vob) {

auto& ssbo = lightSourceData[lx.id];
ssbo.pos = l.position();
ssbo.range = l.range();
ssbo.range = l.isEnabled() ? clampRange(l.range()) : 0;
ssbo.color = l.color();

auto& data = lightSourceDesc[lx.id];
Expand Down Expand Up @@ -289,12 +295,6 @@ void LightGroup::resetDurty() {
std::memset(duryBit.data(), 0, duryBit.size()*sizeof(duryBit[0]));
}

RenderPipeline& LightGroup::shader() const {
if(Gothic::options().doRayQuery)
return Shaders::inst().lightsRq;
return Shaders::inst().lights;
}

const zenkit::LightPreset& LightGroup::findPreset(std::string_view preset) const {
for(auto& i:presets) {
if(i.preset!=preset)
Expand All @@ -314,7 +314,8 @@ void LightGroup::tick(uint64_t time) {
LightSsbo ssbo;
ssbo.pos = light.position();
ssbo.color = light.currentColor();
ssbo.range = light.currentRange();
ssbo.range = light.isEnabled() ? clampRange(light.currentRange()) : 0;

auto& dst = lightSourceData[i];
if(std::memcmp(&dst, &ssbo, sizeof(ssbo))==0)
continue;
Expand All @@ -330,7 +331,6 @@ bool LightGroup::updateLights() {
Resources::recycle(std::move(lightSourceSsbo));
lightSourceSsbo = device.ssbo(lightSourceData);
resetDurty();
allocDescriptorSet();
return true;
}
return false;
Expand Down Expand Up @@ -401,53 +401,3 @@ void LightGroup::prepareGlobals(Tempest::Encoder<Tempest::CommandBuffer>& cmd, u
cmd.setUniforms(Shaders::inst().patch, d);
cmd.dispatch(patchBlock.size());
}

void LightGroup::draw(Encoder<CommandBuffer>& cmd, uint8_t fId) {
static bool light = true;
if(!light)
return;

if(lightSourceSsbo.isEmpty())
return;

auto& p = shader();
cmd.setUniforms(p, desc, &scene.originLwc, sizeof(scene.originLwc));
cmd.draw(nullptr,ibo, 0,ibo.size(), 0,lightSourceData.size());
}

void LightGroup::allocDescriptorSet() {
if(lightSourceSsbo.isEmpty())
return;

Resources::recycle(std::move(desc));

auto& device = Resources::device();
desc = device.descriptors(shader().layout());
prepareUniforms();
prepareRtUniforms();
}

void LightGroup::prepareUniforms() {
if(desc.isEmpty())
return;
desc.set(0, scene.uboGlobal[SceneGlobals::V_Main]);
desc.set(1, *scene.gbufDiffuse, Sampler::nearest());
desc.set(2, *scene.gbufNormals, Sampler::nearest());
desc.set(3, *scene.zbuffer, Sampler::nearest());
desc.set(4, lightSourceSsbo);
}

void LightGroup::prepareRtUniforms() {
if(!Gothic::inst().options().doRayQuery)
return;
if(desc.isEmpty() || scene.rtScene.tlas.isEmpty())
return;
desc.set(6,scene.rtScene.tlas);
if(Resources::device().properties().descriptors.nonUniformIndexing) {
desc.set(7, Sampler::bilinear());
desc.set(8, scene.rtScene.tex);
desc.set(9, scene.rtScene.vbo);
desc.set(10,scene.rtScene.ibo);
desc.set(11,scene.rtScene.rtDesc);
}
}
18 changes: 8 additions & 10 deletions game/graphics/lightgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class LightGroup final {
void setPosition(float x, float y, float z);
void setPosition(const Tempest::Vec3& p);

void setEnabled(bool e);

void setRange (float r);
void setColor (const Tempest::Vec3& c);
void setColor (const std::vector<Tempest::Vec3>& c, float fps, bool smooth);
Expand All @@ -43,17 +45,14 @@ class LightGroup final {
Light add(const zenkit::LightPreset& vob);
Light add(const zenkit::VLight& vob);
Light add(std::string_view preset);
size_t size() const { return lightSourceData.size(); }

void tick(uint64_t time);
bool updateLights();
auto& lightsSsbo() const { return lightSourceSsbo; }

void preFrameUpdate(uint8_t fId);
void prepareGlobals(Tempest::Encoder<Tempest::CommandBuffer> &cmd, uint8_t fId);
void prepareUniforms();
void prepareRtUniforms();

void draw(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fId);

void dbgLights(DbgPainter& p) const;

Expand All @@ -73,16 +72,17 @@ class LightGroup final {
float pading = 0;
};

struct VsmSsbo {
uint32_t mask[6];
};

size_t alloc(bool dynamic);
void free(size_t id);

void markAsDurty(size_t id);
void markAsDurtyNoSync(size_t id);
void resetDurty();

Tempest::RenderPipeline& shader() const;
void allocDescriptorSet();

const zenkit::LightPreset& findPreset(std::string_view preset) const;

const SceneGlobals& scene;
Expand All @@ -94,12 +94,10 @@ class LightGroup final {
std::vector<LightSsbo> lightSourceData;
std::unordered_set<size_t> animatedLights;
std::vector<uint32_t> duryBit;

Tempest::StorageBuffer lightSourceSsbo;
Tempest::DescriptorSet desc;

Tempest::StorageBuffer patchSsbo[Resources::MaxFramesInFlight];
Tempest::DescriptorSet descPatch[Resources::MaxFramesInFlight];

Tempest::IndexBuffer<uint16_t> ibo;
};

12 changes: 10 additions & 2 deletions game/graphics/lightsource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ void LightSource::setColor(const std::vector<glm::u8vec4>& arr, float fps, boo
setColor({static_cast<float>(arr[0].r)/255.f, static_cast<float>(arr[0].g)/255.f, static_cast<float>(arr[0].b)/255.f});
colorAniListFpsInv = 0;
return;
}
}

colorAniList.resize(arr.size());
for(size_t i=0; i<arr.size(); ++i)
colorAniList[i] = {static_cast<float>(arr[i].r)/255.f, static_cast<float>(arr[i].g)/255.f, static_cast<float>(arr[i].b)/255.f};
colorAniListFpsInv = !arr.empty() ? uint64_t(1000.0/fps) : 0;
}
}

void LightSource::setColor(const std::vector<Vec3>& arr, float fps, bool smooth) {
colorSmooth = smooth;
Expand Down Expand Up @@ -101,6 +101,10 @@ void LightSource::setRange(const std::vector<float>& arr, float base, float fps,
}
}

void LightSource::setEnabled(bool e) {
enable = e;
}

void LightSource::update(uint64_t time) {
if(timeOff<time)
time -= timeOff; else
Expand Down Expand Up @@ -137,6 +141,10 @@ bool LightSource::isDynamic() const {
return rangeAniFPSInv!=0 || colorAniListFpsInv!=0;
}

bool LightSource::isEnabled() const {
return enable;
}

void LightSource::setTimeOffset(uint64_t t) {
timeOff = t;
}
Expand Down
Loading

0 comments on commit 54a8c77

Please sign in to comment.