Commit for 2021.07.18 00-48-23.7z
This commit is contained in:
parent
6d8fbc6ee5
commit
8aeca4944c
@ -38,6 +38,13 @@
|
||||
"min": [ -1.5, -1.5, -1.5 ],
|
||||
"max": [ 1.5, 1.5, 1.5 ]
|
||||
}
|
||||
},
|
||||
"bloom": {
|
||||
"scale": 1.0,
|
||||
"strength": 1.0,
|
||||
"threshold": 1.0,
|
||||
"sigma": 0.8,
|
||||
"samples": 5
|
||||
}
|
||||
},
|
||||
"ext": {
|
||||
@ -69,12 +76,13 @@
|
||||
"multithreaded command rendering": false,
|
||||
"deferred mode": "",
|
||||
"deferred reconstruct position": true,
|
||||
"deferred alias output to swapchain": true,
|
||||
"deferred alias output to swapchain": false,
|
||||
"vsync": true,
|
||||
"hdr": false,
|
||||
"vxgi": true,
|
||||
"deferred sampling": true,
|
||||
"culling": false
|
||||
"deferred sampling": false,
|
||||
"culling": false,
|
||||
"bloom": true
|
||||
},
|
||||
"formats": {
|
||||
"depth": "D32_SFLOAT",
|
||||
|
||||
@ -29,10 +29,16 @@
|
||||
"bgm": 0.75,
|
||||
"voice": 1.0
|
||||
},
|
||||
"bloom": {
|
||||
"scale": 1.0,
|
||||
"strength": 0.5,
|
||||
"sigma": 0.75,
|
||||
"samples": 8
|
||||
},
|
||||
"light": {
|
||||
"exposure": 1.0,
|
||||
"gamma": 1.0,
|
||||
|
||||
"brightnessThreshold": 1.0,
|
||||
"ambient": [ 0.1, 0.1, 0.1 ],
|
||||
|
||||
"fog": {
|
||||
|
||||
@ -15,6 +15,9 @@ vec3 orthogonal(vec3 u){
|
||||
vec4 blend( vec4 source, vec4 dest, float a ) {
|
||||
return source * a + dest * (1.0 - a);
|
||||
}
|
||||
float gauss( float x, float sigma ) {
|
||||
return (1.0 / (2.0 * 3.14157 * sigma) * exp(-(x*x) / (2.0 * sigma)));
|
||||
}
|
||||
bool enabled( uint flag, uint bit ) {
|
||||
return (flag & (1 << bit)) != 0;
|
||||
}
|
||||
@ -35,7 +38,7 @@ bool validTextureIndex( int textureIndex ) {
|
||||
bool validCubemapIndex( int textureIndex ) {
|
||||
return 0 <= textureIndex && textureIndex < CUBEMAPS;
|
||||
}
|
||||
#if DEFERRED || COMPUTE
|
||||
#if !BLOOM && (DEFERRED || COMPUTE)
|
||||
bool validTextureIndex( uint id ) {
|
||||
return 0 <= id && id < MAX_TEXTURES;
|
||||
}
|
||||
|
||||
67
bin/data/shaders/display/bloom.comp.glsl
Normal file
67
bin/data/shaders/display/bloom.comp.glsl
Normal file
@ -0,0 +1,67 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define COMPUTE 1
|
||||
#define TEXTURES 0
|
||||
#define CUBEMAPS 0
|
||||
#define BLOOM 1
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint eye;
|
||||
uint mode;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
float scale;
|
||||
float strength;
|
||||
float threshold;
|
||||
float sigma;
|
||||
|
||||
float gamma;
|
||||
float exposure;
|
||||
uint samples;
|
||||
uint padding;
|
||||
} ubo;
|
||||
|
||||
layout (binding = 1, rgba16f) uniform volatile coherent image2D imageColor;
|
||||
layout (binding = 2, rgba16f) uniform volatile coherent image2D imageBloom;
|
||||
layout (binding = 3, rgba16f) uniform volatile coherent image2D imagePingPong;
|
||||
|
||||
#include "../common/macros.h"
|
||||
#include "../common/structs.h"
|
||||
#include "../common/functions.h"
|
||||
|
||||
void main() {
|
||||
const uint mode = PushConstant.mode;
|
||||
const ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||
const ivec2 size = imageSize( imageColor );
|
||||
if ( texel.x >= size.x || texel.y >= size.y ) return;
|
||||
|
||||
if ( mode == 0 ) { // fill bloom
|
||||
vec3 result = imageLoad( imageColor, texel ).rgb;
|
||||
float brightness = dot(result, vec3(0.2126, 0.7152, 0.0722));
|
||||
if ( brightness < ubo.threshold ) result = vec3(0, 0, 0);
|
||||
imageStore( imageBloom, texel, vec4( result, 1.0 ) );
|
||||
} else if ( mode == 1 ) { // bloom horizontal
|
||||
vec3 result = imageLoad( imageBloom, texel ).rgb * gauss( 0, ubo.sigma ) * ubo.strength;
|
||||
for( int i = 1; i < ubo.samples; ++i ) {
|
||||
result += imageLoad( imageBloom, texel + ivec2(i * ubo.scale, 0.0)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
result += imageLoad( imageBloom, texel - ivec2(i * ubo.scale, 0.0)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
}
|
||||
// write to PingPong
|
||||
imageStore( imagePingPong, texel, vec4( result, 1.0 ) );
|
||||
} else if ( mode == 2 ) { // bloom vertical
|
||||
vec3 result = imageLoad( imagePingPong, texel ).rgb * gauss( 0, ubo.sigma ) * ubo.strength;
|
||||
for( int i = 1; i < ubo.samples; ++i ) {
|
||||
result += imageLoad( imagePingPong, texel + ivec2(0.0, i * ubo.scale)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
result += imageLoad( imagePingPong, texel - ivec2(0.0, i * ubo.scale)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
}
|
||||
// write to Bloom
|
||||
imageStore( imageBloom, texel, vec4( result, 1.0 ) );
|
||||
} else if ( mode == 3 ) { // combine
|
||||
vec3 result = imageLoad( imageColor, texel ).rgb + imageLoad( imageBloom, texel ).rgb;
|
||||
imageStore( imageColor, texel, vec4( result, 1.0 ) );
|
||||
}
|
||||
}
|
||||
@ -49,9 +49,14 @@ layout (binding = 4) uniform UBO {
|
||||
float gamma;
|
||||
|
||||
float exposure;
|
||||
float brightnessThreshold;
|
||||
uint msaa;
|
||||
uint shadowSamples;
|
||||
|
||||
uint indexSkybox;
|
||||
uint padding1;
|
||||
uint padding2;
|
||||
uint padding3;
|
||||
} ubo;
|
||||
/*
|
||||
layout (std140, binding = 5) readonly buffer DrawCommands {
|
||||
@ -81,9 +86,10 @@ layout (binding = 11) uniform sampler3D samplerNoise;
|
||||
#endif
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in flat uint inPushConstantPass;
|
||||
layout (location = 1) in flat uvec2 inPushConstantPass;
|
||||
|
||||
layout (location = 0) out vec4 outFragColor;
|
||||
layout (location = 1) out vec4 outFragBright;
|
||||
|
||||
#include "../common/functions.h"
|
||||
#include "../common/fog.h"
|
||||
@ -94,6 +100,9 @@ layout (location = 0) out vec4 outFragColor;
|
||||
#endif
|
||||
|
||||
void postProcess() {
|
||||
float brightness = dot(surface.fragment.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
outFragBright = brightness > ubo.brightnessThreshold ? vec4(surface.fragment.rgb, 1.0) : vec4(0, 0, 0, 1);
|
||||
|
||||
#if FOG
|
||||
fog( surface.ray, surface.fragment.rgb, surface.fragment.a );
|
||||
#endif
|
||||
@ -106,12 +115,12 @@ void postProcess() {
|
||||
#if WHITENOISE
|
||||
if ( enabled(ubo.mode.type, 1) ) whitenoise(surface.fragment.rgb, ubo.mode.parameters);
|
||||
#endif
|
||||
|
||||
outFragColor = vec4(surface.fragment.rgb,1);
|
||||
|
||||
outFragColor = vec4(surface.fragment.rgb, 1.0);
|
||||
}
|
||||
|
||||
void populateSurface() {
|
||||
surface.pass = inPushConstantPass;
|
||||
surface.pass = inPushConstantPass.x;
|
||||
{
|
||||
#if !MULTISAMPLING
|
||||
const float depth = subpassLoad(samplerDepth).r;
|
||||
|
||||
@ -6,7 +6,7 @@ layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
#endif
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out flat uint outPushConstantPass;
|
||||
layout (location = 1) out flat uvec2 outPushConstantPass;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
@ -19,7 +19,7 @@ out gl_PerVertex {
|
||||
|
||||
|
||||
void main() {
|
||||
outPushConstantPass = PushConstant.pass;
|
||||
outPushConstantPass = uvec2(PushConstant.pass, PushConstant.draw);
|
||||
outUv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
gl_Position = vec4(outUv * 2.0f + -1.0f, 0.0f, 1.0f);
|
||||
#if 0
|
||||
|
||||
@ -32,9 +32,14 @@ layout (binding = 4) uniform UBO {
|
||||
float gamma;
|
||||
|
||||
float exposure;
|
||||
float brightnessThreshold;
|
||||
uint msaa;
|
||||
uint shadowSamples;
|
||||
|
||||
uint indexSkybox;
|
||||
uint padding1;
|
||||
uint padding2;
|
||||
uint padding3;
|
||||
} ubo;
|
||||
/*
|
||||
layout (std140, binding = 5) readonly buffer DrawCommands {
|
||||
|
||||
@ -40,6 +40,7 @@ namespace ext {
|
||||
extern UF_API bool vxgi;
|
||||
extern UF_API bool deferredSampling;
|
||||
extern UF_API bool culling;
|
||||
extern UF_API bool bloom;
|
||||
}
|
||||
|
||||
namespace formats {
|
||||
|
||||
@ -36,6 +36,7 @@ namespace ext {
|
||||
void update( const Graphic& graphic );
|
||||
void update( const Graphic& graphic, const GraphicDescriptor& descriptor );
|
||||
void record( const Graphic& graphic, VkCommandBuffer, size_t = 0, size_t = 0 ) const;
|
||||
void record( const Graphic& graphic, const GraphicDescriptor& descriptor, VkCommandBuffer, size_t = 0, size_t = 0 ) const;
|
||||
void destroy();
|
||||
|
||||
uf::stl::vector<Shader*> getShaders( uf::stl::vector<Shader>& );
|
||||
|
||||
@ -27,15 +27,15 @@ namespace ext {
|
||||
uf::stl::vector<Attachment> attachments;
|
||||
|
||||
struct Subpass {
|
||||
VkPipelineStageFlags stage;
|
||||
VkAccessFlags access;
|
||||
uint8_t layer;
|
||||
VkPipelineStageFlags stage = {};
|
||||
VkAccessFlags access = {};
|
||||
uint8_t layer = 0;
|
||||
bool autoBuildPipeline;
|
||||
|
||||
uf::stl::vector<VkAttachmentReference> colors;
|
||||
uf::stl::vector<VkAttachmentReference> inputs;
|
||||
uf::stl::vector<VkAttachmentReference> resolves;
|
||||
VkAttachmentReference depth;
|
||||
uf::stl::vector<VkAttachmentReference> colors = {};
|
||||
uf::stl::vector<VkAttachmentReference> inputs = {};
|
||||
uf::stl::vector<VkAttachmentReference> resolves = {};
|
||||
VkAttachmentReference depth = {};
|
||||
};
|
||||
uf::stl::vector<Subpass> passes;
|
||||
|
||||
|
||||
@ -98,6 +98,10 @@ namespace ext {
|
||||
ext::vulkan::userdata_t specializationConstants;
|
||||
uf::stl::vector<ext::vulkan::userdata_t> pushConstants;
|
||||
uf::stl::vector<ext::vulkan::userdata_t> uniforms;
|
||||
|
||||
// for per-shader texture allotment, needed for our bloom pipeline
|
||||
uf::stl::vector<Texture2D> textures;
|
||||
|
||||
// ~Shader();
|
||||
void initialize( Device& device, const uf::stl::string&, VkShaderStageFlagBits );
|
||||
void destroy();
|
||||
|
||||
@ -67,6 +67,7 @@ namespace ext {
|
||||
extern UF_API bool vxgi;
|
||||
extern UF_API bool deferredSampling;
|
||||
extern UF_API bool culling;
|
||||
extern UF_API bool bloom;
|
||||
}
|
||||
|
||||
namespace formats {
|
||||
|
||||
@ -98,4 +98,6 @@
|
||||
#endif
|
||||
|
||||
#define MIN(X, Y) X < Y ? X : Y
|
||||
#define MAX(X, Y) X > Y ? X : Y
|
||||
#define MAX(X, Y) X > Y ? X : Y
|
||||
#define LENGTH_OF(X) *(&X + 1) - X
|
||||
#define FOR_ARRAY(X) for ( auto i = 0; i < LENGTH_OF(X); ++i )
|
||||
@ -57,104 +57,104 @@ namespace {
|
||||
}
|
||||
|
||||
// standard pipeline
|
||||
uf::stl::string vertexShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/base.vert.spv");
|
||||
uf::stl::string vertexShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/base.vert.spv"); {
|
||||
std::pair<bool, uf::stl::string> settings[] = {
|
||||
{ graph.metadata["flags"]["SKINNED"].as<bool>(), "skinned.vert" },
|
||||
{ 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 );
|
||||
}
|
||||
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");
|
||||
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["fragment"].as<uf::stl::string>("/graph/base.frag.spv"); {
|
||||
std::pair<bool, uf::stl::string> settings[] = {
|
||||
{ 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 );
|
||||
}
|
||||
{
|
||||
graphic.material.metadata.autoInitializeUniforms = false;
|
||||
if ( uf::renderer::settings::experimental::deferredSampling ) {
|
||||
fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", "deferredSampling.frag" );
|
||||
}
|
||||
{
|
||||
if ( !graph.metadata["flags"]["SEPARATE"].as<bool>() ) {
|
||||
vertexShaderFilename = graph.metadata["flags"]["SKINNED"].as<bool>() ? "/graph/skinned.instanced.vert.spv" : "/graph/instanced.vert.spv";
|
||||
} else if ( graph.metadata["flags"]["SKINNED"].as<bool>() ) vertexShaderFilename = "/graph/skinned.vert.spv";
|
||||
vertexShaderFilename = entity.grabURI( vertexShaderFilename, root );
|
||||
graphic.material.attachShader(vertexShaderFilename, uf::renderer::enums::Shader::VERTEX);
|
||||
}
|
||||
{
|
||||
fragmentShaderFilename = entity.grabURI( fragmentShaderFilename, root );
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT);
|
||||
}
|
||||
#if UF_USE_VULKAN
|
||||
graphic.material.attachShader(vertexShaderFilename, uf::renderer::enums::Shader::VERTEX);
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT);
|
||||
graphic.material.metadata.autoInitializeUniforms = true;
|
||||
if ( geometryShaderFilename != "" && uf::renderer::device.enabledFeatures.geometryShader ) {
|
||||
geometryShaderFilename = entity.grabURI( geometryShaderFilename, root );
|
||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY);
|
||||
}
|
||||
{
|
||||
uint32_t maxPasses = 6;
|
||||
|
||||
auto& shader = graphic.material.getShader("vertex");
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "PASSES" ) sc.value.ui = (specializationConstants[sc.index] = maxPasses);
|
||||
}
|
||||
|
||||
uf::renderer::Buffer* indirect = NULL;
|
||||
for ( auto& buffer : graphic.buffers ) if ( !indirect && buffer.usage & uf::renderer::enums::Buffer::INDIRECT ) indirect = &buffer;
|
||||
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.camera );
|
||||
// shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.drawCommands );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.instance );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.joint );
|
||||
}
|
||||
{
|
||||
uint32_t maxTextures = graph.textures.size(); // texture2Ds;
|
||||
|
||||
auto& shader = graphic.material.getShader("fragment");
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures);
|
||||
}
|
||||
for ( auto pair : shader.metadata.definitions.textures ) {
|
||||
auto& tx = pair.second;
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures;
|
||||
}
|
||||
}
|
||||
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.material );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.texture );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.light );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if UF_USE_VULKAN
|
||||
if ( geometryShaderFilename != "" && uf::renderer::device.enabledFeatures.geometryShader ) {
|
||||
geometryShaderFilename = entity.grabURI( geometryShaderFilename, root );
|
||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY);
|
||||
}
|
||||
{
|
||||
uint32_t maxPasses = 6;
|
||||
|
||||
auto& shader = graphic.material.getShader("vertex");
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "PASSES" ) sc.value.ui = (specializationConstants[sc.index] = maxPasses);
|
||||
}
|
||||
|
||||
uf::renderer::Buffer* indirect = NULL;
|
||||
for ( auto& buffer : graphic.buffers ) if ( !indirect && buffer.usage & uf::renderer::enums::Buffer::INDIRECT ) indirect = &buffer;
|
||||
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.camera );
|
||||
// shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.drawCommands );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.instance );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.joint );
|
||||
}
|
||||
{
|
||||
uint32_t maxTextures = graph.textures.size(); // texture2Ds;
|
||||
|
||||
auto& shader = graphic.material.getShader("fragment");
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
auto& sc = pair.second;
|
||||
if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures);
|
||||
}
|
||||
for ( auto pair : shader.metadata.definitions.textures ) {
|
||||
auto& tx = pair.second;
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures;
|
||||
}
|
||||
}
|
||||
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.material );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.texture );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.light );
|
||||
}
|
||||
#endif
|
||||
// culling pipeline
|
||||
if ( uf::renderer::settings::experimental::culling ) {
|
||||
graphic.material.metadata.autoInitializeUniforms = false;
|
||||
uf::renderer::Buffer* indirect = NULL;
|
||||
for ( auto& buffer : graphic.buffers ) if ( !indirect && buffer.usage & uf::renderer::enums::Buffer::INDIRECT ) indirect = &buffer;
|
||||
UF_ASSERT( indirect );
|
||||
|
||||
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 );
|
||||
graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, "culling");
|
||||
graphic.material.metadata.autoInitializeUniforms = true;
|
||||
}
|
||||
graphic.descriptor.inputs.dispatch = { graphic.descriptor.inputs.indirect.count, 1, 1 };
|
||||
|
||||
auto& shader = graphic.material.getShader("compute", "culling");
|
||||
|
||||
uf::renderer::Buffer* indirect = NULL;
|
||||
for ( auto& buffer : graphic.buffers ) if ( !indirect && buffer.usage & uf::renderer::enums::Buffer::INDIRECT ) indirect = &buffer;
|
||||
UF_ASSERT( indirect );
|
||||
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.camera );
|
||||
shader.buffers.emplace_back().aliasBuffer( *indirect );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.instance );
|
||||
}
|
||||
#if UF_USE_VULKAN
|
||||
// depth only pipeline
|
||||
#if UF_USE_VULKAN
|
||||
{
|
||||
graphic.material.metadata.autoInitializeUniforms = false;
|
||||
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/depth.frag.spv");
|
||||
{
|
||||
graphic.material.attachShader(vertexShaderFilename, uf::renderer::enums::Shader::VERTEX, "depth");
|
||||
}
|
||||
{
|
||||
fragmentShaderFilename = entity.grabURI( fragmentShaderFilename, root );
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, "depth");
|
||||
}
|
||||
fragmentShaderFilename = entity.grabURI( fragmentShaderFilename, root );
|
||||
// graphic.material.attachShader(vertexShaderFilename, uf::renderer::enums::Shader::VERTEX, "depth");
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, "depth");
|
||||
graphic.material.metadata.autoInitializeUniforms = true;
|
||||
/*
|
||||
{
|
||||
uint32_t maxPasses = 6;
|
||||
|
||||
@ -173,6 +173,7 @@ namespace {
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.instance );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.joint );
|
||||
}
|
||||
*/
|
||||
{
|
||||
uint32_t maxTextures = graph.textures.size(); // texture2Ds;
|
||||
|
||||
@ -197,20 +198,16 @@ namespace {
|
||||
}
|
||||
// vxgi pipeline
|
||||
if ( uf::renderer::settings::experimental::vxgi ) {
|
||||
// graphic.material.metadata.json["shader"]["autoInitializeUniformBuffers"] = false;
|
||||
graphic.material.metadata.autoInitializeUniforms = false;
|
||||
uf::stl::string vertexShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/base.vert.spv");
|
||||
uf::stl::string geometryShaderFilename = graph.metadata["shaders"]["geometry"].as<uf::stl::string>("/graph/voxelize.geom.spv");
|
||||
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["fragment"].as<uf::stl::string>("/graph/voxelize.frag.spv");
|
||||
if ( uf::renderer::settings::experimental::deferredSampling ) {
|
||||
// fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", "deferredSampling.frag" );
|
||||
}
|
||||
|
||||
{
|
||||
fragmentShaderFilename = entity.grabURI( fragmentShaderFilename, root );
|
||||
graphic.material.metadata.autoInitializeUniforms = false;
|
||||
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, "vxgi");
|
||||
graphic.material.metadata.autoInitializeUniforms = true;
|
||||
}
|
||||
// graphic.material.metadata.json["shader"]["autoInitializeUniformBuffers"] = true;
|
||||
graphic.material.metadata.autoInitializeUniforms = true;
|
||||
if ( geometryShaderFilename != "" && uf::renderer::device.enabledFeatures.geometryShader ) {
|
||||
geometryShaderFilename = entity.grabURI( geometryShaderFilename, root );
|
||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY, "vxgi");
|
||||
@ -246,36 +243,13 @@ namespace {
|
||||
else if ( tx.name == "voxelRadiance" ) layout.descriptorCount = maxCascades;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
ext::json::forEach( shader.metadata.json["specializationConstants"], [&]( size_t i, ext::json::Value& sc ){
|
||||
uf::stl::string name = sc["name"].as<uf::stl::string>();
|
||||
if ( name == "TEXTURES" ) sc["value"] = (specializationConstants[i] = maxTextures);
|
||||
else if ( name == "CASCADES" ) sc["value"] = (specializationConstants[i] = maxCascades);
|
||||
});
|
||||
ext::json::forEach( shader.metadata.json["definitions"]["textures"], [&]( ext::json::Value& t ){
|
||||
size_t binding = t["binding"].as<size_t>();
|
||||
uf::stl::string name = t["name"].as<uf::stl::string>();
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != binding ) continue;
|
||||
if ( name == "samplerTextures" ) layout.descriptorCount = maxTextures;
|
||||
else if ( name == "voxelId" ) layout.descriptorCount = maxCascades;
|
||||
else if ( name == "voxelUv" ) layout.descriptorCount = maxCascades;
|
||||
else if ( name == "voxelNormal" ) layout.descriptorCount = maxCascades;
|
||||
else if ( name == "voxelRadiance" ) layout.descriptorCount = maxCascades;
|
||||
else if ( name == "voxelDepth" ) layout.descriptorCount = maxCascades;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.material );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.texture );
|
||||
shader.buffers.emplace_back().aliasBuffer( uf::graph::storage.buffers.light );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// graphic.process = true;
|
||||
#endif
|
||||
}
|
||||
void initializeGraphics( pod::Graph& graph, uf::Object& entity ) {
|
||||
auto& graphic = entity.getComponent<uf::Graphic>();
|
||||
|
||||
@ -44,6 +44,9 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
transform.reference = &controller.getComponent<pod::Transform<>>();
|
||||
}
|
||||
});
|
||||
this->addHook( "object:Reload.%UID%", [&](ext::json::Value& json){
|
||||
this->callHook("object:UpdateMetadata.%UID%", json);
|
||||
});
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](ext::json::Value& json){
|
||||
if ( ext::json::isNull( json ) ) return;
|
||||
if ( json["type"].as<uf::stl::string>() == "merge" ) {
|
||||
@ -105,7 +108,7 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
|
||||
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](){
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](ext::json::Value& json){
|
||||
metadata.deserialize(self, metadataJson);
|
||||
});
|
||||
metadata.deserialize(self, metadataJson);
|
||||
|
||||
@ -47,6 +47,14 @@ void uf::GraphBehavior::initialize( uf::Object& self ) {
|
||||
sceneMetadataJson["light"]["fog"] = graph.metadata["fog"];
|
||||
shouldUpdate = true;
|
||||
}
|
||||
if ( !ext::json::isNull(graph.metadata["gamma"]) ) {
|
||||
sceneMetadataJson["light"]["gamma"] = graph.metadata["gamma"];
|
||||
shouldUpdate = true;
|
||||
}
|
||||
if ( !ext::json::isNull(graph.metadata["brightnessThreshold"]) ) {
|
||||
sceneMetadataJson["light"]["brightnessThreshold"] = graph.metadata["brightnessThreshold"];
|
||||
shouldUpdate = true;
|
||||
}
|
||||
if ( shouldUpdate ) scene.callHook("object:UpdateMetadata.%UID%");
|
||||
|
||||
// deferred shader loading
|
||||
|
||||
@ -41,6 +41,7 @@ bool ext::opengl::settings::experimental::hdr = true;
|
||||
bool ext::opengl::settings::experimental::vxgi = true;
|
||||
bool ext::opengl::settings::experimental::deferredSampling = true;
|
||||
bool ext::opengl::settings::experimental::culling = false;
|
||||
bool ext::opengl::settings::experimental::bloom = false;
|
||||
|
||||
GLhandle(VkColorSpaceKHR) ext::opengl::settings::formats::colorSpace;
|
||||
ext::opengl::enums::Format::type_t ext::opengl::settings::formats::color = ext::opengl::enums::Format::R8G8B8A8_UNORM;
|
||||
|
||||
@ -325,6 +325,9 @@ PIPELINE_INITIALIZATION_INVALID:
|
||||
return;
|
||||
}
|
||||
void ext::vulkan::Pipeline::record( const Graphic& graphic, VkCommandBuffer commandBuffer, size_t pass, size_t draw ) const {
|
||||
return record( graphic, descriptor, commandBuffer, pass, draw );
|
||||
}
|
||||
void ext::vulkan::Pipeline::record( const Graphic& graphic, const GraphicDescriptor& descriptor, VkCommandBuffer commandBuffer, size_t pass, size_t draw ) const {
|
||||
auto bindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
auto shaders = getShaders( graphic.material.shaders );
|
||||
for ( auto* shader : shaders ) {
|
||||
@ -424,7 +427,8 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto& texture : graphic.material.textures ) {
|
||||
auto& textures = !shader->textures.empty() ? shader->textures : graphic.material.textures;
|
||||
for ( auto& texture : textures ) {
|
||||
infos.image.emplace_back(texture.descriptor);
|
||||
switch ( texture.viewType ) {
|
||||
case VK_IMAGE_VIEW_TYPE_2D: infos.image2D.emplace_back(texture.descriptor); break;
|
||||
@ -957,7 +961,7 @@ void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, const GraphicD
|
||||
return;
|
||||
}
|
||||
if ( !pipeline.metadata.process ) return;
|
||||
pipeline.record(*this, commandBuffer, pass, draw);
|
||||
pipeline.record(*this, descriptor, commandBuffer, pass, draw);
|
||||
|
||||
auto shaders = pipeline.getShaders( material.shaders );
|
||||
for ( auto* shader : shaders ) if ( shader->descriptor.stage == VK_SHADER_STAGE_COMPUTE_BIT ) return;
|
||||
|
||||
@ -38,105 +38,115 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( settings::experimental::bloom ) settings::experimental::deferredAliasOutputToSwapchain = false;
|
||||
|
||||
ext::vulkan::RenderMode::initialize( device );
|
||||
renderTarget.device = &device;
|
||||
renderTarget.views = metadata.eyes;
|
||||
size_t msaa = ext::vulkan::settings::msaa;
|
||||
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
|
||||
struct {
|
||||
size_t id, normals, uvs, albedo, depth, output, debug;
|
||||
} attachments = {};
|
||||
|
||||
attachments.id = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_UINT,
|
||||
struct {
|
||||
size_t id, normals, uvs, albedo, depth, color, bright, scratch, output;
|
||||
} attachments = {};
|
||||
|
||||
attachments.id = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_UINT,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
/*.blend = */false,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
attachments.normals = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_SFLOAT,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
/*.blend = */false,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
if ( ext::vulkan::settings::experimental::deferredSampling ) {
|
||||
attachments.uvs = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_UNORM,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
/*.blend = */false,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
attachments.normals = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_SFLOAT,
|
||||
} else {
|
||||
attachments.albedo = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R8G8B8A8_UNORM,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
/*.blend = */false,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
if ( ext::vulkan::settings::experimental::deferredSampling ) {
|
||||
attachments.uvs = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_UNORM,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
/*.blend = */false,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
} else {
|
||||
attachments.albedo = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R8G8B8A8_UNORM,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
/*.blend = */true,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
}
|
||||
attachments.depth = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */ext::vulkan::settings::formats::depth,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
/*.usage = */VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
/*.blend = */false,
|
||||
/*.blend = */true,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
}
|
||||
attachments.depth = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */ext::vulkan::settings::formats::depth,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
/*.usage = */VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
/*.blend = */false,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
attachments.color = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
|
||||
/*.blend =*/ true,
|
||||
/*.samples =*/ 1,
|
||||
});
|
||||
attachments.bright = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
|
||||
/*.blend =*/ true,
|
||||
/*.samples =*/ 1,
|
||||
});
|
||||
attachments.scratch = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
|
||||
/*.blend =*/ true,
|
||||
/*.samples =*/ 1,
|
||||
});
|
||||
|
||||
// Attach swapchain's image as output
|
||||
if ( settings::experimental::deferredAliasOutputToSwapchain ) {
|
||||
attachments.output = renderTarget.attachments.size();
|
||||
auto& swapchainAttachment = renderTarget.attachments.emplace_back();
|
||||
swapchainAttachment.descriptor.format = ext::vulkan::settings::formats::color; //device.formats.color;
|
||||
swapchainAttachment.descriptor.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
swapchainAttachment.descriptor.layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
swapchainAttachment.descriptor.aliased = true;
|
||||
{
|
||||
VkBool32 blendEnabled = VK_TRUE;
|
||||
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState(
|
||||
writeMask,
|
||||
blendEnabled
|
||||
);
|
||||
if ( blendEnabled == VK_TRUE ) {
|
||||
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
}
|
||||
swapchainAttachment.blendState = blendAttachmentState;
|
||||
// Attach swapchain's image as output
|
||||
if ( settings::experimental::deferredAliasOutputToSwapchain ) {
|
||||
attachments.output = renderTarget.attachments.size();
|
||||
auto& swapchainAttachment = renderTarget.attachments.emplace_back();
|
||||
swapchainAttachment.descriptor.format = ext::vulkan::settings::formats::color; //device.formats.color;
|
||||
swapchainAttachment.descriptor.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
swapchainAttachment.descriptor.layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
swapchainAttachment.descriptor.aliased = true;
|
||||
{
|
||||
VkBool32 blendEnabled = VK_TRUE;
|
||||
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState(
|
||||
writeMask,
|
||||
blendEnabled
|
||||
);
|
||||
if ( blendEnabled == VK_TRUE ) {
|
||||
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
}
|
||||
} else {
|
||||
attachments.output = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R8G8B8A8_UNORM,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
/*.blend =*/ true,
|
||||
/*.samples =*/ 1,
|
||||
});
|
||||
swapchainAttachment.blendState = blendAttachmentState;
|
||||
}
|
||||
attachments.debug = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
} else {
|
||||
attachments.output = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
/*.blend =*/ false,
|
||||
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
/*.blend =*/ true,
|
||||
/*.samples =*/ 1,
|
||||
});
|
||||
metadata.outputs.emplace_back(attachments.output);
|
||||
#if 0
|
||||
attachments.debug = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16B16A16_SFLOAT,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
|
||||
/*.blend = */false,
|
||||
/*.samples = */1,
|
||||
});
|
||||
#endif
|
||||
}
|
||||
metadata.outputs.emplace_back(attachments.color);
|
||||
// metadata.outputs.emplace_back(attachments.output);
|
||||
|
||||
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
|
||||
if ( ext::vulkan::settings::experimental::deferredSampling ) {
|
||||
// First pass: fill the G-Buffer
|
||||
{
|
||||
@ -144,24 +154,38 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
/*.*/ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
/*.colors =*/ { attachments.id, attachments.normals, attachments.uvs },
|
||||
/*.inputs =*/ {},
|
||||
/*.resolve =*/ {},
|
||||
/*.resolve =*/{},
|
||||
/*.depth = */ attachments.depth,
|
||||
/*.layer = */0,
|
||||
/*.layer = */eye,
|
||||
/*.autoBuildPipeline =*/ true
|
||||
);
|
||||
}
|
||||
// Second pass: write to output
|
||||
// Second pass: write to color
|
||||
{
|
||||
renderTarget.addPass(
|
||||
/*.*/ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
/*.colors =*/ { attachments.output, attachments.debug },
|
||||
/*.colors =*/ { attachments.color, attachments.bright },
|
||||
/*.inputs =*/ { attachments.id, attachments.normals, attachments.uvs, attachments.depth },
|
||||
/*.resolve =*/ {},
|
||||
/*.depth = */ attachments.depth,
|
||||
/*.layer = */0,
|
||||
/*.resolve =*/{},
|
||||
/*.depth = */attachments.depth,
|
||||
/*.layer = */eye,
|
||||
/*.autoBuildPipeline =*/ false
|
||||
);
|
||||
}
|
||||
#if 0
|
||||
// Third pass: solely to transition
|
||||
if ( settings::experimental::bloom ) {
|
||||
renderTarget.addPass(
|
||||
/*.*/ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
/*.colors =*/ {},
|
||||
/*.inputs =*/ { attachments.color, attachments.bright, attachments.scratch, attachments.output, attachments.depth },
|
||||
/*.resolve =*/{},
|
||||
/*.depth = */ attachments.depth,
|
||||
/*.layer = */eye,
|
||||
/*.autoBuildPipeline =*/ false
|
||||
);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// First pass: fill the G-Buffer
|
||||
{
|
||||
@ -169,26 +193,41 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
/*.*/ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
/*.colors =*/ { attachments.id, attachments.normals, attachments.albedo },
|
||||
/*.inputs =*/ {},
|
||||
/*.resolve =*/ {},
|
||||
/*.resolve =*/{},
|
||||
/*.depth = */ attachments.depth,
|
||||
/*.layer = */0,
|
||||
/*.layer = */eye,
|
||||
/*.autoBuildPipeline =*/ true
|
||||
);
|
||||
}
|
||||
// Second pass: write to output
|
||||
// Second pass: write to color
|
||||
{
|
||||
renderTarget.addPass(
|
||||
/*.*/ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
/*.colors =*/ { attachments.output, attachments.debug },
|
||||
/*.colors =*/ { attachments.color, attachments.bright },
|
||||
/*.inputs =*/ { attachments.id, attachments.normals, attachments.albedo, attachments.depth },
|
||||
/*.resolve =*/ {},
|
||||
/*.resolve =*/{},
|
||||
/*.depth = */ attachments.depth,
|
||||
/*.layer = */0,
|
||||
/*.layer = */eye,
|
||||
/*.autoBuildPipeline =*/ false
|
||||
);
|
||||
}
|
||||
#if 0
|
||||
// Third pass: solely to transition
|
||||
if ( settings::experimental::bloom ) {
|
||||
renderTarget.addPass(
|
||||
/*.*/ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
|
||||
/*.colors =*/ {},
|
||||
/*.inputs =*/ { attachments.color, attachments.bright, attachments.scratch, attachments.output, attachments.depth },
|
||||
/*.resolve =*/{},
|
||||
/*.depth = */ attachments.depth,
|
||||
/*.layer = */eye,
|
||||
/*.autoBuildPipeline =*/ false
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
renderTarget.initialize( device );
|
||||
|
||||
{
|
||||
@ -215,25 +254,40 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
blitter.initializeMesh( mesh );
|
||||
|
||||
uf::stl::string vertexShaderFilename = uf::io::root+"/shaders/display/subpass.vert.spv";
|
||||
uf::stl::string fragmentShaderFilename = uf::io::root+"/shaders/display/subpass.frag.spv";
|
||||
if ( uf::renderer::settings::experimental::vxgi ) {
|
||||
fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", "vxgi.frag" );
|
||||
}
|
||||
if ( msaa > 1 ) {
|
||||
fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", "msaa.frag" );
|
||||
}
|
||||
if ( uf::renderer::settings::experimental::deferredSampling ) {
|
||||
fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", "deferredSampling.frag" );
|
||||
uf::stl::string fragmentShaderFilename = uf::io::root+"/shaders/display/subpass.frag.spv"; {
|
||||
std::pair<bool, uf::stl::string> settings[] = {
|
||||
{ uf::renderer::settings::experimental::vxgi, "vxgi.frag" },
|
||||
{ msaa > 1, "msaa.frag" },
|
||||
{ uf::renderer::settings::experimental::deferredSampling, "deferredSampling.frag" },
|
||||
};
|
||||
FOR_ARRAY( settings ) if ( settings[i].first ) fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", settings[i].second );
|
||||
}
|
||||
|
||||
blitter.material.initializeShaders({
|
||||
{uf::io::resolveURI(vertexShaderFilename), VK_SHADER_STAGE_VERTEX_BIT},
|
||||
{uf::io::resolveURI(fragmentShaderFilename), VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||
});
|
||||
{
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
||||
|
||||
if ( settings::experimental::bloom ) {
|
||||
uf::stl::string computeShaderFilename = uf::io::resolveURI(uf::io::root+"/shaders/display/bloom.comp.spv");
|
||||
blitter.material.attachShader(computeShaderFilename, uf::renderer::enums::Shader::COMPUTE, "bloom");
|
||||
|
||||
auto& shader = blitter.material.getShader("compute", "bloom");
|
||||
shader.textures.clear();
|
||||
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[attachments.color], (size_t) 0 );
|
||||
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[attachments.bright], (size_t) 0 );
|
||||
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[attachments.scratch], (size_t) 0 );
|
||||
for ( auto& texture : shader.textures ) {
|
||||
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
}
|
||||
{
|
||||
auto& shader = blitter.material.getShader("fragment");
|
||||
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
|
||||
|
||||
size_t maxLights = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>(512);
|
||||
size_t maxTextures2D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["2D"].as<size_t>(512);
|
||||
size_t maxTexturesCube = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["cube"].as<size_t>(128);
|
||||
@ -267,28 +321,6 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
else if ( tx.name == "voxelRadiance" ) layout.descriptorCount = maxCascades;
|
||||
}
|
||||
}
|
||||
/*
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
ext::json::forEach( shader.metadata.json["specializationConstants"], [&]( size_t i, ext::json::Value& sc ){
|
||||
uf::stl::string name = sc["name"].as<uf::stl::string>();
|
||||
if ( name == "TEXTURES" ) sc["value"] = (specializationConstants[i] = maxTextures2D);
|
||||
else if ( name == "CUBEMAPS" ) sc["value"] = (specializationConstants[i] = maxTexturesCube);
|
||||
else if ( name == "CASCADES" ) sc["value"] = (specializationConstants[i] = maxCascades);
|
||||
});
|
||||
ext::json::forEach( shader.metadata.json["definitions"]["textures"], [&]( ext::json::Value& t ){
|
||||
size_t binding = t["binding"].as<size_t>();
|
||||
uf::stl::string name = t["name"].as<uf::stl::string>();
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != binding ) continue;
|
||||
if ( name == "samplerTextures" ) layout.descriptorCount = maxTextures2D;
|
||||
else if ( name == "samplerCubemaps" ) layout.descriptorCount = maxTexturesCube;
|
||||
else if ( name == "voxelId" ) layout.descriptorCount = maxCascades;
|
||||
else if ( name == "voxelUv" ) layout.descriptorCount = maxCascades;
|
||||
else if ( name == "voxelNormal" ) layout.descriptorCount = maxCascades;
|
||||
else if ( name == "voxelRadiance" ) layout.descriptorCount = maxCascades;
|
||||
}
|
||||
});
|
||||
*/
|
||||
} else {
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
||||
@ -304,63 +336,22 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
||||
else if ( tx.name == "samplerCubemaps" ) layout.descriptorCount = maxTexturesCube;
|
||||
}
|
||||
}
|
||||
/*
|
||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
||||
ext::json::forEach( shader.metadata.json["specializationConstants"], [&]( size_t i, ext::json::Value& sc ){
|
||||
uf::stl::string name = sc["name"].as<uf::stl::string>();
|
||||
if ( name == "TEXTURES" ) sc["value"] = (specializationConstants[i] = maxTextures2D);
|
||||
else if ( name == "CUBEMAPS" ) sc["value"] = (specializationConstants[i] = maxTexturesCube);
|
||||
});
|
||||
|
||||
ext::json::forEach( shader.metadata.json["definitions"]["textures"], [&]( ext::json::Value& t ){
|
||||
size_t binding = t["binding"].as<size_t>();
|
||||
uf::stl::string name = t["name"].as<uf::stl::string>();
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != binding ) continue;
|
||||
if ( name == "samplerTextures" ) layout.descriptorCount = maxTextures2D;
|
||||
else if ( name == "samplerCubemaps" ) layout.descriptorCount = maxTexturesCube;
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
/*
|
||||
uf::stl::vector<pod::Light> lights(maxLights);
|
||||
uf::stl::vector<pod::Material> materials(maxTextures2D);
|
||||
uf::stl::vector<pod::Texture> textures(maxTextures2D);
|
||||
uf::stl::vector<pod::DrawCommand> drawCommands(maxTextures2D);
|
||||
|
||||
for ( auto& material : materials ) material.colorBase = {0,0,0,0};
|
||||
metadata.lightBufferIndex = shader.initializeBuffer(
|
||||
(const void*) lights.data(),
|
||||
lights.size() * sizeof(pod::Light),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
metadata.materialBufferIndex = shader.initializeBuffer(
|
||||
(const void*) materials.data(),
|
||||
materials.size() * sizeof(pod::Material),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
|
||||
metadata.textureBufferIndex = shader.initializeBuffer(
|
||||
(const void*) textures.data(),
|
||||
textures.size() * sizeof(pod::Texture),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
|
||||
metadata.drawCallBufferIndex = shader.initializeBuffer(
|
||||
(const void*) drawCommands.data(),
|
||||
drawCommands.size() * sizeof(pod::DrawCommand),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
);
|
||||
*/
|
||||
}
|
||||
// blitter.initializePipeline();
|
||||
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
|
||||
blitter.descriptor.subpass = 2 * eye + 1;
|
||||
if ( blitter.hasPipeline( blitter.descriptor ) ) continue;
|
||||
blitter.initializePipeline( blitter.descriptor );
|
||||
auto descriptor = blitter.descriptor;
|
||||
descriptor.subpass = (renderTarget.passes.size() / metadata.eyes) * eye + 1;
|
||||
if ( !blitter.hasPipeline( descriptor ) ) blitter.initializePipeline( descriptor );
|
||||
|
||||
if ( settings::experimental::bloom ) {
|
||||
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };
|
||||
descriptor.pipeline = "bloom";
|
||||
descriptor.subpass = 0;
|
||||
if ( !blitter.hasPipeline( descriptor ) ) {
|
||||
blitter.initializePipeline( descriptor );
|
||||
}
|
||||
}
|
||||
}
|
||||
blitter.descriptor.subpass = 1;
|
||||
}
|
||||
}
|
||||
void ext::vulkan::DeferredRenderMode::tick() {
|
||||
@ -371,15 +362,37 @@ void ext::vulkan::DeferredRenderMode::tick() {
|
||||
|
||||
if ( resized ) {
|
||||
renderTarget.initialize( *renderTarget.device );
|
||||
|
||||
if ( settings::experimental::bloom ) {
|
||||
auto& shader = blitter.material.getShader("compute", "bloom");
|
||||
#if 1
|
||||
shader.textures.clear();
|
||||
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[renderTarget.attachments.size() - 5], (size_t) 0 ); // attachments.color
|
||||
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[renderTarget.attachments.size() - 4], (size_t) 0 ); // attachments.bright
|
||||
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[renderTarget.attachments.size() - 3], (size_t) 0 ); // attachments.scratch
|
||||
for ( auto& texture : shader.textures ) {
|
||||
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// update blitter descriptor set
|
||||
if ( rebuild && blitter.initialized ) {
|
||||
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
|
||||
blitter.descriptor.subpass = 2 * eye + 1;
|
||||
if ( !blitter.hasPipeline( blitter.descriptor ) ) continue;
|
||||
blitter.getPipeline( blitter.descriptor ).update( blitter, blitter.descriptor );
|
||||
auto descriptor = blitter.descriptor;
|
||||
descriptor.subpass = (renderTarget.passes.size() / metadata.eyes) * eye + 1;
|
||||
if ( blitter.hasPipeline( blitter.descriptor ) ) blitter.getPipeline( blitter.descriptor ).update( blitter, blitter.descriptor );
|
||||
|
||||
if ( settings::experimental::bloom ) {
|
||||
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };
|
||||
descriptor.pipeline = "bloom";
|
||||
descriptor.subpass = 0;
|
||||
if ( blitter.hasPipeline( descriptor ) ) {
|
||||
blitter.getPipeline( descriptor ).update( blitter, descriptor );
|
||||
}
|
||||
}
|
||||
}
|
||||
blitter.descriptor.subpass = 1;
|
||||
}
|
||||
}
|
||||
void ext::vulkan::DeferredRenderMode::destroy() {
|
||||
@ -530,6 +543,57 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
|
||||
}
|
||||
vkCmdEndRenderPass(commands[i]);
|
||||
|
||||
if ( settings::experimental::bloom ) {
|
||||
ext::vulkan::GraphicDescriptor descriptor = blitter.descriptor;
|
||||
descriptor.inputs.dispatch = { (width / 8) + 1, (height / 8) + 1, 1 };
|
||||
descriptor.pipeline = "bloom";
|
||||
descriptor.subpass = 0;
|
||||
|
||||
auto& shader = blitter.material.getShader("compute", "bloom");
|
||||
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
for ( auto& attachment : shader.textures ) {
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_FLAGS_NONE, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
}
|
||||
#if 0
|
||||
blitter.record(commands[i], descriptor, 0, 0);
|
||||
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
for ( auto& attachment : shader.textures ) {
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_FLAGS_NONE, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
}
|
||||
#endif
|
||||
blitter.record(commands[i], descriptor, 0, 1);
|
||||
for ( auto& attachment : shader.textures ) {
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_FLAGS_NONE, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
}
|
||||
blitter.record(commands[i], descriptor, 0, 2);
|
||||
for ( auto& attachment : shader.textures ) {
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_FLAGS_NONE, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
}
|
||||
for ( auto& attachment : shader.textures ) {
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_FLAGS_NONE, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
}
|
||||
blitter.record(commands[i], descriptor, 0, 3);
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
for ( auto& attachment : shader.textures ) {
|
||||
imageMemoryBarrier.image = attachment.image;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_FLAGS_NONE, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto layer : layers ) {
|
||||
layer->pipelineBarrier( commands[i], 1 );
|
||||
}
|
||||
@ -581,7 +645,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
// outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
{
|
||||
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
|
||||
@ -608,10 +672,10 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
|
||||
imageMemoryBarrier.image = outputAttachment.image;
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = outputAttachment.descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; //outputAttachment.descriptor.layout;
|
||||
imageMemoryBarrier.newLayout = outputAttachment.descriptor.layout; //VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
|
||||
outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
// outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
|
||||
}
|
||||
{
|
||||
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
|
||||
|
||||
@ -211,7 +211,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
/*.blend = */false,
|
||||
/*.samples = */msaa,
|
||||
});
|
||||
if ( false && ext::vulkan::settings::experimental::deferredMode != "" ) {
|
||||
if ( !true && ext::vulkan::settings::experimental::deferredMode != "" ) {
|
||||
attachments.uvs = renderTarget.attach(RenderTarget::Attachment::Descriptor{
|
||||
/*.format = */VK_FORMAT_R16G16_UNORM,
|
||||
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
@ -242,7 +242,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
/*.blend =*/ true,
|
||||
/*.samples =*/ 1,
|
||||
});
|
||||
if ( false && ext::vulkan::settings::experimental::deferredMode != "" ) {
|
||||
if ( !true && ext::vulkan::settings::experimental::deferredMode != "" ) {
|
||||
// First pass: fill the G-Buffer
|
||||
{
|
||||
renderTarget.addPass(
|
||||
@ -346,16 +346,6 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
else if ( sType == "geometry" ) type = ext::vulkan::enums::Shader::GEOMETRY;
|
||||
else if ( sType == "compute" ) type = ext::vulkan::enums::Shader::COMPUTE;
|
||||
}
|
||||
#if 0
|
||||
if ( type == ext::vulkan::enums::Shader::FRAGMENT ) {
|
||||
if ( msaa > 1 ) {
|
||||
filename = uf::string::replace( filename, "frag", "msaa.frag" );
|
||||
}
|
||||
if ( uf::renderer::settings::experimental::deferredSampling ) {
|
||||
filename = uf::string::replace( filename, "frag", "deferredSampling.frag" );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
blitter.material.attachShader( uf::io::root+filename, type, pipeline );
|
||||
});
|
||||
} else if ( ext::json::isObject( metadata.json["shaders"] ) ) {
|
||||
@ -373,16 +363,6 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
else if ( key == "fragment" ) type = ext::vulkan::enums::Shader::FRAGMENT;
|
||||
else if ( key == "geometry" ) type = ext::vulkan::enums::Shader::GEOMETRY;
|
||||
else if ( key == "compute" ) type = ext::vulkan::enums::Shader::COMPUTE;
|
||||
#if 0
|
||||
if ( type == ext::vulkan::enums::Shader::FRAGMENT ) {
|
||||
if ( msaa > 1 ) {
|
||||
filename = uf::string::replace( filename, "frag", "msaa.frag" );
|
||||
}
|
||||
if ( uf::renderer::settings::experimental::deferredSampling ) {
|
||||
filename = uf::string::replace( filename, "frag", "deferredSampling.frag" );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
blitter.material.attachShader( uf::io::root+filename, type, pipeline );
|
||||
});
|
||||
} else if ( metadata.json["shaders"].is<bool>() && !metadata.json["shaders"].as<bool>() ) {
|
||||
@ -390,13 +370,13 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
blitter.process = false;
|
||||
} else {
|
||||
uf::stl::string vertexShaderFilename = uf::io::root+"/shaders/display/renderTarget.vert.spv";
|
||||
uf::stl::string fragmentShaderFilename = uf::io::root+"/shaders/display/renderTarget.frag.spv";
|
||||
if ( msaa > 1 ) {
|
||||
fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", "msaa.frag" );
|
||||
}
|
||||
// I don't actually have support for deferred sampling within a render target
|
||||
if ( uf::renderer::settings::experimental::deferredSampling ) {
|
||||
// fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", "deferredSampling.frag" );
|
||||
uf::stl::string fragmentShaderFilename = uf::io::root+"/shaders/display/renderTarget.frag.spv"; {
|
||||
std::pair<bool, uf::stl::string> settings[] = {
|
||||
{ msaa > 1, "msaa.frag" },
|
||||
// I don't actually have support for deferred sampling within a render target
|
||||
// { uf::renderer::settings::experimental::deferredSampling, "deferredSampling.frag" },
|
||||
};
|
||||
FOR_ARRAY( settings ) if ( settings[i].first ) fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", settings[i].second );
|
||||
}
|
||||
blitter.material.initializeShaders({
|
||||
{uf::io::resolveURI(vertexShaderFilename), VK_SHADER_STAGE_VERTEX_BIT},
|
||||
|
||||
@ -11,15 +11,15 @@ void ext::vulkan::RenderTarget::addPass( VkPipelineStageFlags stage, VkAccessFla
|
||||
pass.access = access;
|
||||
pass.layer = layer;
|
||||
pass.autoBuildPipeline = autoBuildPipeline;
|
||||
for ( auto& i : colors ) pass.colors.push_back( { (uint32_t) i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL } );
|
||||
for ( auto& i : inputs ) pass.inputs.push_back( { (uint32_t) i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } );
|
||||
for ( auto& i : resolves ) pass.resolves.push_back( { (uint32_t) i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } );
|
||||
for ( auto& i : colors ) pass.colors.emplace_back( VkAttachmentReference{ (uint32_t) i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL } );
|
||||
for ( auto& i : inputs ) pass.inputs.emplace_back( VkAttachmentReference{ (uint32_t) i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } );
|
||||
for ( auto& i : resolves ) pass.resolves.emplace_back( VkAttachmentReference{ (uint32_t) i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } );
|
||||
if ( depth < attachments.size() ) pass.depth = { (uint32_t) depth, attachments[depth].descriptor.layout };
|
||||
|
||||
if ( !resolves.empty() && resolves.size() != colors.size() )
|
||||
VK_VALIDATION_MESSAGE("Mismatching resolves count: Expecting " << colors.size() << ", got " << resolves.size());
|
||||
|
||||
passes.push_back(pass);
|
||||
passes.emplace_back(pass);
|
||||
}
|
||||
size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descriptor, Attachment* attachment ) {
|
||||
if ( this->views == 0 ) this->views = 1;
|
||||
@ -180,7 +180,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
description.finalLayout = attachment.descriptor.layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : attachment.descriptor.layout;
|
||||
description.flags = 0;
|
||||
|
||||
attachments.push_back(description);
|
||||
attachments.emplace_back(description);
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,7 +208,9 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
size_t i = 0;
|
||||
// std::cout << this << ": " << std::endl;
|
||||
#if 0
|
||||
UF_MSG_DEBUG(this << ": ");
|
||||
#endif
|
||||
for ( auto& pass : passes ) {
|
||||
VkSubpassDescription description;
|
||||
// describe renderpass
|
||||
@ -228,13 +230,12 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
descriptions.push_back(description);
|
||||
descriptions.emplace_back(description);
|
||||
|
||||
#if 0
|
||||
UF_MSG_DEBUG("Pass: " << descriptions.size() - 1);
|
||||
for ( auto& color : pass.colors ) UF_MSG_DEBUG("Color: " << color.attachment << "\t" << std::hex << color.layout << "\t" << this->attachments[color.attachment].image);
|
||||
for ( auto& input : pass.inputs ) UF_MSG_DEBUG("Input: " << input.attachment << "\t" << std::hex << input.layout << "\t" << this->attachments[input.attachment].image);
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
// transition dependency between subpasses
|
||||
dependency.srcSubpass = dependency.dstSubpass;
|
||||
@ -243,7 +244,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
dependency.dstSubpass = i++;
|
||||
dependency.dstStageMask = pass.stage;
|
||||
dependency.dstAccessMask = pass.access;
|
||||
dependencies.push_back(dependency);
|
||||
dependencies.emplace_back(dependency);
|
||||
}
|
||||
// dependency: transition to final
|
||||
{
|
||||
@ -253,7 +254,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
dependencies.push_back(dependency);
|
||||
dependencies.emplace_back(dependency);
|
||||
}
|
||||
|
||||
// depth dependency
|
||||
@ -270,7 +271,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||
dependency.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
dependencies.push_back(dependency);
|
||||
dependencies.emplace_back(dependency);
|
||||
}
|
||||
{
|
||||
VkSubpassDependency dependency;
|
||||
@ -284,7 +285,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
dependency.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
|
||||
dependencies.push_back(dependency);
|
||||
dependencies.emplace_back(dependency);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -293,7 +294,6 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
UF_MSG_DEBUG("\tStage: " << std::hex << dependency.srcStageMask << " -> " << std::hex << dependency.dstStageMask);
|
||||
UF_MSG_DEBUG("\tAccess: " << std::hex << dependency.srcAccessMask << " -> " << std::hex << dependency.dstAccessMask);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
VkRenderPassCreateInfo renderPassInfo = {};
|
||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
@ -327,7 +327,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
*/
|
||||
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass));
|
||||
|
||||
// std::cout << renderPass << ": " << attachments.size() << std::endl;
|
||||
// UF_MSG_DEBUG(renderPass << ": " << attachments.size());
|
||||
}
|
||||
{
|
||||
// destroy previous framebuffers
|
||||
@ -340,8 +340,8 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
|
||||
for ( size_t j = 0; j < this->views; ++j ) {
|
||||
for ( auto& attachment : this->attachments ) {
|
||||
if ( attachment.descriptor.aliased && attachment.descriptor.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ) {
|
||||
attachmentViews.push_back(base.renderTarget.attachments[i].view);
|
||||
} else attachmentViews.push_back(attachment.views[j]);
|
||||
attachmentViews.emplace_back(base.renderTarget.attachments[i].view);
|
||||
} else attachmentViews.emplace_back(attachment.views[j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +41,7 @@ bool ext::vulkan::settings::experimental::hdr = true;
|
||||
bool ext::vulkan::settings::experimental::vxgi = true;
|
||||
bool ext::vulkan::settings::experimental::deferredSampling = true;
|
||||
bool ext::vulkan::settings::experimental::culling = false;
|
||||
bool ext::vulkan::settings::experimental::bloom = false;
|
||||
|
||||
VkColorSpaceKHR ext::vulkan::settings::formats::colorSpace;
|
||||
ext::vulkan::enums::Format::type_t ext::vulkan::settings::formats::color = ext::vulkan::enums::Format::R8G8B8A8_UNORM;
|
||||
|
||||
@ -99,7 +99,7 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
|
||||
renderMode.height = size.y;
|
||||
}
|
||||
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](){
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](ext::json::Value& json){
|
||||
metadata.deserialize(self, metadataJson);
|
||||
});
|
||||
metadata.deserialize(self, metadataJson);
|
||||
|
||||
@ -121,7 +121,7 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
|
||||
this->queueHook("discord.Activity.Update.%UID%", ext::json::null(), 1.0);
|
||||
#endif
|
||||
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](){
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](ext::json::Value& json){
|
||||
metadata.deserialize(self, metadataJson);
|
||||
});
|
||||
metadata.deserialize(self, metadataJson);
|
||||
|
||||
@ -28,7 +28,7 @@ void ext::PlayerModelBehavior::initialize( uf::Object& self ) {
|
||||
|
||||
metadata.reference = &controllerTransform;
|
||||
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](){
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](ext::json::Value& json){
|
||||
metadata.deserialize(self, metadataJson);
|
||||
});
|
||||
metadata.deserialize(self, metadataJson);
|
||||
|
||||
@ -190,7 +190,7 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](){
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&]( ext::json::Value& json ){
|
||||
metadata.deserialize(self, metadataJson);
|
||||
});
|
||||
metadata.deserialize(self, metadataJson);
|
||||
@ -502,6 +502,7 @@ void ext::ExtSceneBehavior::Metadata::serialize( uf::Object& self, uf::Serialize
|
||||
serializer["light"]["specular"] = uf::vector::encode( /*this->*/light.specular );
|
||||
serializer["light"]["exposure"] = /*this->*/light.exposure;
|
||||
serializer["light"]["gamma"] = /*this->*/light.gamma;
|
||||
serializer["light"]["brightnessThreshold"] = /*this->*/light.brightnessThreshold;
|
||||
|
||||
serializer["light"]["fog"]["color"] = uf::vector::encode( /*this->*/fog.color );
|
||||
serializer["light"]["fog"]["step scale"] = /*this->*/fog.stepScale;
|
||||
@ -518,26 +519,30 @@ void ext::ExtSceneBehavior::Metadata::serialize( uf::Object& self, uf::Serialize
|
||||
serializer["system"]["renderer"]["shader"]["parameters"] = uf::vector::encode( /*this->*/shader.parameters );
|
||||
}
|
||||
void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ) {
|
||||
if ( !serializer["light"]["point light eye depth scale"].is<float>() )
|
||||
serializer["light"]["point light eye depth scale"] = ext::config["engine"]["scenes"]["lights"]["point light eye depth scale"];
|
||||
|
||||
/*this->*/max.textures2D = ext::config["engine"]["scenes"]["textures"]["max"]["2D"].as<uint32_t>(/*this->*/max.textures2D);
|
||||
/*this->*/max.texturesCube = ext::config["engine"]["scenes"]["textures"]["max"]["cube"].as<uint32_t>(/*this->*/max.texturesCube);
|
||||
/*this->*/max.textures3D = ext::config["engine"]["scenes"]["textures"]["max"]["3D"].as<uint32_t>(/*this->*/max.textures3D);
|
||||
/*this->*/max.lights = ext::config["engine"]["scenes"]["lights"]["max"].as<uint32_t>(/*this->*/max.lights);
|
||||
|
||||
/*this->*/light.enabled = ext::config["engine"]["scenes"]["lights"]["enabled"].as<bool>(true) && serializer["light"]["should"].as<bool>(true);
|
||||
|
||||
/*this->*/shadow.enabled = ext::config["engine"]["scenes"]["shadows"]["enabled"].as<bool>(true) && serializer["light"]["shadows"].as<bool>(true);
|
||||
/*this->*/shadow.samples = ext::config["engine"]["scenes"]["shadows"]["samples"].as<uint32_t>();
|
||||
/*this->*/shadow.max = ext::config["engine"]["scenes"]["shadows"]["max"].as<uint32_t>();
|
||||
/*this->*/shadow.update = ext::config["engine"]["scenes"]["shadows"]["update"].as<uint32_t>();
|
||||
/*this->*/shadow.experimentalMode = ext::config["engine"]["scenes"]["shadows"]["experimental mode"].as<uint32_t>(0);
|
||||
|
||||
/*this->*/light.enabled = ext::config["engine"]["scenes"]["lights"]["enabled"].as<bool>(true) && serializer["light"]["should"].as<bool>(true);
|
||||
/*this->*/light.ambient = uf::vector::decode( serializer["light"]["ambient"], pod::Vector4f{ 1, 1, 1, 1 } );
|
||||
/*this->*/light.specular = uf::vector::decode( serializer["light"]["specular"], pod::Vector4f{ 1, 1, 1, 1 } );
|
||||
/*this->*/light.exposure = serializer["light"]["exposure"].as<float>(1.0f);
|
||||
/*this->*/light.gamma = serializer["light"]["gamma"].as<float>(2.2f);
|
||||
/*this->*/light.brightnessThreshold = serializer["light"]["brightnessThreshold"].as<float>(ext::config["engine"]["scenes"]["bloom"]["brightnessThreshold"].as<float>(1.0f));
|
||||
|
||||
UF_MSG_DEBUG( serializer["bloom"] );
|
||||
|
||||
/*this->*/bloom.scale = serializer["bloom"]["scale"].as(ext::config["engine"]["scenes"]["bloom"]["scale"].as(bloom.scale));
|
||||
/*this->*/bloom.strength = serializer["bloom"]["strength"].as(ext::config["engine"]["scenes"]["bloom"]["strength"].as(bloom.strength));
|
||||
/*this->*/bloom.sigma = serializer["bloom"]["sigma"].as(ext::config["engine"]["scenes"]["bloom"]["sigma"].as(bloom.sigma));
|
||||
/*this->*/bloom.samples = serializer["bloom"]["samples"].as(ext::config["engine"]["scenes"]["bloom"]["samples"].as(bloom.samples));
|
||||
|
||||
/*this->*/fog.color = uf::vector::decode( serializer["light"]["fog"]["color"], pod::Vector3f{ 1, 1, 1 } );
|
||||
/*this->*/fog.stepScale = serializer["light"]["fog"]["step scale"].as<float>();
|
||||
@ -561,6 +566,39 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali
|
||||
#if UF_USE_OPENGL_FIXED_FUNCTION
|
||||
uf::renderer::states::rebuild = true;
|
||||
#endif
|
||||
|
||||
if ( uf::renderer::settings::experimental::bloom ) {
|
||||
auto& renderMode = uf::renderer::getRenderMode("", true);
|
||||
auto& blitter = *renderMode.getBlitters().front();
|
||||
auto& shader = blitter.material.getShader("compute", "bloom");
|
||||
|
||||
struct UniformDescriptor {
|
||||
float scale;
|
||||
float strength;
|
||||
float threshold;
|
||||
float sigma;
|
||||
|
||||
float gamma;
|
||||
float exposure;
|
||||
uint32_t samples;
|
||||
uint32_t padding;
|
||||
};
|
||||
|
||||
UniformDescriptor uniforms = {
|
||||
.scale = bloom.scale,
|
||||
.strength = bloom.strength,
|
||||
.threshold = light.brightnessThreshold,
|
||||
.sigma = bloom.sigma,
|
||||
|
||||
.gamma = light.gamma,
|
||||
.exposure = light.exposure,
|
||||
.samples = bloom.samples,
|
||||
};
|
||||
|
||||
UF_MSG_DEBUG( bloom.scale << " " << bloom.strength << " " << light.brightnessThreshold << " " << bloom.sigma << " " << light.gamma << " " << light.exposure << " " << bloom.samples );
|
||||
|
||||
shader.updateBuffer( uniforms, shader.getUniformBuffer("UBO") );
|
||||
}
|
||||
}
|
||||
|
||||
void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string& renderModeName, bool isCompute ) {
|
||||
@ -574,7 +612,7 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
|
||||
auto& renderMode = uf::renderer::getRenderMode(renderModeName, true);
|
||||
uf::stl::vector<uf::Graphic*> blitters = renderMode.getBlitters();
|
||||
auto blitters = renderMode.getBlitters();
|
||||
|
||||
#if UF_USE_OPENGL
|
||||
struct LightInfo {
|
||||
@ -680,9 +718,14 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string
|
||||
alignas(4) float gamma;
|
||||
|
||||
alignas(4) float exposure;
|
||||
alignas(4) float brightnessThreshold;
|
||||
alignas(4) uint32_t msaa;
|
||||
alignas(4) uint32_t shadowSamples;
|
||||
alignas(4) uint32_t shadowSamples;
|
||||
|
||||
alignas(4) uint32_t indexSkybox;
|
||||
alignas(4) uint32_t padding1;
|
||||
alignas(4) uint32_t padding2;
|
||||
alignas(4) uint32_t padding3;
|
||||
};
|
||||
|
||||
// struct that contains our skybox cubemap, noise texture, and VXGI voxels
|
||||
@ -774,8 +817,10 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string
|
||||
uniforms.gamma = metadata.light.gamma;
|
||||
|
||||
uniforms.exposure = metadata.light.exposure;
|
||||
uniforms.brightnessThreshold = metadata.light.brightnessThreshold;
|
||||
uniforms.msaa = ext::vulkan::settings::msaa;
|
||||
uniforms.shadowSamples = std::min( 0, metadata.shadow.samples );
|
||||
|
||||
uniforms.indexSkybox = indexSkybox;
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,14 @@ namespace ext {
|
||||
pod::Vector4f specular = {1,1,1,1};
|
||||
float exposure = 1.0f;
|
||||
float gamma = 1.0f;
|
||||
float brightnessThreshold = 1.0f;
|
||||
} light;
|
||||
struct {
|
||||
float scale = 1.0f;
|
||||
float strength = 1.0f;
|
||||
float sigma = 0.8f;
|
||||
uint32_t samples = 1;
|
||||
} bloom;
|
||||
struct {
|
||||
bool enabled = true;
|
||||
int samples = 4;
|
||||
|
||||
@ -426,7 +426,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<ext::GuiBehavior::Metadata>();
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](){
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](ext::json::Value& json){
|
||||
metadata.deserialize(self, metadataJson);
|
||||
});
|
||||
metadata.deserialize(self, metadataJson);
|
||||
@ -570,7 +570,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
|
||||
});
|
||||
auto& metadataGlyph = this->getComponent<ext::GuiBehavior::GlyphMetadata>();
|
||||
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](){
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](ext::json::Value& json){
|
||||
metadataGlyph.deserialize(self, metadataJson);
|
||||
});
|
||||
// metadataGlyph.deserialize(self, metadataJson);
|
||||
|
||||
@ -84,7 +84,7 @@ void ext::GuiManagerBehavior::initialize( uf::Object& self ) {
|
||||
}
|
||||
});
|
||||
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](){
|
||||
this->addHook( "object:UpdateMetadata.%UID%", [&](ext::json::Value& json){
|
||||
metadata.deserialize(self, metadataJson);
|
||||
});
|
||||
metadata.deserialize(self, metadataJson);
|
||||
|
||||
@ -354,6 +354,7 @@ void EXT_API ext::initialize() {
|
||||
uf::renderer::settings::experimental::vxgi = ::config["engine"]["ext"][RENDERER]["experimental"]["vxgi"].as( uf::renderer::settings::experimental::vxgi );
|
||||
uf::renderer::settings::experimental::deferredSampling = ::config["engine"]["ext"][RENDERER]["experimental"]["deferred sampling"].as( uf::renderer::settings::experimental::deferredSampling );
|
||||
uf::renderer::settings::experimental::culling = ::config["engine"]["ext"][RENDERER]["experimental"]["culling"].as( uf::renderer::settings::experimental::culling );
|
||||
uf::renderer::settings::experimental::bloom = ::config["engine"]["ext"][RENDERER]["experimental"]["bloom"].as( uf::renderer::settings::experimental::bloom );
|
||||
#define JSON_TO_VKFORMAT( key ) if ( ::config["engine"]["ext"][RENDERER]["formats"][#key].is<uf::stl::string>() ) {\
|
||||
uf::stl::string format = ::config["engine"]["ext"][RENDERER]["formats"][#key].as<uf::stl::string>();\
|
||||
format = uf::string::replace( uf::string::uppercase(format), " ", "_" );\
|
||||
|
||||
Loading…
Reference in New Issue
Block a user