Commit for 2021.02.12.7z

This commit is contained in:
mrq 2021-02-12 00:00:00 -06:00
parent 160c7ff198
commit 23e8aacdfa
22 changed files with 362 additions and 132 deletions

View File

@ -1,22 +1,49 @@
#version 450
layout (binding = 1) uniform sampler2D samplerColor;
#define UF_DEFERRED_SAMPLING 0
#define UF_CAN_DISCARD 1
layout (binding = 1) uniform sampler2D samplerTexture;
layout (location = 0) in vec2 inUv;
layout (location = 1) in vec4 inColor;
layout (location = 2) in vec3 inNormal;
layout (location = 3) in vec3 inPosition;
layout (location = 0) out vec4 outAlbedoSpecular;
layout (location = 1) out vec4 outNormal;
layout (location = 2) out vec4 outPosition;
layout (location = 0) out uvec2 outId;
layout (location = 1) out vec2 outNormals;
#if UF_DEFERRED_SAMPLING
layout (location = 2) out vec2 outUvs;
#else
layout (location = 2) out vec4 outAlbedo;
#endif
vec2 encodeNormals( vec3 n ) {
float p = sqrt(n.z*8+8);
return n.xy/p + 0.5;
}
float mipLevel( in vec2 uv ) {
vec2 dx_vtc = dFdx(uv);
vec2 dy_vtc = dFdy(uv);
return 0.5 * log2(max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)));
}
void main() {
outAlbedoSpecular = texture(samplerColor, inUv);
if ( outAlbedoSpecular.a < 0.001 ) discard;
outAlbedoSpecular.rgb *= inColor.rgb;
outAlbedoSpecular.a = 1;
outNormal = vec4(inNormal,1);
outPosition = vec4(inPosition,1);
float mip = mipLevel(inUv.xy);
vec2 uv = inUv.xy;
vec4 C = vec4(1, 1, 1, 1);
vec3 P = inPosition;
vec3 N = inNormal;
#if UF_DEFERRED_SAMPLING
outUvs = wrap(inUv.xy);
vec4 outAlbedo = vec4(0,0,0,0);
#endif
#if !UF_DEFERRED_SAMPLING || UF_CAN_DISCARD
C = textureLod( samplerTexture, uv, mip );
#endif
#if !UF_DEFERRED_SAMPLING
outAlbedo = C * inColor;
#endif
outNormals = encodeNormals( N );
//outId = ivec2(0, 0);
}

View File

@ -1,10 +1,17 @@
#version 450
#extension GL_EXT_samplerless_texture_functions : require
#define UF_DEFERRED_SAMPLING 0
#define UF_CAN_DISCARD 1
layout (binding = 1) uniform sampler samp;
layout (binding = 2) uniform texture2D albedoTexture;
layout (binding = 3) uniform texture2D normalTexture;
layout (binding = 4) uniform texture2D positionTexture;
layout (binding = 2) uniform utexture2D textureId;
layout (binding = 3) uniform texture2D textureNormals;
#if UF_DEFERRED_SAMPLING
layout (binding = 4) uniform texture2D textureUvs;
#else
layout (binding = 4) uniform texture2D textureAlbedo;
#endif
struct Cursor {
vec2 position;
@ -16,24 +23,53 @@ layout (location = 0) in vec2 inUv;
layout (location = 1) in float inAlpha;
layout (location = 2) in Cursor inCursor;
layout (location = 0) out vec4 outAlbedoSpecular;
layout (location = 1) out vec4 outNormal;
layout (location = 2) out vec4 outPosition;
layout (location = 0) out vec4 outAlbedo;
void main() {
if ( inCursor.radius.x <= 0 && inCursor.radius.y <= 0 ) {
vec2 uv = gl_FragCoord.xy / textureSize(albedoTexture, 0);
outAlbedoSpecular = texture(sampler2D(albedoTexture, samp), uv);
outNormal = texture(sampler2D(normalTexture, samp), uv);
outPosition = texture(sampler2D(positionTexture, samp), uv);
vec2 uv = gl_FragCoord.xy / textureSize(textureId, 0);
outAlbedo = texture(sampler2D(textureAlbedo, samp), uv).rgba;
return;
}
outAlbedoSpecular = texture(sampler2D(albedoTexture, samp), inUv);
float dist = pow(inUv.x - inCursor.position.x, 2) / pow(inCursor.radius.x, 2) + pow(inUv.y - inCursor.position.y, 2) / pow(inCursor.radius.y, 2);
outAlbedo = texture(sampler2D(textureAlbedo, samp), inUv);
if ( dist <= 1 ) {
float attenuation = dist;
outAlbedoSpecular.rgb = mix( inCursor.color.rgb * inCursor.color.a, outAlbedoSpecular.rgb, attenuation );
outAlbedo.rgb = mix( inCursor.color.rgb * inCursor.color.a, outAlbedo.rgb, attenuation );
}
if ( inAlpha < 1.0 ) outAlbedoSpecular.a = inAlpha;
}
if ( inAlpha < 1.0 ) outAlbedo.a = inAlpha;
}
/*
layout (location = 0) out uvec2 outId;
layout (location = 1) out vec2 outNormals;
#if UF_DEFERRED_SAMPLING
layout (location = 2) out vec2 outUvs;
#else
layout (location = 2) out vec4 outAlbedo;
#endif
void main() {
if ( inCursor.radius.x <= 0 && inCursor.radius.y <= 0 ) {
vec2 uv = gl_FragCoord.xy / textureSize(textureId, 0);
outId = texture(usampler2D(textureId, samp), uv).xy;
outNormals = texture(sampler2D(textureNormals, samp), uv).xy;
#if UF_DEFERRED_SAMPLING
outUvs = texture(sampler2D(textureUvs, samp), uv).xy;
#else
outAlbedo = texture(sampler2D(textureAlbedo, samp), uv).rgba;
#endif
return;
}
float dist = pow(inUv.x - inCursor.position.x, 2) / pow(inCursor.radius.x, 2) + pow(inUv.y - inCursor.position.y, 2) / pow(inCursor.radius.y, 2);
#if !UF_DEFERRED_SAMPLING
outAlbedo = texture(sampler2D(textureAlbedo, samp), inUv);
if ( dist <= 1 ) {
float attenuation = dist;
outAlbedo.rgb = mix( inCursor.color.rgb * inCursor.color.a, outAlbedo.rgb, attenuation );
}
if ( inAlpha < 1.0 ) outAlbedo.a = inAlpha;
#endif
}
*/

View File

@ -2,7 +2,7 @@
#extension GL_EXT_samplerless_texture_functions : require
#define SAMPLES 16
#define POISSON_DISK 4
#define POISSON_DISK 16
#define RAY_MARCH_FOG 0
#define UF_DEFERRED_SAMPLING 0
@ -97,20 +97,18 @@ struct DrawCall {
layout (input_attachment_index = 0, binding = 0) uniform usubpassInputMS samplerId;
layout (input_attachment_index = 1, binding = 1) uniform subpassInputMS samplerNormal;
#if UF_DEFERRED_SAMPLING
layout (input_attachment_index = 2, binding = 2) uniform subpassInputMS samplerUv;
#else
layout (input_attachment_index = 2, binding = 2) uniform subpassInputMS samplerAlbedo;
#endif
layout (input_attachment_index = 3, binding = 4) uniform subpassInputMS samplerDepth;
layout (input_attachment_index = 3, binding = 3) uniform subpassInputMS samplerDepth;
layout (binding = 5) uniform sampler3D samplerNoise;
layout (binding = 6) uniform samplerCube samplerSkybox;
layout (binding = 7) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 4) uniform sampler3D samplerNoise;
layout (binding = 5) uniform samplerCube samplerSkybox;
layout (binding = 6) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 7) uniform UBO {
layout (binding = 8) uniform UBO {
Matrices matrices;
Mode mode;
@ -125,16 +123,16 @@ layout (binding = 7) uniform UBO {
float kexp;
} ubo;
layout (std140, binding = 8) readonly buffer Lights {
layout (std140, binding = 9) readonly buffer Lights {
Light lights[];
};
layout (std140, binding = 9) readonly buffer Materials {
layout (std140, binding = 10) readonly buffer Materials {
Material materials[];
};
layout (std140, binding = 10) readonly buffer Textures {
layout (std140, binding = 11) readonly buffer Textures {
Texture textures[];
};
layout (std140, binding = 11) readonly buffer DrawCalls {
layout (std140, binding = 12) readonly buffer DrawCalls {
DrawCall drawCalls[];
};
@ -633,11 +631,14 @@ void main() {
vec2 uv = subpassLoad(samplerUv, SAMPLES).xy;
C = sampleTexture( drawId, drawCall.textureIndex + material.indexAlbedo, uv, C );
// OPAQUE
if ( material.modeAlpha == 0 ) C.a = 1;
if ( material.modeAlpha == 0 ) {
C.a = 1;
// BLEND
else if ( material.modeAlpha == 1 ) {
} else if ( material.modeAlpha == 1 ) {
// MASK
} else if ( material.modeAlpha == 2 ) {
}
#else
C = subpassLoad(samplerAlbedo, SAMPLES);

View File

@ -49,7 +49,6 @@ layout (location = 7) flat in ivec4 inId;
layout (location = 0) out uvec2 outId;
layout (location = 1) out vec2 outNormals;
#if UF_DEFERRED_SAMPLING
layout (location = 2) out vec2 outUvs;
#else
@ -97,10 +96,17 @@ void main() {
if ( !validTextureIndex( material.indexAlbedo ) ) discard; {
Texture t = textures[material.indexAlbedo + 1];
C = textureLod( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
// alpha mode MASK
if ( material.modeAlpha == 0 ) C.a = 1;
else if ( material.modeAlpha == 2 && C.a < abs(material.factorAlphaCutoff) ) discard;
// alpha mode OPAQUE
if ( material.modeAlpha == 0 ) {
C.a = 1;
// alpha mode BLEND
} else if ( material.modeAlpha == 1 ) {
// alpha mode MASK
} else if ( material.modeAlpha == 2 ) {
if ( C.a < abs(material.factorAlphaCutoff) ) discard;
C.a = 1;
}
}
#endif
@ -128,7 +134,6 @@ void main() {
#endif
outAlbedo = C * inColor;
#endif
outNormals = encodeNormals( N );
outId = ivec2(inId.w+1, inId.y+1);
}

View File

@ -1,6 +1,9 @@
#version 450
layout (binding = 1) uniform sampler2D samplerColor;
#define UF_DEFERRED_SAMPLING 0
#define UF_CAN_DISCARD 1
layout (binding = 1) uniform sampler2D samplerTexture;
struct Gui {
vec4 offset;
@ -12,7 +15,24 @@ struct Gui {
layout (location = 0) in vec2 inUv;
layout (location = 1) in flat Gui inGui;
layout (location = 0) out vec4 outFragColor;
layout (location = 0) out uvec2 outId;
layout (location = 1) out vec2 outNormals;
#if UF_DEFERRED_SAMPLING
layout (location = 2) out vec2 outUvs;
#else
layout (location = 2) out vec4 outAlbedo;
#endif
vec2 encodeNormals( vec3 n ) {
float p = sqrt(n.z*8+8);
return n.xy/p + 0.5;
}
float mipLevel( in vec2 uv ) {
vec2 dx_vtc = dFdx(uv);
vec2 dy_vtc = dFdy(uv);
return 0.5 * log2(max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)));
}
void main() {
if ( inUv.x < inGui.offset.x ) discard;
@ -20,11 +40,27 @@ void main() {
if ( inUv.x > inGui.offset.z ) discard;
if ( inUv.y > inGui.offset.w ) discard;
outFragColor = texture(samplerColor, inUv);
if ( outFragColor.a < 0.001 ) discard;
float mip = mipLevel(inUv.xy);
vec2 uv = inUv.xy;
vec4 C = vec4(1, 1, 1, 1);
//vec3 N = inNormal;
#if UF_DEFERRED_SAMPLING
outUvs = wrap(inUv.xy);
vec4 outAlbedo = vec4(0,0,0,0);
#endif
#if !UF_DEFERRED_SAMPLING || UF_CAN_DISCARD
C = textureLod( samplerTexture, uv, mip );
#endif
#if !UF_DEFERRED_SAMPLING
if ( inGui.mode == 1 ) {
outFragColor = inGui.color;
C = inGui.color;
} else {
outFragColor *= inGui.color;
C *= inGui.color;
}
outAlbedo = C;
#endif
/*
outNormals = encodeNormals( N );
outId = ivec2(0, 0);
*/
}

View File

@ -1,6 +1,9 @@
#version 450
layout (binding = 1) uniform sampler2D samplerColor;
#define UF_DEFERRED_SAMPLING 0
#define UF_CAN_DISCARD 1
layout (binding = 1) uniform sampler2D samplerTexture;
struct Gui {
vec4 offset;
@ -18,7 +21,14 @@ struct Gui {
layout (location = 0) in vec2 inUv;
layout (location = 1) in flat Gui inGui;
layout (location = 0) out vec4 outFragColor;
layout (location = 0) out uvec2 outId;
layout (location = 1) out vec2 outNormals;
#if UF_DEFERRED_SAMPLING
layout (location = 2) out vec2 outUvs;
#else
layout (location = 2) out vec4 outAlbedo;
#endif
void main() {
if ( inUv.x < inGui.offset.x ) discard;
@ -26,22 +36,26 @@ void main() {
if ( inUv.x > inGui.offset.z ) discard;
if ( inUv.y > inGui.offset.w ) discard;
#if UF_DEFERRED_SAMPLING
vec4 outAlbedo = vec4(0,0,0,0);
#endif
if ( inGui.shadowbox == 1 ) {
outFragColor = inGui.color;
outAlbedo = inGui.color;
return;
}
float dist = texture(samplerColor, inUv).r;
float dist = texture(samplerTexture, inUv).r;
if ( inGui.sdf == 1 ) {
float smoothing = ( inGui.spread > 0 && inGui.scale > 0 ) ? 0.25 / (inGui.spread * inGui.scale) : 0.25 / (4 * 1.5);
float outlining = smoothstep(0.5 - smoothing, 0.5 + smoothing, dist);
float alpha = smoothstep(inGui.weight - smoothing, inGui.weight + smoothing, dist);
vec4 c = inGui.color;
outFragColor = mix(inGui.stroke, c, outlining);
outFragColor.a = inGui.color.a * alpha;
outAlbedo = mix(inGui.stroke, c, outlining);
outAlbedo.a = inGui.color.a * alpha;
if ( alpha < 0.001 ) discard;
if ( alpha > 1 ) discard;
} else {
outFragColor = vec4(inGui.color) * dist;
outAlbedo = vec4(inGui.color) * dist;
if ( dist < 0.001 ) discard;
if ( dist > 1 ) discard;
}

View File

@ -6,7 +6,7 @@
#include <uf/utils/graphic/graphic.h>
#include <uf/utils/serialize/serializer.h>
#ifdef USE_OPENVR_MINGW
#include <openvr/openvr_mingw.h>
#include <openvr/openvr_mingw.hpp>
#else
#include <openvr/openvr.h>
#endif

View File

@ -27,6 +27,7 @@ namespace ext {
struct Subpass {
VkPipelineStageFlags stage;
VkAccessFlags access;
bool autoBuildPipeline;
std::vector<VkAttachmentReference> colors;
std::vector<VkAttachmentReference> inputs;
@ -45,7 +46,7 @@ namespace ext {
// RAII
void initialize( Device& device );
void destroy();
void addPass( VkPipelineStageFlags, VkAccessFlags, const std::vector<size_t>&, const std::vector<size_t>&, const std::vector<size_t>&, size_t );
void addPass( VkPipelineStageFlags, VkAccessFlags, const std::vector<size_t>&, const std::vector<size_t>&, const std::vector<size_t>&, size_t, bool = true );
size_t attach( const Attachment::Descriptor& descriptor, Attachment* attachment = NULL );
};
}

View File

@ -218,6 +218,7 @@ bool uf::Object::load( const uf::Serializer& _json ) {
uf::instantiator::bind( "RenderBehavior", *this );
}
if ( json["defaults"]["asset load"].as<bool>() ) {
std::cout << "Binding GltfBehavior to " << this->getName() << std::endl;
uf::instantiator::bind( "GltfBehavior", *this );
}
{

View File

@ -368,6 +368,9 @@ pod::Graph ext::gltf::load( const std::string& filename, ext::gltf::load_mode_t
} else {
std::cout << "Unhandled alpha mode: " << material.alphaMode << std::endl;
}
if ( m.doubleSided && graph.metadata["cull mode"].as<std::string>() == "auto" ) {
graph.metadata["cull mode"] = "none";
}
}
}
// load node information/meshes

View File

@ -11,6 +11,17 @@ namespace {
graphic.material.device = &uf::renderer::device;
graphic.descriptor.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
graphic.descriptor.cullMode = !(graph.mode & ext::gltf::LoadMode::INVERT) ? VK_CULL_MODE_BACK_BIT : VK_CULL_MODE_FRONT_BIT; // VK_CULL_MODE_NONE
if ( graph.metadata["cull mode"].is<std::string>() ) {
if ( graph.metadata["cull mode"].as<std::string>() == "back" ) {
graphic.descriptor.cullMode = VK_CULL_MODE_BACK_BIT;
} else if ( graph.metadata["cull mode"].as<std::string>() == "front" ) {
graphic.descriptor.cullMode = VK_CULL_MODE_FRONT_BIT;
} else if ( graph.metadata["cull mode"].as<std::string>() == "none" ) {
graphic.descriptor.cullMode = VK_CULL_MODE_NONE;
} else if ( graph.metadata["cull mode"].as<std::string>() == "both" ) {
graphic.descriptor.cullMode = VK_CULL_MODE_FRONT_AND_BACK;
}
}
{
#if UF_VK_TESTING
for ( auto& texture : graph.textures ) {

View File

@ -230,7 +230,7 @@ void ext::openvr::terminate() {
ext::openvr::context = NULL;
}
void ext::openvr::resetPosition() {
ext::openvr::context->ResetSeatedZeroPose();
// ext::openvr::context->ResetSeatedZeroPose();
}
void ext::openvr::tick() {
if ( !ext::openvr::context ) return;

View File

@ -499,7 +499,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
//for ( const auto& resource : res.key ) {
#define LOOP_RESOURCES( key, type ) for ( size_t i = 0; i < res.key.size(); ++i ) {\
const auto& resource = res.key[i];\
if ( false ) VK_VALIDATION_MESSAGE("["<<filename<<"] Found resource: "#type " with binding: " << comp.get_decoration(resource.id, spv::DecorationBinding));\
VK_DEBUG_VALIDATION_MESSAGE("["<<filename<<"] Found resource: "#type " with binding: " << comp.get_decoration(resource.id, spv::DecorationBinding));\
parseResource( resource, type, i );\
}
LOOP_RESOURCES( sampled_images, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER );
@ -829,7 +829,6 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& des
descriptorSetLayoutBindings.data(),
descriptorSetLayoutBindings.size()
);
VK_CHECK_RESULT(vkCreateDescriptorSetLayout( device, &descriptorLayout, nullptr, &descriptorSetLayout ));
VkDescriptorSetAllocateInfo allocInfo = ext::vulkan::initializers::descriptorSetAllocateInfo(

View File

@ -129,6 +129,19 @@ void ext::vulkan::RenderMode::bindPipelines() {
this->bindPipelines( graphics );
}
void ext::vulkan::RenderMode::bindPipelines( const std::vector<ext::vulkan::Graphic*>& graphics ) {
for ( auto* pointer : graphics ) {
auto& graphic = *pointer;
for ( size_t currentPass = 0; currentPass < renderTarget.passes.size(); ++currentPass ) {
auto& subpass = renderTarget.passes[currentPass];
if ( !subpass.autoBuildPipeline ) continue;
// bind to this render mode
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic.descriptor, currentPass);
// ignore if pipeline exists for this render mode
if ( graphic.hasPipeline( descriptor ) ) continue;
graphic.initializePipeline( descriptor );
}
}
/*
size_t subpasses = metadata["subpasses"].as<size_t>();
for ( auto* pointer : graphics ) {
auto& graphic = *pointer;
@ -140,6 +153,7 @@ void ext::vulkan::RenderMode::bindPipelines( const std::vector<ext::vulkan::Grap
graphic.initializePipeline( descriptor );
}
}
*/
}
void ext::vulkan::RenderMode::render() {

View File

@ -26,6 +26,8 @@ std::vector<ext::vulkan::Graphic*> ext::vulkan::DeferredRenderMode::getBlitters(
}
void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
if ( !metadata["eyes"].is<size_t>() ) metadata["eyes"] = 1;
metadata["outputs"] = ext::json::array();
{
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
@ -37,7 +39,6 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
ext::vulkan::RenderMode::initialize( device );
renderTarget.device = &device;
if ( !metadata["eyes"].is<size_t>() ) metadata["eyes"] = 1;
size_t eyes = metadata["eyes"].as<size_t>();
for ( size_t eye = 0; eye < eyes; ++eye ) {
struct {
@ -72,7 +73,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*.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,
/*.blend = */true,
/*.samples = */msaa,
});
}
@ -118,48 +119,51 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*.samples =*/ 1,
});
}
metadata["outputs"][eye] = attachments.output;
metadata["outputs"].emplace_back(attachments.output);
if ( ext::vulkan::settings::experimental::deferredMode == "deferredSampling" ) {
// First pass: fill the G-Buffer
{
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.id, attachments.normals, attachments.uvs },
{},
{},
attachments.depth
/*.*/ 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 =*/ {},
/*.depth = */ attachments.depth,
/*.autoBuildPipeline =*/ true
);
}
// Second pass: write to output
{
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.id, attachments.normals, attachments.uvs, attachments.depth },
{},
attachments.depth
/*.*/ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
/*.colors =*/ { attachments.output },
/*.inputs =*/ { attachments.id, attachments.normals, attachments.uvs, attachments.depth },
/*.resolve =*/ {},
/*.depth = */ attachments.depth,
/*.autoBuildPipeline =*/ false
);
}
} else {
// First pass: fill the G-Buffer
{
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.id, attachments.normals, attachments.albedo },
{},
{},
attachments.depth
/*.*/ 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 =*/ {},
/*.depth = */ attachments.depth,
/*.autoBuildPipeline =*/ true
);
}
// Second pass: write to output
{
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.id, attachments.normals, attachments.albedo, attachments.depth },
{},
attachments.depth
/*.*/ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
/*.colors =*/ { attachments.output },
/*.inputs =*/ { attachments.id, attachments.normals, attachments.albedo, attachments.depth },
/*.resolve =*/ {},
/*.depth = */ attachments.depth,
/*.autoBuildPipeline =*/ false
);
}
}
@ -263,6 +267,7 @@ void ext::vulkan::DeferredRenderMode::destroy() {
void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
if ( !metadata["eyes"].is<size_t>() ) metadata["eyes"] = 1;
size_t eyes = metadata["eyes"].as<size_t>();
@ -281,7 +286,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes(std::vector<std::string>{"RenderTarget", "Compute"}, false);
auto& scene = uf::scene::getCurrentScene();
auto& metadata = scene.getComponent<uf::Serializer>();
auto& sceneMetadata = scene.getComponent<uf::Serializer>();
auto& commands = getCommands();
auto& swapchainRender = ext::vulkan::getRenderMode("Swapchain");
for (size_t i = 0; i < commands.size(); ++i) {
@ -292,8 +297,8 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
for ( auto& attachment : renderTarget.attachments ) {
VkClearValue clearValue;
if ( attachment.descriptor.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
if ( !ext::json::isNull( metadata["system"]["renderer"]["clear values"][(int) clearValues.size()] ) ) {
auto& v = metadata["system"]["renderer"]["clear values"][(int) clearValues.size()];
if ( !ext::json::isNull( sceneMetadata["system"]["renderer"]["clear values"][(int) clearValues.size()] ) ) {
auto& v = sceneMetadata["system"]["renderer"]["clear values"][(int) clearValues.size()];
clearValue.color = { {
v[0].as<float>(),
v[1].as<float>(),
@ -340,6 +345,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
layer->pipelineBarrier( commands[i], 0 );
}
size_t currentSubpass = 0;
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(commands[i], 0, 1, &viewport);
vkCmdSetScissor(commands[i], 0, 1, &scissor);
@ -350,7 +356,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
for ( auto graphic : graphics ) {
// only draw graphics that are assigned to this type of render mode
if ( graphic->descriptor.renderMode != this->getName() ) continue;
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor);
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentSubpass);
graphic->record( commands[i], descriptor, eye, currentDraw++ );
}
// blit any RT's that request this subpass
@ -359,13 +365,15 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != currentPass ) continue;
blitter.record(commands[i]);
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(blitter.descriptor, currentSubpass);
blitter.record(commands[i], descriptor);
}
}
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); ++currentPass;
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); ++currentPass; ++currentSubpass;
// deferred post-processing lighting pass
{
blitter.record(commands[i]);
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(blitter.descriptor, currentSubpass);
blitter.record(commands[i], descriptor, eye, currentDraw++);
}
// blit any RT's that request this subpass
{
@ -373,10 +381,11 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != currentPass ) continue;
blitter.record(commands[i]);
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(blitter.descriptor, currentSubpass);
blitter.record(commands[i], descriptor, eye, currentDraw++);
}
}
if ( eye + 1 < eyes ) vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
if ( eye + 1 < eyes ) vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); ++currentSubpass;
}
vkCmdEndRenderPass(commands[i]);
@ -422,8 +431,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
swapchainRender.height > 0 ? swapchainRender.height : ext::vulkan::settings::height,
1
};
auto& outputAttachment = renderTarget.attachments[renderTarget.attachments.size()-1];
auto& outputAttachment = renderTarget.attachments[metadata["outputs"][0].as<size_t>()];
// Transition to KHR
{
imageMemoryBarrier.image = outputAttachment.image;

View File

@ -70,10 +70,11 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
{},
{},
{},
attachments.depth
attachments.depth,
true
);
} else {
#if 1
#if 0
struct {
size_t albedo, normals, position, depth;
} attachments;
@ -130,32 +131,103 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
}
#else
struct {
size_t normals, uvs, id, depth;
size_t id, normals, uvs, albedo, depth, output;
} attachments;
//VK_FORMAT_R16G16B16A16_SFLOAT
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
attachments.uvs = renderTarget.attach( VK_FORMAT_R16G16_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // uvs
attachments.id = renderTarget.attach( VK_FORMAT_R16G16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // ID
attachments.depth = renderTarget.attach( ext::vulkan::settings::formats::depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
size_t msaa = ext::vulkan::settings::msaa;
// First pass: fill the G-Buffer
{
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.normals, attachments.uvs, attachments.id },
{},
attachments.depth
);
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::deferredMode == "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,
});
}
// Second pass: write to output
{
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.normals, attachments.uvs, attachments.id, attachments.depth },
attachments.depth
);
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.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,
});
if ( ext::vulkan::settings::experimental::deferredMode == "deferredSampling" ) {
// First pass: fill the G-Buffer
{
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.id, attachments.normals, attachments.uvs },
{},
{},
attachments.depth,
true
);
}
// Second pass: write to output
{
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.id, attachments.normals, attachments.uvs, attachments.depth },
{},
attachments.depth,
false
);
}
} else {
// First pass: fill the G-Buffer
{
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.id, attachments.normals, attachments.albedo },
{},
{},
attachments.depth,
true
);
}
// Second pass: write to output
{
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.id, attachments.normals, attachments.albedo, attachments.depth },
{},
attachments.depth,
false
);
}
}
metadata["outputs"][0] = attachments.output;
#endif
}
}
@ -346,12 +418,12 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const std::vecto
scissor.offset.x = 0;
scissor.offset.y = 0;
size_t subpasses = metadata["subpasses"].as<size_t>();
if ( subpasses == 0 ) subpasses = 1;
size_t subpasses = renderTarget.passes.size();
size_t currentPass = 0;
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(commands[i], 0, 1, &viewport);
vkCmdSetScissor(commands[i], 0, 1, &scissor);
for ( size_t currentPass = 0; currentPass < subpasses; ++currentPass ) {
for ( ; currentPass < subpasses; ++currentPass ) {
size_t currentDraw = 0;
for ( auto graphic : graphics ) {
if ( graphic->descriptor.renderMode != this->getTarget() ) continue;

View File

@ -3,10 +3,11 @@
#include <uf/ext/vulkan/initializers.h>
#include <uf/utils/window/window.h>
void ext::vulkan::RenderTarget::addPass( VkPipelineStageFlags stage, VkAccessFlags access, const std::vector<size_t>& colors, const std::vector<size_t>& inputs, const std::vector<size_t>& resolves, size_t depth ) {
void ext::vulkan::RenderTarget::addPass( VkPipelineStageFlags stage, VkAccessFlags access, const std::vector<size_t>& colors, const std::vector<size_t>& inputs, const std::vector<size_t>& resolves, size_t depth, bool autoBuildPipeline ) {
Subpass pass;
pass.stage = stage;
pass.access = access;
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 } );

View File

@ -478,7 +478,7 @@ void ext::vulkan::Texture::fromBuffers(
if ( data ) {
uint8_t* layerPointer = (uint8_t*) data;
VkDeviceSize layerSize = bufferSize / this->layers;
for ( size_t layer = 1; layer <= this->layers; ++layer ) {
for ( size_t layer = 0; layer < this->layers; ++layer ) {
this->update( (void*) layerPointer, layerSize, imageLayout, layer );
layerPointer += layerSize;
}
@ -585,13 +585,14 @@ void ext::vulkan::Texture::update( void* data, VkDeviceSize bufferSize, VkImageL
VkImageSubresourceRange subresourceRange = {};
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresourceRange.baseMipLevel = 0;
subresourceRange.baseArrayLayer = layer;
subresourceRange.levelCount = this->mips;
subresourceRange.layerCount = 1;
VkBufferImageCopy bufferCopyRegion = {};
bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
bufferCopyRegion.imageSubresource.mipLevel = 0;
bufferCopyRegion.imageSubresource.baseArrayLayer = layer - 1;
bufferCopyRegion.imageSubresource.baseArrayLayer = layer;
bufferCopyRegion.imageSubresource.layerCount = 1;
bufferCopyRegion.imageExtent.width = width;
bufferCopyRegion.imageExtent.height = height;
@ -664,7 +665,7 @@ void ext::vulkan::Texture::generateMipmaps( VkCommandBuffer commandBuffer, uint3
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.image = image;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseArrayLayer = layer - 1;
barrier.subresourceRange.baseArrayLayer = layer;
barrier.subresourceRange.layerCount = 1;
barrier.subresourceRange.levelCount = 1;
@ -691,13 +692,13 @@ void ext::vulkan::Texture::generateMipmaps( VkCommandBuffer commandBuffer, uint3
blit.srcOffsets[1] = { mipWidth, mipHeight, mipDepth };
blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
blit.srcSubresource.mipLevel = i - 1;
blit.srcSubresource.baseArrayLayer = layer - 1;
blit.srcSubresource.baseArrayLayer = layer;
blit.srcSubresource.layerCount = 1;
blit.dstOffsets[0] = { 0, 0, 0 };
blit.dstOffsets[1] = { mipWidth > 1 ? mipWidth / 2 : 1, mipHeight > 1 ? mipHeight / 2 : 1, mipDepth > 1 ? mipDepth / 2 : 1 };
blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
blit.dstSubresource.mipLevel = i;
blit.dstSubresource.baseArrayLayer = layer - 1;
blit.dstSubresource.baseArrayLayer = layer;
blit.dstSubresource.layerCount = 1;
vkCmdBlitImage(