fixed shadowmaps

This commit is contained in:
ecker 2026-05-11 16:41:57 -05:00
parent c62240641a
commit 2e018962ee
20 changed files with 97 additions and 46 deletions

View File

@ -8,9 +8,9 @@
"useLightmaps": false,
"max": 32,
"shadows": {
"enabled": false, // to-do: fix
"enabled": true, // to-do: fix
"update": 4,
"max": 8,
"max": 16,
"samples": 2
},
"bloom": {
@ -118,7 +118,7 @@
"gui": true,
"vsync": true, // vsync on vulkan side rather than engine-side
"hdr": true,
"vxgi": true,
"vxgi": false,
"culling": false,
"bloom": false,
"dof": false,

View File

@ -26,7 +26,7 @@
"bias": {
"constant": 1.25,
"slope": 1.75,
"shader": 0.000005 // 0.000005 //0.000000005
"shader": 0.00005 // 0.000005 //0.000000005
},
"radius": [0.5, 0],
"resolution": 1024,

View File

@ -1,11 +1,11 @@
{
"type": "Object",
"name": "Player: Model",
"ignore": true,
"ignore": false,
"import": "/model.json",
"assets": [
"/player/ben.glb"
// { "filename": "/player/bear/graph.json" }
// "/player/ben.glb"
{ "filename": "/player/bear/graph.json" }
],
"behaviors": [
"PlayerModelBehavior"
@ -22,7 +22,7 @@
},
"metadata": {
"track": true,
"hide": false,
"hide": true,
"graph": {
"debug": {
"print": {

View File

@ -102,6 +102,8 @@ int main(int argc, char** argv){
}
while ( client::ready && uf::ready ) {
++uf::time::frame;
#if UF_EXCEPTIONS
try {
#endif

View File

@ -68,6 +68,7 @@ namespace ext {
bool autoInitializeUniformBuffers = true;
bool autoInitializeUniformUserdatas = false;
uf::stl::unordered_map<uf::stl::string, size_t> shaders;
uf::stl::unordered_map<uf::stl::string, size_t> hashes;
} metadata;
void initialize( Device& device );

View File

@ -430,6 +430,7 @@ namespace ext {
uf::stl::string renderMode = "";
uf::stl::string pipeline = "";
hash_t material = {};
uint32_t renderTarget = 0;
uint32_t subpass = 0;

View File

@ -733,7 +733,7 @@ void UF_API uf::initialize() {
}
void UF_API uf::tick() {
++uf::time::frame;
//++uf::time::frame;
static pod::Thread& threadMain = uf::thread::get(uf::thread::mainThreadName);
#if UF_THREAD_METRICS

View File

@ -201,8 +201,6 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
{filenames.vertex, uf::renderer::enums::Shader::VERTEX},
{filenames.fragment, uf::renderer::enums::Shader::FRAGMENT},
});
#if UF_USE_VULKAN
{
auto& shader = graphic.material.getShader("vertex");

View File

@ -75,7 +75,7 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
}
camera.setProjection( uf::matrix::perspective( fov, raidou, range.x, range.y ) );
}
// camera.update(true);
camera.update(true);
}
// sloppy
@ -668,7 +668,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
}
}
#endif
// camera.update(true);
camera.update(true);
#if UF_ENTITY_METADATA_USE_JSON
metadata.serialize(self, metadataJson);

View File

@ -51,12 +51,12 @@ void ext::PlayerModelBehavior::tick( uf::Object& self ) {
this->process([&](uf::Entity* entity){
if ( !entity->hasComponent<uf::Graphic>() ) return;
auto& graphic = entity->getComponent<uf::Graphic>();
if ( !graphic.initialized ) return;
auto& descriptorSet = graphic.getDescriptorSet();
descriptorSet.metadata.process = !metadata.hide;
metadata.set = true;
uf::renderer::states::rebuild = true;
});
metadata.set = true;
uf::renderer::states::rebuild = true;
}
void ext::PlayerModelBehavior::render( uf::Object& self ){}

View File

@ -235,7 +235,7 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
}
if ( metadata.renderer.full ) {
/* Update lights */ {
ext::ExtSceneBehavior::bindBuffers( *this, graphic, "ray:gen", uf::renderer::settings::pipelines::names::rt );
ext::ExtSceneBehavior::bindBuffers( *this, graphic, "", "ray:gen", uf::renderer::settings::pipelines::names::rt );
}
if ( !metadata.renderer.bound ) return;
#if !UF_USE_EXTERNAL_IMAGE

View File

@ -458,7 +458,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
auto/*&*/ graph = this->getGraph();
auto& controller = this->getController();
// auto& camera = controller.getComponent<uf::Camera>();
auto& camera = this->getCamera( controller );
// auto& camera = this->getCamera( controller );
auto& controllerMetadata = controller.getComponent<uf::Serializer>();
auto& controllerTransform = controller.getComponent<pod::Transform<>>();
auto& metadata = this->getComponent<ext::ExtSceneBehavior::Metadata>();
@ -524,8 +524,6 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
auto& storage = uf::graph::globalStorage ? uf::graph::storage : this->getComponent<pod::Graph::Storage>();
auto/*&*/ graph = this->getGraph();
auto& controller = this->getController();
// auto& camera = controller.getComponent<uf::Camera>();
auto& camera = this->getCamera( controller );
auto& controllerMetadata = controller.getComponent<uf::Serializer>();
auto& controllerTransform = controller.getComponent<pod::Transform<>>();
auto& metadata = this->getComponent<ext::ExtSceneBehavior::Metadata>();
@ -919,9 +917,13 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali
void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string& renderModeName, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) {
auto& renderMode = uf::renderer::getRenderMode(renderModeName, true);
bindBuffers( self, renderMode.getBlitter(), shaderType, shaderPipeline );
bindBuffers( self, renderMode.getBlitter(), renderMode, shaderType, shaderPipeline );
}
void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic& graphic, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) {
void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic& graphic, const uf::stl::string& renderModeName, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) {
auto& renderMode = uf::renderer::getRenderMode(renderModeName, true);
bindBuffers( self, graphic, renderMode, shaderType, shaderPipeline );
}
void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic& graphic, uf::renderer::RenderMode& renderMode, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) {
auto/*&*/ graph = this->getGraph();
auto& controller = this->getController();
// auto& camera = controller.getComponent<uf::Camera>();
@ -1246,6 +1248,8 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
}
if ( shouldUpdate ) {
// graphic.updatePipelines();
graphic.update();
renderMode.rebuild = true;
metadata.shader.invalidated = false;
}

View File

@ -83,7 +83,9 @@ namespace ext {
} framebuffer;
);
void bindBuffers( uf::Object&, const uf::stl::string& = "", const uf::stl::string& = "fragment", const uf::stl::string& = "deferred" );
void bindBuffers( uf::Object&, uf::renderer::Graphic&, const uf::stl::string& = "fragment", const uf::stl::string& = "deferred" );
void bindBuffers( uf::Object&, const uf::stl::string&, const uf::stl::string&, const uf::stl::string& );
void bindBuffers( uf::Object&, uf::renderer::Graphic&, const uf::stl::string&, const uf::stl::string&, const uf::stl::string& );
void bindBuffers( uf::Object&, uf::renderer::Graphic&, uf::renderer::RenderMode&, const uf::stl::string& = "compute", const uf::stl::string& = "deferred" );
}
}

View File

@ -25,7 +25,10 @@ namespace {
auto& animation = storage.animations.map[name];
UF_ASSERT( animation.path != "" );
//UF_ASSERT( animation.path != "" );
if ( animation.path == "" ) {
return;
}
uf::Serializer json;
json.readFromFile( animation.path );

View File

@ -1511,8 +1511,6 @@ void uf::graph::render( pod::Graph::Storage& storage ) {
}
#endif
// if ( controller.getName() == "Player" ) UF_MSG_DEBUG("frame={}, camera={}, renderMode={}, {}", uf::time::frame, uf::matrix::toString( viewport.matrices[0].view ), renderMode->getName(), renderMode->getType() );
storage.buffers.camera.update( (const void*) &viewport, sizeof(pod::Camera::Viewports) );
#if UF_USE_VULKAN

View File

@ -64,7 +64,7 @@ const uf::Entity& uf::Scene::getController() const {
return scene.getController();
}
uf::Camera& uf::Scene::getCamera(uf::Entity& controller) {
uf::Camera& uf::Scene::getCamera( uf::Entity& controller ) {
// ???
/*
if ( auto currentRenderMode = uf::renderer::getCurrentRenderMode(); currentRenderMode && !currentRenderMode->getName().empty() ) {
@ -75,18 +75,21 @@ uf::Camera& uf::Scene::getCamera(uf::Entity& controller) {
auto& metadata = this->getComponent<uf::SceneBehavior::Metadata>();
#endif
auto uid = controller.getUid();
auto& cachedCamera = metadata.cache.cameras[uid].camera;
auto& lastFrame = metadata.cache.cameras[uid].lastFrame;
auto& cache = metadata.cache.cameras[uid];
auto& cachedCamera = cache.camera;
auto& lastFrame = cache.lastFrame;
if ( lastFrame != uf::time::frame ) {
auto& sourceCamera = controller.getComponent<uf::Camera>();
cachedCamera.setTransform(uf::transform::flatten(sourceCamera.getTransform()));
// update if camera wasn't already updated
//sourceCamera.update(true);
// copy all matrices
for ( auto i = 0; i < uf::camera::maxViews; ++i ) {
cachedCamera.setView(sourceCamera.getView(i), i);
cachedCamera.setProjection(sourceCamera.getProjection(i), i);
}
cachedCamera.update(true);
// flatten the transform in the event the parent transform updates later
cachedCamera.setTransform(uf::transform::flatten(cachedCamera.getTransform()));
lastFrame = uf::time::frame;
}
return cachedCamera;
@ -104,8 +107,9 @@ void uf::Scene::invalidateGraph() {
auto& metadata = this->getComponent<uf::SceneBehavior::Metadata>();
#endif
metadata.invalidationQueued = true;
/*
metadata.cache.controllers.clear();
metadata.cache.cameras.clear();
/*
metadata.tasks.serial.clear();
metadata.tasks.parallel.clear();

View File

@ -12,6 +12,8 @@
#include <fstream>
#include <regex>
#define USE_SHARED_PIPELINES 0
#define VK_DEBUG_VALIDATION_MESSAGE(...)\
// VK_VALIDATION_MESSAGE(x);
@ -38,6 +40,8 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic ) {
return this->initialize( graphic, graphic.descriptor );
}
void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDescriptor& descriptor ) {
if ( pipeline != VK_NULL_HANDLE ) return;
this->device = graphic.device;
this->descriptor = descriptor;
Device& device = *graphic.device;
@ -1057,6 +1061,8 @@ void ext::vulkan::Material::attachShader( const uf::stl::string& filename, VkSha
metadata.json["shaders"][pipeline][type]["index"] = shaders.size() - 1;
metadata.json["shaders"][pipeline][type]["filename"] = filename;
metadata.shaders[pipeline+":"+type] = shaders.size() - 1;
uf::hash( metadata.hashes[pipeline], filename );
}
void ext::vulkan::Material::initializeShaders( const uf::stl::vector<std::pair<uf::stl::string, VkShaderStageFlagBits>>& layout, const uf::stl::string& pipeline ) {
shaders.clear(); shaders.reserve( layout.size() );
@ -1101,6 +1107,8 @@ void ext::vulkan::Graphic::initialize( const GraphicDescriptor& descriptor ) {
update( descriptor );
}
void ext::vulkan::Graphic::update() {
// update descriptor
this->descriptor.material = material.metadata.hashes[descriptor.pipeline];
update( this->descriptor );
}
void ext::vulkan::Graphic::update( const GraphicDescriptor& descriptor ) {
@ -1114,7 +1122,11 @@ void ext::vulkan::Graphic::initializePipeline() {
initializePipeline( this->descriptor );
}
ext::vulkan::Pipeline& ext::vulkan::Graphic::initializePipeline( const GraphicDescriptor& descriptor ) {
#if USE_SHARED_PIPELINES
auto& pipeline = Pipeline::pipelines[descriptor];
#else
auto& pipeline = pipelines[descriptor];
#endif
pipeline.initialize(*this, descriptor);
return pipeline;
}
@ -1828,7 +1840,11 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
}
}
bool ext::vulkan::Graphic::hasPipeline( const GraphicDescriptor& descriptor ) const {
#if USE_SHARED_PIPELINES
return Pipeline::pipelines.count( descriptor ) > 0;
#else
return pipelines.count( descriptor ) > 0;
#endif
}
ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline() {
return getPipeline( descriptor );
@ -1838,11 +1854,19 @@ const ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline() const {
}
ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( const GraphicDescriptor& descriptor ) {
if ( !hasPipeline(descriptor) ) return initializePipeline( descriptor );
#if USE_SHARED_PIPELINES
return Pipeline::pipelines[descriptor];
#else
return pipelines[descriptor];
#endif
}
const ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( const GraphicDescriptor& descriptor ) const {
if ( !hasPipeline(descriptor) ) UF_EXCEPTION("does not have pipeline");
#if USE_SHARED_PIPELINES
return Pipeline::pipelines.at(descriptor);
#else
return pipelines.at(descriptor);
#endif
}
bool ext::vulkan::Graphic::hasDescriptorSet( const GraphicDescriptor& descriptor ) const {
return descriptorSets.count( descriptor ) > 0;
@ -1852,8 +1876,12 @@ void ext::vulkan::Graphic::initializeDescriptorSet() {
initializeDescriptorSet( this->descriptor );
}
ext::vulkan::DescriptorSet& ext::vulkan::Graphic::initializeDescriptorSet( const GraphicDescriptor& descriptor ) {
auto& pipeline = getPipeline();
auto& descriptorSet = descriptorSets[descriptor];
// ensure pipeline exists (because we're passing this as const)
pipeline.initialize(*this, descriptor);
descriptorSet.initialize(*this, descriptor);
descriptorSet.update(*this, descriptor);
@ -1879,12 +1907,17 @@ void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, size_t pass, s
}
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, const GraphicDescriptor& descriptor, size_t pass, size_t draw, size_t offset ) const {
if ( !process ) return;
if ( !this->hasPipeline( descriptor ) ) {
//UF_MSG_DEBUG("{} has no valid pipeline ({}:{}:{})", (void*) this, descriptor.renderMode, descriptor.renderTarget, descriptor.pipeline);
#if USE_SHARED_PIPELINES
if ( Pipeline::pipelines.count( descriptor ) == 0 ) {
Pipeline::pipelines[descriptor].initialize(*this, descriptor);
}
#endif
if ( !hasPipeline( descriptor ) ) {
// UF_MSG_DEBUG("{} has no valid pipeline ({}:{}:{})", (void*) this, descriptor.renderMode, descriptor.renderTarget, descriptor.pipeline);
return;
}
if ( !this->hasDescriptorSet( descriptor ) ) {
//UF_MSG_DEBUG("{} has no valid descriptor set ({}:{}:{})", (void*) this, descriptor.renderMode, descriptor.renderTarget, descriptor.pipeline);
if ( !hasDescriptorSet( descriptor ) ) {
// UF_MSG_DEBUG("{} has no valid descriptor set ({}:{}:{})", (void*) this, descriptor.renderMode, descriptor.renderTarget, descriptor.pipeline);
return;
}
@ -2063,7 +2096,7 @@ void ext::vulkan::GraphicDescriptor::parse( ext::json::Value& metadata ) {
}
ext::vulkan::GraphicDescriptor::hash_t ext::vulkan::GraphicDescriptor::hash() const {
size_t seed{};
uf::hash( seed, aux, subpass, renderMode, renderTarget, pipeline, topology, cullMode, fill, lineWidth, frontFace, depth.test, depth.write, depth.operation, depth.bias.enable, depth.bias.constant, depth.bias.slope, depth.bias.clamp );
uf::hash( seed, aux, subpass, renderMode, renderTarget, material, pipeline, topology, cullMode, fill, lineWidth, frontFace, depth.test, depth.write, depth.operation, depth.bias.enable, depth.bias.constant, depth.bias.slope, depth.bias.clamp );
return seed;
}

View File

@ -494,11 +494,14 @@ void ext::vulkan::initialize( bool soft ) {
}
void ext::vulkan::tick() {
// ext::vulkan::mutex.lock();
if ( ext::vulkan::states::resized || ext::vulkan::settings::experimental::rebuildOnTickBegin ) {
synchronize(0b11);
if ( ext::vulkan::states::resized ) {
// synchronize(0b11);
ext::vulkan::states::rebuild = true;
::skip = true;
}
if ( ext::vulkan::settings::experimental::rebuildOnTickBegin ) {
ext::vulkan::states::rebuild = true;
}
ext::fsr::tick();

View File

@ -44,7 +44,7 @@ void uf::camera::update( pod::Camera& camera, bool override ) {
#if UF_USE_OPENVR
if ( this->m_pod.stereoscopic && ext::openvr::context ) {
camera.transform.orientation = uf::quaternion::identity();
pod::Matrix4t<> view = uf::matrix::inverse( uf::transform::model( camera.transform, false, 1 ) );
pod::Matrix4t<> view = uf::matrix::inverse( uf::transform::model( camera.transform ) );
camera.transform.orientation = ext::openvr::hmdQuaternion();
uf::camera::view( camera, ext::openvr::hmdViewMatrix(vr::Eye_Left, view ), 0 );
@ -52,7 +52,7 @@ void uf::camera::update( pod::Camera& camera, bool override ) {
} else
#endif
{
pod::Matrix4t<> view = uf::matrix::inverse( uf::transform::model( camera.transform, false, 1 ) );
pod::Matrix4t<> view = uf::matrix::inverse( uf::transform::model( camera.transform ) );
uf::camera::view( camera, view );
}
}

View File

@ -131,13 +131,14 @@ void uf::physics::step( pod::World& world, float dt ) {
if ( uf::physics::settings.warmupSolver ) impl::prepareManifoldCache( uf::physics::settings.manifoldsCache, islands, bodies );
// iterate islands
#pragma omp parallel for schedule(dynamic)
for ( auto& island : islands ) {
//#pragma omp parallel for schedule(dynamic)
auto tasks = uf::thread::schedule(true);
for ( auto& island : islands ) tasks.queue([&]{
STATIC_THREAD_LOCAL(uf::stl::vector<pod::Manifold>, manifolds);
manifolds.reserve(uf::physics::settings.reserveCount);
// sleeping island, skip (asleep islands shouldn't ever be in here)
if ( !island.awake ) continue;
if ( !island.awake ) return;
// iterate overlap pairs
for ( auto& [ ia, ib ] : island.pairs ) {
@ -197,7 +198,8 @@ void uf::physics::step( pod::World& world, float dt ) {
if ( uf::physics::settings.warmupSolver ) {
impl::updateManifoldCache( manifolds, uf::physics::settings.manifoldsCache );
}
}
});
uf::thread::execute( tasks );
if ( uf::physics::settings.warmupSolver ) impl::pruneManifoldCache( uf::physics::settings.manifoldsCache );