Commit for 2022.05.30 21-53-42.7z

This commit is contained in:
mrq 2022-05-30 21:53:00 -05:00
parent 22d18c953c
commit 27980e0de9
33 changed files with 483 additions and 103 deletions

View File

@ -1,7 +1,7 @@
{
"engine": {
"scenes": {
"start": "McDonalds",
"start": "SH2_McDonalds",
"meshes": { "interleave": true },
"matrix": { "reverseInfinite": true },
"lights": {

View File

@ -23,7 +23,10 @@
"precision": 4,
"combined": false,
"encode buffers": true,
"unwrap": true
"unwrap": true,
"mesh": {
// "print": true
}
},
"baking": {
"enabled": false,
@ -32,18 +35,21 @@
"layers": 1,
"trigger": { "mode": "rendered", "quit": true },
// "trigger": { "mode": "key", "value": "B" },
"output": "./lightmap.%i.png"
},
"-grid": {
"/^worldspawn/": {
"size": [6,6,6],
// "epsilon": 0.01,
"cleanup": true,
"print": true
"output": "./lightmap.%i.png",
"settings": {
"useInputMeshUvs": true,
"maxIterations": 8,
// "maxChartSize": 0,
// "padding": 0,
// "texelsPerUnit": 0,
"bilinear": true,
"blockAlign": true,
"bruteForce": true,
// "rotateChartsToAxis": false,
"rotateCharts": true
}
},
// "lightmap": "./lightmap.%i.min.png",
// "lightmap": "./lightmap.%i.png",
// "filter": "NEAREST",
"flags": {
"ATLAS": false,

View File

@ -0,0 +1,31 @@
{
"import": "/model.json",
"assets": [
// { "filename": "./models/gm_construct.glb" }
{ "filename": "./models/gm_construct/graph.json.gz" }
],
"metadata": {
"model": {
"lightmap": true,
"baking": {
"enabled": false,
"resolution": 1024,
"settings": {
// "useInputMeshUvs": false
}
},
"cull mode": "none",
"tags": {
"/^worldspawn/": {
"physics": { "type": "mesh", "static": true },
"grid": { "size": [5,2,5], "epsilon": 1.0, "cleanup": true, "print": true }
},
"info_player_spawn": {
"action": "attach",
"filename": "./player.json",
"preserve orientation": true
}
}
}
}
}

View File

@ -0,0 +1,32 @@
{
"name": "Gui: Loading",
"type": "Object",
"behaviors": [
"GuiBehavior"
],
"assets": [
{ "filename": "./gm_construct.json", "delay": 0 }
],
"ignore": false,
"transform": {
"position": [ -0.830591, -0.699509, 0 ],
"rotation": {
"axis": [ 1, 0, 0 ],
"angle": 0
},
"scale": [ 0.258737, 0.115371, 1 ]
},
"metadata": {
"uv": [ 0, 0, 1, 1 ],
"color": [ 1, 1, 1, 0.1 ],
"location": "",
"scaling": "relative",
"text settings": {
"stroke": [ 1, 0.749, 0.368, 1 ],
"color": [ 1, 0.749, 0.368, 1 ],
"string": "Loading...",
"string1": "コマンド"
}
}
}

View File

@ -0,0 +1,19 @@
{
"import": "/player.json",
"assets": [
// { "filename": "/gui/hud/hud.json", "delay": 0 }
],
"metadata": {
"overlay": {
"floating": true
},
"collider": true,
"light": {
"should": false,
"color": [1, 1, 1],
"position": [ 0, 2.5, 0 ],
"power": 1,
"radius": [0.001, 32]
}
}
}

View File

@ -0,0 +1,51 @@
{
"import": "/scene.json",
"assets": [
"./loading.json"
],
"system": {
"hot reload": {
"enabled": true
},
"renderer": {
"clear values": [
[ 0, 0, 0, 0 ]
],
"shader": {
"mode": 1,
"scalar": 16,
"parameters": [ 0, 0, 0, "time" ]
}
}
},
"metadata": {
"menus": {
"pause": "/gui/pause/menu.json"
},
"light": {
"exposure": 1.0,
"gamma": 1.0,
"ambient": [ 0.15, 0.15, 0.15 ],
"fog": {
"color": [ 0.5, 0.5, 0.5 ],
"range": [ 64, 256 ],
"step scale": 2,
"absorbtion": 0.07,
"density": {
"threshold": 0.35,
"multiplier": 5.0,
"scale": 25.0,
"offset": [0.2, 0, 1],
"timescale": 8
}
},
"should": true,
"shadows": true
},
"noise": {
"size": [ 32, 32, 32 ]
}
}
}

View File

@ -3,19 +3,21 @@
"assets": [
// { "filename": "./static.json", "delay": 8 },
// { "filename": "./models/mcdonalds.glb", "delay": 0, "single threaded": false }
// { "filename": "./models/mcdonalds/graph.json", "delay": 0, "single threaded": false, "category": "models" }
{ "filename": "./models/mcdonalds/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/mcdonalds.glb" }
{ "filename": "./models/mcdonalds/graph.json.gz" }
// { "filename": "./models/mini_mcd.glb", "delay": 0, "single threaded": false }
// { "filename": "./models/mini_mcd/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/mini_mcd.glb" }
// { "filename": "./models/mini_mcd/graph.json.gz" }
],
"metadata": {
"model": {
"lightmap": true,
"baking": {
"enabled": true,
"resolution": 2048
"enabled": false,
"resolution": 2048,
"settings": {
"useInputMeshUvs": false
}
},
"cull mode": "none",
"tags": {

View File

@ -34,10 +34,10 @@
"exposure": 1.0,
"gamma": 1.0,
"brightnessThreshold": 1.2,
// "ambient": [ 0.1, 0.1, 0.1 ],
"ambient": [ 0, 0, 0 ],
"ambient": [ 0.1, 0.1, 0.1 ],
// "ambient": [ 1.0, 1.0, 1.0 ],
"fog-": {
"fog": {
"color": [ 0.5, 0.5, 0.5 ],
"range": [ 16, 32 ],
"step scale": 2,

View File

@ -6,5 +6,14 @@
"behaviors": [
"SceneBehavior",
"ExtSceneBehavior"
]
],
"metadata": {
// sky, and not skybox, so i can supply parameters for global lighting
"sky": {
// sky.box.filename, so i can add in additional parameters, for example, using it as a render target
"box": {
"filename": "/skybox/%d.png"
}
}
}
}

View File

@ -3,30 +3,29 @@
"assets": [
// { "filename": "./static.json", "delay": 8 },
{ "filename": "./models/sh_mcd.glb", "delay": 0, "single threaded": false }
// { "filename": "./models/sh_mcd/graph.json", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/sh_mcd/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/sh_mcd.glb" }
{ "filename": "./models/sh_mcd/graph.json.gz" }
],
"metadata": {
"model": {
"cull mode": "none",
"alpha mode": "BLEND",
"grid": {
"/^worldspawn/": {
"size": [4,4,4],
// "epsilon": 0.01,
"cleanup": true,
"print": true
},
"/^worldspawn_sh2/": {
"size": [32,32,32],
// "epsilon": 0.01,
"cleanup": true,
"print": true
"lightmap": true,
"baking": {
"enabled": false,
"resolution": 1024,
"settings": {
"useInputMeshUvs": false
}
},
"tags": {
"worldspawn": { "physics": { "type": "mesh", "static": true } },
"/^worldspawn/": {
"physics": { "type": "mesh", "static": true },
"grid": { "size": [3,1,3], "epsilon": 1.0, "cleanup": true, "print": true }
},
"/^cb$/": {
"grid": { "size": [12,1,12], "epsilon": 1.0, "cleanup": true, "print": true }
},
// "worldspawn_sh2": { "physics": { "type": "mesh", "static": true } },
"info_player_spawn": { "action": "attach", "filename": "./player.json", "preserve orientation": true },

View File

@ -28,7 +28,7 @@ vec4 voxelTrace( inout Ray ray, float aperture, float maxDistance ) {
const float tStart = rayBoxInfoA.x;
const float tEnd = maxDistance > 0 ? min(maxDistance, rayBoxInfoB.y) : rayBoxInfoB.y;
const float tDelta = voxelInfo.radianceSizeRecip * granularityRecip;
const float tDelta = voxelInfo.radianceSizeRecip * granularityRecip * 1.5;
// marcher
ray.distance = tStart;
ray.position = vec3(0);

View File

@ -49,7 +49,7 @@ namespace uf {
template<typename T>
void queueHook( const uf::stl::string&, const T&, float = 0 );
uf::stl::string grabURI( const uf::stl::string& filename, const uf::stl::string& root = "" );
uf::stl::string resolveURI( const uf::stl::string& filename, const uf::stl::string& root = "" );
};
}

View File

@ -26,6 +26,12 @@ namespace ext {
uf::stl::vector<uf::stl::string> pipelines;
uf::stl::vector<uint8_t> outputs;
struct {
float frequency = 0.0f;
float timer = 0.0f;
bool execute = true;
} limiter;
uint8_t subpasses = 1;
uint8_t samples = 1;
uint8_t eyes = 1;
@ -42,6 +48,16 @@ namespace ext {
std::thread::id mostRecentCommandPoolId;
uf::ThreadUnique<commands_container_t> commands;
constexpr static int32_t CALLBACK_BEGIN = -1;
constexpr static int32_t CALLBACK_END = -2;
constexpr static int32_t EXECUTE_BEGIN = -3;
constexpr static int32_t EXECUTE_END = -4;
typedef std::function<void(VkCommandBuffer)> callback_t;
uf::stl::unordered_map<int32_t, callback_t> commandBufferCallbacks;
void bindCallback( int32_t, const callback_t& );
virtual ~RenderMode();
// RAII
virtual const uf::stl::string getName() const;

View File

@ -6,7 +6,8 @@ namespace ext {
namespace vulkan {
struct UF_API BaseRenderMode : RenderMode {
// virtual ~RenderMode();
// RAII
//
virtual const uf::stl::string getType() const;
virtual void initialize( Device& device );

View File

@ -8,7 +8,7 @@ namespace ext {
struct UF_API ComputeRenderMode : public ext::vulkan::RenderMode {
ext::vulkan::Graphic blitter, compute;
// RAII
//
virtual const uf::stl::string getType() const;
virtual const size_t blitters() const;
virtual ext::vulkan::Graphic* getBlitter(size_t = 0);

View File

@ -7,8 +7,7 @@ namespace ext {
namespace vulkan {
struct UF_API DeferredRenderMode : public ext::vulkan::RenderMode {
ext::vulkan::Graphic blitter;
// RAII
virtual const uf::stl::string getType() const;
virtual const size_t blitters() const;
virtual ext::vulkan::Graphic* getBlitter(size_t = 0);

View File

@ -7,20 +7,12 @@ namespace ext {
namespace vulkan {
struct UF_API RenderTargetRenderMode : public ext::vulkan::RenderMode {
ext::vulkan::Graphic blitter;
typedef std::function<void(VkCommandBuffer)> callback_t;
uf::stl::unordered_map<int32_t, callback_t> commandBufferCallbacks;
//
const uf::stl::string getTarget() const;
void setTarget( const uf::stl::string& );
void bindCallback( int32_t, const callback_t& );
constexpr static int32_t CALLBACK_BEGIN = -1;
constexpr static int32_t CALLBACK_END = -2;
// RAII
//
virtual const uf::stl::string getType() const;
virtual const size_t blitters() const;
virtual ext::vulkan::Graphic* getBlitter(size_t = 0);

View File

@ -122,7 +122,7 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity ) {
{ !graph.metadata["flags"]["SEPARATE"].as<bool>(), "instanced.vert" },
};
FOR_ARRAY(settings) if ( settings[i].first ) vertexShaderFilename = uf::string::replace( vertexShaderFilename, "vert", settings[i].second );
vertexShaderFilename = entity.grabURI( vertexShaderFilename, root );
vertexShaderFilename = entity.resolveURI( vertexShaderFilename, root );
}
uf::stl::string geometryShaderFilename = graph.metadata["shaders"]["geometry"].as<uf::stl::string>("");
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["fragment"].as<uf::stl::string>("/graph/base.frag.spv"); {
@ -130,7 +130,7 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity ) {
{ uf::renderer::settings::experimental::deferredSampling, "deferredSampling.frag" },
};
FOR_ARRAY(settings) if ( settings[i].first ) fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", settings[i].second );
fragmentShaderFilename = entity.grabURI( fragmentShaderFilename, root );
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );
}
{
graphic.material.metadata.autoInitializeUniforms = false;
@ -196,7 +196,7 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity ) {
uf::stl::string compShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/cull.comp.spv");
{
graphic.material.metadata.autoInitializeUniforms = false;
compShaderFilename = entity.grabURI( compShaderFilename, root );
compShaderFilename = entity.resolveURI( compShaderFilename, root );
graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, "culling");
graphic.material.metadata.autoInitializeUniforms = true;
}
@ -212,14 +212,14 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity ) {
}
}
if ( geometryShaderFilename != "" && uf::renderer::device.enabledFeatures.geometryShader ) {
geometryShaderFilename = entity.grabURI( geometryShaderFilename, root );
geometryShaderFilename = entity.resolveURI( geometryShaderFilename, root );
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY);
}
// depth only pipeline
{
graphic.material.metadata.autoInitializeUniforms = false;
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/depth.frag.spv");
fragmentShaderFilename = entity.grabURI( fragmentShaderFilename, root );
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, "depth");
graphic.material.metadata.autoInitializeUniforms = true;
{
@ -252,13 +252,13 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity ) {
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["fragment"].as<uf::stl::string>("/graph/voxelize.frag.spv");
{
fragmentShaderFilename = entity.grabURI( fragmentShaderFilename, root );
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );
graphic.material.metadata.autoInitializeUniforms = false;
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, "vxgi");
graphic.material.metadata.autoInitializeUniforms = true;
}
if ( geometryShaderFilename != "" && uf::renderer::device.enabledFeatures.geometryShader ) {
geometryShaderFilename = entity.grabURI( geometryShaderFilename, root );
geometryShaderFilename = entity.resolveURI( geometryShaderFilename, root );
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY, "vxgi");
}
{

View File

@ -491,8 +491,8 @@ size_t uf::Object::loadChildUid( const uf::Serializer& json, bool initialize ) {
return pointer ? pointer->getUid() : 0;
}
uf::stl::string uf::Object::grabURI( const uf::stl::string& filename, const uf::stl::string& root ) {
return uf::io::resolveURI( filename, root );
uf::stl::string uf::Object::resolveURI( const uf::stl::string& filename, const uf::stl::string& root ) {
return uf::io::resolveURI( filename, root == "" ? this->getComponent<uf::ObjectBehavior::Metadata>().system.root : root );
}

View File

@ -144,6 +144,10 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
auto imageID = graph.images.size();
auto keyName = graph.images.emplace_back(/*filename + "/" +*/ i.name);
auto& image = /*graph.storage*/uf::graph::storage.images[keyName];
if ( graph.metadata["exporter"]["image"]["print"].as<bool>() ) {
UF_MSG_DEBUG("Image: " << i.name );
}
image.loadFromBuffer( &i.image[0], {i.width, i.height}, 8, i.component, graph.metadata["flip textures"].as<bool>(true) );
}
}
@ -154,6 +158,9 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
auto samplerID = graph.samplers.size();
auto keyName = graph.samplers.emplace_back(/*filename + "/" +*/ s.name);
auto& sampler = /*graph.storage*/uf::graph::storage.samplers[keyName];
if ( graph.metadata["exporter"]["sampler"]["print"].as<bool>() ) {
UF_MSG_DEBUG("Sampler: " << s.name );
}
sampler.descriptor.filter.min = getFilterMode( s.minFilter );
sampler.descriptor.filter.mag = getFilterMode( s.magFilter );
@ -171,6 +178,9 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
auto textureID = graph.textures.size();
auto keyName = graph.textures.emplace_back((t.name == "" ? graph.images[t.source] : (/*filename + "/" +*/ t.name)));
auto& texture = /*graph.storage*/uf::graph::storage.textures[keyName];
if ( graph.metadata["exporter"]["texture"]["print"].as<bool>() ) {
UF_MSG_DEBUG("Texture: " << t.name );
}
texture.index = t.source;
texture.sampler = t.sampler;
@ -185,6 +195,9 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
auto materialID = graph.materials.size();
auto keyName = graph.materials.emplace_back(/*filename + "/" +*/ m.name);
auto& material = /*graph.storage*/uf::graph::storage.materials[keyName];
if ( graph.metadata["exporter"]["material"]["print"].as<bool>() ) {
UF_MSG_DEBUG("Material: " << m.name );
}
material.indexAlbedo = m.pbrMetallicRoughness.baseColorTexture.index;
material.indexNormal = m.normalTexture.index;
@ -228,6 +241,9 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
for ( auto& m : model.meshes ) {
auto meshID = graph.meshes.size();
auto keyName = graph.meshes.emplace_back(/*filename + "/" +*/ m.name);
if ( graph.metadata["exporter"]["mesh"]["print"].as<bool>() ) {
UF_MSG_DEBUG("Mesh: " << m.name );
}
graph.primitives.emplace_back(keyName);
graph.drawCommands.emplace_back(keyName);
@ -243,7 +259,8 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
bool print = false;
bool cleanup = true;
} meshgrid;
ext::json::forEach( graph.metadata["tags"], [&]( const uf::stl::string& key, ext::json::Value& value ) {
if ( !ext::json::isObject( value["grid"] ) ) return; // no tag["grid"] defined
if ( ext::json::isNull( value["grid"]["size"] ) ) return; // no tag["grid"]["size"] defined
@ -361,6 +378,9 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
auto skinID = graph.skins.size();
auto keyName = graph.skins.emplace_back(/*filename + "/" +*/ s.name);
auto& skin = /*graph.storage*/uf::graph::storage.skins[keyName];
if ( graph.metadata["exporter"]["skin"]["print"].as<bool>() ) {
UF_MSG_DEBUG("Skin: " << s.name );
}
skin.name = s.name;
if ( s.inverseBindMatrices > -1 ) {
@ -395,6 +415,10 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
auto animationID = graph.animations.size();
auto keyName = graph.animations.emplace_back(/*filename + "/" +*/ a.name);
auto& animation = /*graph.storage*/uf::graph::storage.animations[keyName];
if ( graph.metadata["exporter"]["animation"]["print"].as<bool>() ) {
UF_MSG_DEBUG("Animation: " << a.name );
}
animation.name = a.name;
// load samplers
@ -451,6 +475,10 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
{
for ( auto& l : model.lights ) {
auto& light = graph.lights[l.name];
if ( graph.metadata["exporter"]["light"]["print"].as<bool>() ) {
UF_MSG_DEBUG("Light: " << l.name );
}
light.color = { l.color[0], l.color[1], l.color[2], };
light.intensity = l.intensity;
light.range = l.range;

View File

@ -171,7 +171,7 @@ for ( auto& p : m.primitives ) {
}
if ( meshgrid.grid.divisions.x > 1 && meshgrid.grid.divisions.y > 1 && meshgrid.grid.divisions.z > 1 ) {
if ( meshgrid.grid.divisions.x > 1 || meshgrid.grid.divisions.y > 1 || meshgrid.grid.divisions.z > 1 ) {
auto partitioned = uf::meshgrid::partition( meshgrid.grid, meshlets, meshgrid.eps );
if ( meshgrid.print ) UF_MSG_DEBUG( "Draw commands: " << m.name << ": " << meshlets.size() << " -> " << partitioned.size() << " | Partitions: " <<
(meshgrid.grid.divisions.x * meshgrid.grid.divisions.y * meshgrid.grid.divisions.z) << " -> " << meshgrid.grid.nodes.size()

View File

@ -135,7 +135,15 @@ void UF_API ext::opengl::removeRenderMode( ext::opengl::RenderMode* mode, bool f
void UF_API ext::opengl::initialize() {
device.initialize();
// swapchain.initialize( device );
{
if ( uf::io::exists(uf::io::root + "/textures/missing.png") ) {
uf::Image image;
image.open(uf::io::root + "/textures/missing.png");
Texture2D::empty.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
Texture2D::empty.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
Texture2D::empty.loadFromImage( image );
} else {
// hard coded missing texture if not provided
uf::stl::vector<uint8_t> pixels = {
255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255,
255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255,

View File

@ -31,6 +31,10 @@ const ext::vulkan::RenderTarget& ext::vulkan::RenderMode::getRenderTarget( size_
return renderTarget;
}
void ext::vulkan::RenderMode::bindCallback( int32_t subpass, const ext::vulkan::RenderMode::callback_t& callback ) {
commandBufferCallbacks[subpass] = callback;
}
const size_t ext::vulkan::RenderMode::blitters() const {
return 0;
}

View File

@ -486,6 +486,9 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
}
}
// pre-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_BEGIN) > 0 ) commandBufferCallbacks[CALLBACK_BEGIN]( commands[i] );
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(commands[i], 0, 1, &viewport);
vkCmdSetScissor(commands[i], 0, 1, &scissor);
@ -529,6 +532,9 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
}
vkCmdEndRenderPass(commands[i]);
// post-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_END) > 0 ) commandBufferCallbacks[CALLBACK_END]( commands[i] );
if ( settings::experimental::bloom ) {
ext::vulkan::GraphicDescriptor descriptor = blitter.descriptor;
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };

View File

@ -4,6 +4,7 @@
#include <uf/ext/vulkan/rendermodes/rendertarget.h>
#include <uf/ext/vulkan/initializers.h>
#include <uf/utils/window/window.h>
#include <uf/utils/math/physics.h>
#include <uf/utils/graphic/graphic.h>
#include <uf/ext/vulkan/graphic.h>
#include <uf/engine/graph/graph.h>
@ -17,9 +18,6 @@ void ext::vulkan::RenderTargetRenderMode::setTarget( const uf::stl::string& targ
// this->metadata["target"] = target;
metadata.target = target;
}
void ext::vulkan::RenderTargetRenderMode::bindCallback( int32_t subpass, const ext::vulkan::RenderTargetRenderMode::callback_t& callback ) {
commandBufferCallbacks[subpass] = callback;
}
const uf::stl::string ext::vulkan::RenderTargetRenderMode::getType() const {
return "RenderTarget";
@ -522,6 +520,20 @@ void ext::vulkan::RenderTargetRenderMode::destroy() {
blitter.destroy();
}
void ext::vulkan::RenderTargetRenderMode::render() {
if ( metadata.limiter.frequency > 0 ) {
if ( metadata.limiter.timer > metadata.limiter.frequency ) {
metadata.limiter.timer = 0;
metadata.limiter.execute = true;
} else {
metadata.limiter.timer = metadata.limiter.timer + uf::physics::time::delta;
metadata.limiter.execute = false;
}
}
if ( !metadata.limiter.execute ) return;
if ( commandBufferCallbacks.count(EXECUTE_BEGIN) > 0 ) commandBufferCallbacks[EXECUTE_BEGIN]( VkCommandBuffer{} );
auto& commands = getCommands( this->mostRecentCommandPoolId );
// Submit commands
// Use a fence to ensure that command buffer has finished executing before using it again
@ -553,6 +565,8 @@ void ext::vulkan::RenderTargetRenderMode::render() {
waitInfo.pValues = NULL;
VK_CHECK_RESULT(vkWaitSemaphores( *device, &waitInfo, UINT64_MAX ));
*/
if ( commandBufferCallbacks.count(EXECUTE_END) > 0 ) commandBufferCallbacks[EXECUTE_END]( VkCommandBuffer{} );
}
void ext::vulkan::RenderTargetRenderMode::pipelineBarrier( VkCommandBuffer commandBuffer, uint8_t state ) {
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };

View File

@ -198,7 +198,16 @@ void ext::vulkan::initialize() {
ext::vulkan::mutex.lock();
device.initialize();
swapchain.initialize( device );
{
if ( uf::io::exists(uf::io::root + "/textures/missing.png") ) {
uf::Image image;
image.open(uf::io::root + "/textures/missing.png");
Texture2D::empty.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
Texture2D::empty.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
Texture2D::empty.loadFromImage( image );
} else {
// hard coded missing texture if not provided
uf::stl::vector<uint8_t> pixels = {
255, 0, 255, 255, 0, 0, 0, 255,
0, 0, 0, 255, 255, 0, 255, 255,

View File

@ -127,14 +127,20 @@ size_t UF_API ext::xatlas::unwrap( pod::Graph& graph, bool combined ) {
}
::xatlas::ChartOptions chartOptions{};
// chartOptions.useInputMeshUvs = true;
chartOptions.useInputMeshUvs = graph.metadata["baking"]["settings"]["useInputMeshUvs"].as(chartOptions.useInputMeshUvs);
chartOptions.maxIterations = graph.metadata["baking"]["settings"]["maxIterations"].as(chartOptions.maxIterations);
::xatlas::PackOptions packOptions{};
packOptions.bruteForce = true;
// packOptions.resolution = resolution;
// packOptions.texelsPerUnit = 64.0f;
packOptions.blockAlign = true;
packOptions.bilinear = true;
packOptions.maxChartSize = graph.metadata["baking"]["settings"]["maxChartSize"].as(packOptions.maxChartSize);
packOptions.padding = graph.metadata["baking"]["settings"]["padding"].as(packOptions.padding);
packOptions.texelsPerUnit = graph.metadata["baking"]["settings"]["texelsPerUnit"].as(packOptions.texelsPerUnit);
packOptions.bilinear = graph.metadata["baking"]["settings"]["bilinear"].as(packOptions.bilinear);
packOptions.blockAlign = graph.metadata["baking"]["settings"]["blockAlign"].as(packOptions.blockAlign);
packOptions.bruteForce = graph.metadata["baking"]["settings"]["bruteForce"].as(packOptions.bruteForce);
packOptions.createImage = graph.metadata["baking"]["settings"]["createImage"].as(packOptions.createImage);
packOptions.rotateChartsToAxis = graph.metadata["baking"]["settings"]["rotateChartsToAxis"].as(packOptions.rotateChartsToAxis);
packOptions.rotateCharts = graph.metadata["baking"]["settings"]["rotateCharts"].as(packOptions.rotateCharts);
packOptions.resolution = graph.metadata["baking"]["resolution"].as(packOptions.resolution);
// pack
pod::Thread::container_t jobs;

View File

@ -25,7 +25,6 @@ uf::stl::vector<uf::stl::string> UF_API uf::string::matches( const uf::stl::stri
uf::stl::vector<uf::stl::string> matches;
if ( std::regex_search( str, match, regex ) ) {
for ( auto& m : match ) {
UF_MSG_DEBUG(m);
matches.emplace_back(m.str());
}
}

View File

@ -38,7 +38,7 @@ void ext::BakingBehavior::initialize( uf::Object& self ) {
UF_MSG_DEBUG("Temporarily altering shadow limits...");
this->addHook( "entity:PostInitialization.%UID%", [&]( ext::json::Value& ){
metadata.output = this->grabURI( metadataJson["baking"]["output"].as<uf::stl::string>(), metadataJson["baking"]["root"].as<uf::stl::string>() );
metadata.output = this->resolveURI( metadataJson["baking"]["output"].as<uf::stl::string>(), metadataJson["baking"]["root"].as<uf::stl::string>() );
metadata.renderModeName = "B:" + std::to_string((int) this->getUid());
metadata.trigger.mode = metadataJson["baking"]["trigger"]["mode"].as( metadata.trigger.mode );

View File

@ -108,6 +108,11 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
this->addHook( "window:Resized", [&](pod::payloads::windowResized& payload){
ext::gui::size.current = payload.window.size;
});
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
metadata.deserialize(self, metadataJson);
// lock control
{
pod::payloads::windowMouseCursorVisibility payload;
@ -163,13 +168,13 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
}
// initialize cubemap
{
uf::stl::vector<uf::stl::string> filenames = {
uf::io::root+"/textures/skybox/front.png",
uf::io::root+"/textures/skybox/back.png",
uf::io::root+"/textures/skybox/up.png",
uf::io::root+"/textures/skybox/down.png",
uf::io::root+"/textures/skybox/right.png",
uf::io::root+"/textures/skybox/left.png",
const uf::stl::vector<uf::stl::string> filenames = {
"front",
"back",
"up",
"down",
"right",
"left",
};
uf::Image::container_t pixels;
uf::stl::vector<uf::Image> images(filenames.size());
@ -177,7 +182,7 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
pod::Vector2ui size = {0,0};
auto& texture = sceneTextures.skybox;
for ( uint32_t i = 0; i < filenames.size(); ++i ) {
auto& filename = filenames[i];
auto filename = uf::string::replace( this->resolveURI(metadata.sky.box.filename), "%d", filenames[i] );
auto& image = images[i];
image.open(filename);
image.flip();
@ -189,14 +194,10 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
pixels.reserve( pixels.size() + p.size() );
pixels.insert( pixels.end(), p.begin(), p.end() );
}
texture.mips = 0;
// texture.mips = 0;
texture.fromBuffers( (void*) pixels.data(), pixels.size(), uf::renderer::enums::Format::R8G8B8A8_UNORM, size.x, size.y, 1, filenames.size() );
}
#endif
this->addHook( "object:Serialize.%UID%", [&](ext::json::Value& json){ metadata.serialize(self, metadataJson); });
this->addHook( "object:Deserialize.%UID%", [&](ext::json::Value& json){ metadata.deserialize(self, metadataJson); });
metadata.deserialize(self, metadataJson);
}
void ext::ExtSceneBehavior::tick( uf::Object& self ) {
auto& assetLoader = this->getComponent<uf::Asset>();
@ -575,6 +576,7 @@ void ext::ExtSceneBehavior::Metadata::serialize( uf::Object& self, uf::Serialize
serializer["light"]["fog"]["density"]["threshold"] = /*this->*/fog.density.threshold;
serializer["light"]["fog"]["density"]["multiplier"] = /*this->*/fog.density.multiplier;
serializer["light"]["fog"]["density"]["scale"] = /*this->*/fog.density.scale;
serializer["sky"]["box"]["filename"] = /*this->*/sky.box.filename;
serializer["system"]["renderer"]["shader"]["mode"] = /*this->*/shader.mode;
serializer["system"]["renderer"]["shader"]["scalar"] = /*this->*/shader.scalar;
@ -613,6 +615,8 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali
/*this->*/fog.density.threshold = serializer["light"]["fog"]["density"]["threshold"].as<float>();
/*this->*/fog.density.multiplier = serializer["light"]["fog"]["density"]["multiplier"].as<float>();
/*this->*/fog.density.scale = serializer["light"]["fog"]["density"]["scale"].as<float>();
/*this->*/sky.box.filename = serializer["sky"]["box"]["filename"].as<uf::stl::string>();
/*this->*/shader.mode = serializer["system"]["renderer"]["shader"]["mode"].as<uint32_t>();
/*this->*/shader.scalar = serializer["system"]["renderer"]["shader"]["scalar"].as<uint32_t>();

View File

@ -60,6 +60,11 @@ namespace ext {
float scale = 50.0f;
} density;
} fog;
struct {
struct {
uf::stl::string filename = "%root%/textures/skybox/%d.png";
} box;
} sky;
);
void bindBuffers( uf::Object&, const uf::stl::string& = "", bool = false );

View File

@ -42,7 +42,7 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
if ( metadata.voxelSize.y == 0 ) metadata.voxelSize.y = DEFAULT_VOXEL_SIZE;
if ( metadata.voxelSize.z == 0 ) metadata.voxelSize.z = DEFAULT_VOXEL_SIZE;
if ( metadata.renderer.limiter == 0 ) metadata.renderer.limiter = DEFAULT_VOXELIZE_LIMITER;
if ( metadata.limiter.frequency == 0 ) metadata.limiter.frequency = DEFAULT_VOXELIZE_LIMITER;
if ( metadata.dispatchSize.x == 0 ) metadata.dispatchSize.x = DEFAULT_DISPATCH_SIZE;
if ( metadata.dispatchSize.y == 0 ) metadata.dispatchSize.y = DEFAULT_DISPATCH_SIZE;
@ -97,6 +97,8 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
renderMode.width = metadata.fragmentSize.x;
renderMode.height = metadata.fragmentSize.y;
// renderMode.metadata.limiter.frequency = metadata.limiter.frequency;
uf::stl::string computeShaderFilename = "/shaders/display/vxgi.comp.spv";
if ( renderMode.metadata.samples > 1 ) {
computeShaderFilename = uf::string::replace( computeShaderFilename, "frag", "msaa.frag" );
@ -177,6 +179,134 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
);
}
});
#if 0
renderMode.bindCallback( renderMode.EXECUTE_BEGIN, [&]( VkCommandBuffer _ ) {
auto& controller = scene.getController();
auto controllerTransform = uf::transform::flatten( controller.getComponent<uf::Camera>().getTransform() );
pod::Vector3f controllerPosition = controllerTransform.position - metadata.extents.min;
controllerPosition.x = floor(controllerPosition.x);
controllerPosition.y = floor(controllerPosition.y);
controllerPosition.z = floor(controllerPosition.z);
controllerPosition += metadata.extents.min;
controllerPosition.x = floor(controllerPosition.x);
controllerPosition.y = floor(controllerPosition.y);
controllerPosition.z = -floor(controllerPosition.z);
pod::Vector3f min = metadata.extents.min + controllerPosition;
pod::Vector3f max = metadata.extents.max + controllerPosition;
metadata.extents.matrix = uf::matrix::orthographic( min.x, max.x, min.y, max.y, min.z, max.z );
auto& graph = scene.getGraph();
for ( auto entity : graph ) {
if ( !entity->hasComponent<uf::Graphic>() ) continue;
auto& graphic = entity->getComponent<uf::Graphic>();
if ( graphic.material.hasShader("geometry", "vxgi") ) {
auto& shader = graphic.material.getShader("geometry", "vxgi");
struct UniformDescriptor {
/*alignas(16)*/ pod::Matrix4f matrix;
/*alignas(4)*/ float cascadePower;
/*alignas(4)*/ float padding1;
/*alignas(4)*/ float padding2;
/*alignas(4)*/ float padding3;
};
#if UF_UNIFORMS_REUSE
auto& uniform = shader.getUniform("UBO");
auto& uniforms = uniform.get<UniformDescriptor>();
uniforms = UniformDescriptor{
.matrix = metadata.extents.matrix,
.cascadePower = metadata.cascadePower,
};
shader.updateUniform( "UBO", uniform );
#else
UniformDescriptor uniforms = {
.matrix = metadata.extents.matrix,
.cascadePower = metadata.cascadePower,
};
shader.updateBuffer( uniforms, shader.getUniformBuffer("UBO") );
#endif
}
}
} );
#endif
auto& deferredRenderMode = uf::renderer::getRenderMode("", true);
deferredRenderMode.bindCallback( renderMode.CALLBACK_BEGIN, [&]( VkCommandBuffer commandBuffer ){
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
for ( auto& t : sceneTextures.voxels.radiance ) {
VkPipelineStageFlags srcStageMask, dstStageMask;
imageMemoryBarrier.image = t.image;
imageMemoryBarrier.oldLayout = t.imageLayout;
imageMemoryBarrier.newLayout = t.imageLayout;
imageMemoryBarrier.subresourceRange.levelCount = t.mips;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
/*
imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
*/
vkCmdPipelineBarrier( commandBuffer,
srcStageMask, dstStageMask,
VK_FLAGS_NONE,
0, NULL,
0, NULL,
1, &imageMemoryBarrier
);
}
});
deferredRenderMode.bindCallback( renderMode.CALLBACK_END, [&]( VkCommandBuffer commandBuffer ){
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
for ( auto& t : sceneTextures.voxels.radiance ) {
VkPipelineStageFlags srcStageMask, dstStageMask;
imageMemoryBarrier.image = t.image;
imageMemoryBarrier.oldLayout = t.imageLayout;
imageMemoryBarrier.newLayout = t.imageLayout;
imageMemoryBarrier.subresourceRange.levelCount = t.mips;
/*
imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
*/
imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
vkCmdPipelineBarrier( commandBuffer,
srcStageMask, dstStageMask,
VK_FLAGS_NONE,
0, NULL,
0, NULL,
1, &imageMemoryBarrier
);
}
});
}
#endif
}
@ -189,23 +319,32 @@ void ext::VoxelizerBehavior::tick( uf::Object& self ) {
auto& scene = uf::scene::getCurrentScene();
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
auto& controller = scene.getController();
auto controllerTransform = uf::transform::flatten( controller.getComponent<uf::Camera>().getTransform() );
renderMode.setTarget("");
if ( renderMode.executed ) {
if ( !metadata.initialized ) metadata.initialized = true;
if ( metadata.renderer.limiter > 0 ) {
if ( metadata.renderer.timer > metadata.renderer.limiter ) {
metadata.renderer.timer = 0;
renderMode.execute = true;
if ( metadata.limiter.frequency > 0 ) {
if ( metadata.limiter.timer > metadata.limiter.frequency ) {
metadata.limiter.timer = 0;
renderMode.metadata.limiter.execute = true;
} else {
metadata.renderer.timer = metadata.renderer.timer + uf::physics::time::delta;
renderMode.execute = false;
metadata.limiter.timer = metadata.limiter.timer + uf::physics::time::delta;
renderMode.metadata.limiter.execute = false;
}
}
if ( renderMode.execute ) {
#if 1
// bool should = false;
// if ( renderMode.metadata.limiter.frequency <= 0 && renderMode.metadata.limiter.timer <= 0 ) should = true;
// else if ( renderMode.metadata.limiter.timer + renderMode.metadata.limiter.frequency >= renderMode.metadata.limiter.frequency ) should = true;
// if ( renderMode.execute ) {
if ( renderMode.metadata.limiter.execute ) {
// if ( should ) {
auto& controller = scene.getController();
auto controllerTransform = uf::transform::flatten( controller.getComponent<uf::Camera>().getTransform() );
pod::Vector3f controllerPosition = controllerTransform.position - metadata.extents.min;
controllerPosition.x = floor(controllerPosition.x);
controllerPosition.y = floor(controllerPosition.y);
@ -252,6 +391,7 @@ void ext::VoxelizerBehavior::tick( uf::Object& self ) {
}
}
}
#endif
}
ext::ExtSceneBehavior::bindBuffers( scene, metadata.renderModeName, true );
ext::ExtSceneBehavior::bindBuffers( scene );

View File

@ -29,9 +29,9 @@ namespace ext {
pod::Matrix4f matrix = uf::matrix::identity();
} extents;
struct {
float limiter = 0.0f;
float frequency = 0.0f;
float timer = 0.0f;
} renderer;
} limiter;
bool initialized = false;
);
}