stabilized voxelization with a bunch of cringe

This commit is contained in:
mrq 2025-07-28 23:31:15 -05:00 committed by ecker
parent 67f0456352
commit d519af9cc3
17 changed files with 295 additions and 135 deletions

View File

@ -29,9 +29,9 @@
}
},
"vxgi": {
// "limiter": 0,
"limiter": 0.5,
"size": 128,
"limiter": 0,
// "limiter": 0.5,
"size": 256,
"dispatch": 8,
"cascades": 3,
"cascadePower": 2.0,
@ -288,7 +288,7 @@
"compression": "gz"
},
"imgui": {
"enabled": false
"enabled": true
},
"fsr": {
"enabled": true,

View File

@ -18,7 +18,7 @@
[ 0, 0, 0, 0 ]
],
"shader": {
"mode": 0,
"mode": 10,
"scalar": 16,
"parameters": [ 0, 0, 0, "time" ]
}

View File

@ -17,6 +17,25 @@ float mipLevels( ivec2 size ) {
return floor(log2(max(size.x, size.y)));
}
//
vec4 rgbaUVec4toVec4( uvec4 rgba ) {
/*
return vec4(float((val & 0x000000FF)),
float((val & 0x0000FF00) >> 8U),
float((val & 0x00FF0000) >> 16U),
float((val & 0xFF000000) >> 24U));
*/
return rgba / vec4(256.0);
}
uvec4 rgbaVec4toUvec4( vec4 rgba ) {
/*
return (uint(val.w) & 0x000000FF) << 24U |
(uint(val.z) & 0x000000FF) << 16U |
(uint(val.y) & 0x000000FF) << 8U |
(uint(val.x) & 0x000000FF);
*/
return uvec4(rgba * uvec4(256));
}
//
void toneMap( inout vec3 color, float exposure ) {
color.rgb = vec3(1.0) - exp(-color.rgb * exposure);
}

View File

@ -104,4 +104,13 @@ const float SQRT2 = 1.41421356237;
const float LIGHT_POWER_CUTOFF = 0.0005;
const float LIGHTMAP_GAMMA = 1.0;
#define SETTINGS_TYPE_FULLBRIGHT 0x10
#define UBO_RENDER_MODE_ALBEDO 0x0001
#define UBO_RENDER_MODE_LIGHT 0x0002
#define UBO_RENDER_MODE_RADIANCE 0x0003
#define UBO_RENDER_MODE_NORMAL 0x0004
#define UBO_RENDER_MODE_UV 0x0005
#define UBO_RENDER_MODE_ST 0x0006
#define UBO_RENDER_MODE_METALLIC 0x0007
#define UBO_RENDER_MODE_ROUGHNESS 0x0008
#define UBO_RENDER_MODE_OCCLUSION 0x0009
#define UBO_RENDER_MODE_VXGI 0x000A

View File

@ -275,6 +275,7 @@ struct VoxelInfo {
float mipmapLevels;
float radianceSize;
float radianceSizeRecip;
uint state; // yuck
} voxelInfo;
// Raytrace stuff

View File

@ -55,7 +55,7 @@ vec4 voxelTrace( inout Ray ray, float aperture, float maxDistance ) {
coneDiameter = coneCoefficient * ray.distance;
level = aperture > 0 ? log2( coneDiameter ) : 0;
if ( level >= voxelInfo.mipmapLevels ) break;
radiance = textureLod(voxelRadiance[nonuniformEXT(cascade)], uvw.xzy, level);
radiance = textureLod(voxelOutput[nonuniformEXT(cascade)], uvw.xzy, level);
color += (1.0 - color.a) * radiance;
occlusion += ((1.0f - occlusion) * radiance.a) / (1.0f + occlusionFalloff * coneDiameter);
}
@ -82,7 +82,7 @@ float shadowFactorVXGI( const Light light, float def ) {
return 1.0 - voxelTrace( ray, SHADOW_APERTURE, z ).a;
}
void indirectLightingVXGI() {
voxelInfo.radianceSize = textureSize( voxelRadiance[0], 0 ).x;
voxelInfo.radianceSize = textureSize( voxelOutput[0], 0 ).x;
voxelInfo.radianceSizeRecip = 1.0 / voxelInfo.radianceSize;
voxelInfo.mipmapLevels = log2(voxelInfo.radianceSize) + 1;
#if VXGI_NDC

View File

@ -95,12 +95,19 @@ layout (binding = 17) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 18) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 19) uniform sampler3D samplerNoise;
#if VXGI
layout (binding = 20) uniform usampler3D voxelId[CASCADES];
layout (binding = 21) uniform sampler3D voxelNormal[CASCADES];
layout (binding = 22) uniform sampler3D voxelRadiance[CASCADES];
layout (binding = 20) uniform usampler3D voxelDrawId[CASCADES];
layout (binding = 21) uniform usampler3D voxelInstanceId[CASCADES];
layout (binding = 22) uniform sampler3D voxelNormalX[CASCADES];
layout (binding = 23) uniform sampler3D voxelNormalY[CASCADES];
layout (binding = 24) uniform sampler3D voxelRadianceR[CASCADES];
layout (binding = 25) uniform sampler3D voxelRadianceG[CASCADES];
layout (binding = 26) uniform sampler3D voxelRadianceB[CASCADES];
layout (binding = 27) uniform sampler3D voxelRadianceA[CASCADES];
layout (binding = 28) uniform sampler3D voxelCount[CASCADES];
layout (binding = 29) uniform sampler3D voxelOutput[CASCADES];
#endif
#if RT
layout (binding = 23) uniform accelerationStructureEXT tlas;
layout (binding = 30) uniform accelerationStructureEXT tlas;
#endif
#if BUFFER_REFERENCE

View File

@ -49,13 +49,16 @@ layout (binding = 7) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 8) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 9) uniform sampler3D samplerNoise;
layout (binding = 10, rg16ui) uniform volatile coherent uimage3D voxelId[CASCADES];
layout (binding = 11, rg16f) uniform volatile coherent image3D voxelNormal[CASCADES];
#if VXGI_HDR
layout (binding = 12, rgba32f) uniform volatile coherent image3D voxelRadiance[CASCADES];
#else
layout (binding = 12, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES];
#endif
layout (binding = 10, r32ui) uniform volatile coherent uimage3D voxelDrawId[CASCADES];
layout (binding = 11, r32ui) uniform volatile coherent uimage3D voxelInstanceId[CASCADES];
layout (binding = 12, r32ui) uniform volatile coherent uimage3D voxelNormalX[CASCADES];
layout (binding = 13, r32ui) uniform volatile coherent uimage3D voxelNormalY[CASCADES];
layout (binding = 14, r32ui) uniform volatile coherent uimage3D voxelRadianceR[CASCADES];
layout (binding = 15, r32ui) uniform volatile coherent uimage3D voxelRadianceG[CASCADES];
layout (binding = 16, r32ui) uniform volatile coherent uimage3D voxelRadianceB[CASCADES];
layout (binding = 17, r32ui) uniform volatile coherent uimage3D voxelRadianceA[CASCADES];
layout (binding = 18, r32ui) uniform volatile coherent uimage3D voxelCount[CASCADES];
layout (binding = 19, rgba16f) uniform volatile coherent image3D voxelOutput[CASCADES];
#include "../../common/functions.h"
#include "../../common/light.h"
@ -65,10 +68,14 @@ layout (binding = 11, rg16f) uniform volatile coherent image3D voxelNormal[CASCA
void main() {
const vec3 tUvw = gl_GlobalInvocationID.xzy;
for ( uint CASCADE = 0; CASCADE < CASCADES; ++CASCADE ) {
surface.normal.world = decodeNormals( vec2(imageLoad(voxelNormal[CASCADE], ivec3(tUvw) ).xy) );
vec2 N_E;
N_E.x = uintBitsToFloat(imageLoad(voxelNormalX[CASCADE], ivec3(tUvw) ).x);
N_E.y = uintBitsToFloat(imageLoad(voxelNormalY[CASCADE], ivec3(tUvw) ).x);
surface.normal.world = decodeNormals( N_E );
surface.normal.eye = vec3( ubo.settings.vxgi.matrix * vec4( surface.normal.world, 0.0f ) );
surface.position.eye = (vec3(gl_GlobalInvocationID.xyz) / vec3(imageSize(voxelRadiance[CASCADE])) * 2.0f - 1.0f) * cascadePower(CASCADE);
surface.position.eye = (vec3(gl_GlobalInvocationID.xyz) / vec3(imageSize(voxelOutput[CASCADE])) * 2.0f - 1.0f) * cascadePower(CASCADE);
surface.position.world = vec3( inverse(ubo.settings.vxgi.matrix) * vec4( surface.position.eye, 1.0f ) );
surface.pass = 0; // PushConstant.pass;
@ -78,10 +85,32 @@ void main() {
surface.material.indirect = vec4(0);
#if 0
surface.material.albedo = imageLoad(voxelRadiance[CASCADE], ivec3(tUvw) );
surface.fragment.rgb = surface.material.albedo.rgb;
#if 0
vec4 A = imageLoad(voxelOutput[CASCADE], ivec3(tUvw) );
#else
const uvec2 ID = uvec2(imageLoad(voxelId[CASCADE], ivec3(tUvw) ).xy);
vec4 A = vec4(0);
A.r = imageLoad(voxelRadianceR[CASCADE], ivec3(tUvw) ).r;
A.g = imageLoad(voxelRadianceG[CASCADE], ivec3(tUvw) ).r;
A.b = imageLoad(voxelRadianceB[CASCADE], ivec3(tUvw) ).r;
A.a = imageLoad(voxelRadianceA[CASCADE], ivec3(tUvw) ).r;
A /= 256.0;
uint count = imageLoad(voxelCount[CASCADE], ivec3(tUvw) ).r;
if ( count > 0 ) A /= count;
/*
vec4 A = vec4(surface.normal.world, 1.0);
*/
#endif
surface.material.albedo = A;
surface.fragment.rgb = surface.material.albedo.rgb;
const bool DISCARD_DUE_TO_DIVERGENCE = surface.material.albedo.a == 0;
#else
const uvec2 ID = uvec2(
imageLoad(voxelDrawId[CASCADE], ivec3(tUvw) ).x,
imageLoad(voxelInstanceId[CASCADE], ivec3(tUvw) ).x
);
const bool DISCARD_DUE_TO_DIVERGENCE = ID.x == 0 || ID.y == 0;
const uint drawID = ID.x == 0 ? 0 : ID.x - 1;
@ -90,7 +119,7 @@ void main() {
// if ( ID.x == 0 || ID.y == 0 ) {
#if 1
if ( DISCARD_DUE_TO_DIVERGENCE ) {
imageStore(voxelRadiance[CASCADE], ivec3(tUvw), vec4(0));
imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(0));
continue;
}
#endif
@ -101,7 +130,21 @@ void main() {
surface.material.albedo = material.colorBase;
surface.fragment = material.colorEmissive;
surface.material.albedo = imageLoad(voxelRadiance[CASCADE], ivec3(tUvw) );
#if 0
vec4 A = imageLoad(voxelOutput[CASCADE], ivec3(tUvw) );
#else
vec4 A = vec4(0);
A.r = imageLoad(voxelRadianceR[CASCADE], ivec3(tUvw) ).r;
A.g = imageLoad(voxelRadianceG[CASCADE], ivec3(tUvw) ).r;
A.b = imageLoad(voxelRadianceB[CASCADE], ivec3(tUvw) ).r;
A.a = imageLoad(voxelRadianceA[CASCADE], ivec3(tUvw) ).r;
A /= 256.0;
uint count = imageLoad(voxelCount[CASCADE], ivec3(tUvw) ).r;
if ( count > 0 ) A /= count;
#endif
surface.material.albedo = A;
surface.material.metallic = material.factorMetallic;
surface.material.roughness = material.factorRoughness;
surface.material.occlusion = material.factorOcclusion;
@ -167,12 +210,12 @@ void main() {
#endif
#if 0
imageStore(voxelRadiance[CASCADE], ivec3(tUvw), vec4(surface.fragment.rgb, surface.material.albedo.a));
imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(surface.fragment.rgb, surface.material.albedo.a));
#else
if ( DISCARD_DUE_TO_DIVERGENCE ) {
imageStore(voxelRadiance[CASCADE], ivec3(tUvw), vec4(0));
imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(0));
} else {
imageStore(voxelRadiance[CASCADE], ivec3(tUvw), vec4(surface.fragment.rgb, surface.material.albedo.a));
imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(surface.fragment.rgb, surface.material.albedo.a));
}
#endif
}

View File

@ -12,7 +12,11 @@ layout( push_constant ) uniform PushBlock {
uint mip;
} PushConstant;
layout (binding = 1, rg16f) uniform volatile coherent image3D voxelRadiance[CASCADES * MIPS];
#if VXGI_HDR
layout (binding = 1, rgba32f) uniform volatile coherent image3D voxelRadiance[CASCADES * MIPS];
#else
layout (binding = 1, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES * MIPS];
#endif
const float gaussianWeights[] = {
//Top slice

View File

@ -7,8 +7,7 @@
#define DEFERRED_SAMPLING 0
#define CUBEMAPS 1
#define BLEND 1
#define DEPTH_TEST 0
#define BLEND 0
#define USE_LIGHTMAP 1
layout (constant_id = 0) const uint TEXTURES = 512;
layout (constant_id = 1) const uint CASCADES = 16;
@ -38,16 +37,16 @@ layout (std140, binding = 11) readonly buffer Lights {
Light lights[];
};
layout (binding = 12, rg16ui) uniform volatile coherent uimage3D voxelId[CASCADES];
layout (binding = 13, rg16f) uniform volatile coherent image3D voxelNormal[CASCADES];
#if VXGI_HDR
layout (binding = 14, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES];
#else
layout (binding = 14, rgba8) uniform volatile coherent image3D voxelRadiance[CASCADES];
#endif
#if DEPTH_TEST
layout (binding = 15, r16f) uniform volatile coherent image3D voxelDepth[CASCADES];
#endif
layout (binding = 12, r32ui) uniform volatile coherent uimage3D voxelDrawId[CASCADES];
layout (binding = 13, r32ui) uniform volatile coherent uimage3D voxelInstanceId[CASCADES];
layout (binding = 14, r32ui) uniform volatile coherent uimage3D voxelNormalX[CASCADES];
layout (binding = 15, r32ui) uniform volatile coherent uimage3D voxelNormalY[CASCADES];
layout (binding = 16, r32ui) uniform volatile coherent uimage3D voxelRadianceR[CASCADES];
layout (binding = 17, r32ui) uniform volatile coherent uimage3D voxelRadianceG[CASCADES];
layout (binding = 18, r32ui) uniform volatile coherent uimage3D voxelRadianceB[CASCADES];
layout (binding = 19, r32ui) uniform volatile coherent uimage3D voxelRadianceA[CASCADES];
layout (binding = 20, r32ui) uniform volatile coherent uimage3D voxelCount[CASCADES];
layout (binding = 21, rgba16f) uniform volatile coherent image3D voxelOutput[CASCADES];
layout (location = 0) flat in uvec4 inId;
layout (location = 1) flat in vec4 inPOS0;
@ -120,23 +119,20 @@ void main() {
N = TBN * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - 1.0 );
}
const ivec3 uvw = ivec3(P * imageSize(voxelRadiance[CASCADE]));
const ivec3 uvw = ivec3(P * imageSize(voxelOutput[CASCADE]));
#if DEPTH_TEST
const float outDepth = length(inPosition.xzy);
const float inDepth = imageLoad(voxelDepth[CASCADE], uvw).r;
if ( inDepth != 0 && inDepth < outDepth ) discard;
imageStore(voxelDepth[CASCADE], uvw, vec4(inDepth, 0, 0, 0));
#endif
imageAtomicMax(voxelDrawId[CASCADE], ivec3(uvw), uint( drawID + 1 ) );
imageAtomicMax(voxelInstanceId[CASCADE], ivec3(uvw), uint( instanceID + 1 ) );
imageStore(voxelId[CASCADE], uvw, uvec4(uvec2(drawID + 1, instanceID + 1), 0, 0));
imageStore(voxelNormal[CASCADE], uvw, vec4(encodeNormals( normalize( N ) ), 0, 0));
#if BLEND
// GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
const vec4 src = A * inColor;
const vec4 dst = imageLoad(voxelRadiance[CASCADE], uvw);
imageStore(voxelRadiance[CASCADE], uvw, blend( src, dst, src.a ) );
#else
imageStore(voxelRadiance[CASCADE], uvw, A );
#endif
vec2 N_E = encodeNormals( normalize( N ) );
imageAtomicMin(voxelNormalX[CASCADE], ivec3(uvw), uint( floatBitsToUint( N_E.x ) ) );
imageAtomicMin(voxelNormalY[CASCADE], ivec3(uvw), uint( floatBitsToUint( N_E.y ) ) );
imageAtomicAdd(voxelRadianceR[CASCADE], ivec3(uvw), uint( A.r * 256 ) );
imageAtomicAdd(voxelRadianceG[CASCADE], ivec3(uvw), uint( A.g * 256 ) );
imageAtomicAdd(voxelRadianceB[CASCADE], ivec3(uvw), uint( A.b * 256 ) );
imageAtomicAdd(voxelRadianceA[CASCADE], ivec3(uvw), uint( A.a * 256 ) );
imageAtomicAdd(voxelCount[CASCADE], ivec3(uvw), uint( 1 ) );
imageStore(voxelOutput[CASCADE], uvw, vec4(N.x, N.y, N.z, A.a) );
}

View File

@ -5,11 +5,16 @@ namespace pod {
uf::renderer::Texture3D noise;
uf::renderer::TextureCube skybox;
struct {
uf::stl::vector<uf::renderer::Texture3D> id;
uf::stl::vector<uf::renderer::Texture3D> uv;
uf::stl::vector<uf::renderer::Texture3D> normal;
uf::stl::vector<uf::renderer::Texture3D> radiance;
uf::stl::vector<uf::renderer::Texture3D> depth;
uf::stl::vector<uf::renderer::Texture3D> drawId;
uf::stl::vector<uf::renderer::Texture3D> instanceId;
uf::stl::vector<uf::renderer::Texture3D> normalX;
uf::stl::vector<uf::renderer::Texture3D> normalY;
uf::stl::vector<uf::renderer::Texture3D> radianceR;
uf::stl::vector<uf::renderer::Texture3D> radianceG;
uf::stl::vector<uf::renderer::Texture3D> radianceB;
uf::stl::vector<uf::renderer::Texture3D> radianceA;
uf::stl::vector<uf::renderer::Texture3D> count;
uf::stl::vector<uf::renderer::Texture3D> output;
} voxels;
};
}

View File

@ -191,11 +191,16 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
if ( uf::renderer::settings::pipelines::vxgi ) {
auto& scene = uf::scene::getCurrentScene();
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
for ( auto& t : sceneTextures.voxels.id ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.normal ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.uv ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radiance ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.depth ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.drawId ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.instanceId ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.normalX ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.normalY ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceR ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceG ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceB ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceA ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.count ) graphic.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.output ) graphic.material.textures.emplace_back().aliasTexture(t);
}
#endif
}
@ -361,11 +366,16 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
}
{
uint32_t voxelTypes = 0;
if ( !sceneTextures.voxels.id.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.normal.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.uv.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.radiance.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.depth.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.drawId.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.instanceId.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.normalX.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.normalY.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.radianceR.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.radianceG.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.radianceB.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.radianceA.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.count.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.output.empty() ) ++voxelTypes;
uint32_t maxTextures = texture2Ds;
uint32_t maxCascades = texture3Ds / voxelTypes;
@ -377,10 +387,16 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
});
shader.setDescriptorCounts({
{ "samplerTextures", maxTextures },
{ "voxelId", maxCascades },
{ "voxelUv", maxCascades },
{ "voxelNormal", maxCascades },
{ "voxelRadiance", maxCascades },
{ "voxelDrawId", maxCascades },
{ "voxelInstanceId", maxCascades },
{ "voxelNormalX", maxCascades },
{ "voxelNormalY", maxCascades },
{ "voxelRadianceR", maxCascades },
{ "voxelRadianceG", maxCascades },
{ "voxelRadianceB", maxCascades },
{ "voxelRadianceA", maxCascades },
{ "voxelCount", maxCascades },
{ "voxelOutput", maxCascades },
});
shader.buffers.emplace_back( storage.buffers.drawCommands.alias() );

View File

@ -284,10 +284,16 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
shader.setDescriptorCounts({
{ "samplerTextures", maxTextures2D },
{ "samplerCubemaps", maxTexturesCube },
{ "voxelId", maxCascades },
{ "voxelUv", maxCascades },
{ "voxelNormal", maxCascades },
{ "voxelRadiance", maxCascades },
{ "voxelDrawId", maxCascades },
{ "voxelInstanceId", maxCascades },
{ "voxelNormalX", maxCascades },
{ "voxelNormalY", maxCascades },
{ "voxelRadianceR", maxCascades },
{ "voxelRadianceG", maxCascades },
{ "voxelRadianceB", maxCascades },
{ "voxelRadianceA", maxCascades },
{ "voxelCount", maxCascades },
{ "voxelOutput", maxCascades },
});
// shader.buffers.emplace_back( storage.buffers.camera.alias() );

View File

@ -336,10 +336,16 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
shader.setDescriptorCounts({
{ "samplerTextures", maxTextures2D },
{ "samplerCubemaps", maxTexturesCube },
{ "voxelId", maxCascades },
{ "voxelUv", maxCascades },
{ "voxelNormal", maxCascades },
{ "voxelRadiance", maxCascades },
{ "voxelDrawId", maxCascades },
{ "voxelInstanceId", maxCascades },
{ "voxelNormalX", maxCascades },
{ "voxelNormalY", maxCascades },
{ "voxelRadianceR", maxCascades },
{ "voxelRadianceG", maxCascades },
{ "voxelRadianceB", maxCascades },
{ "voxelRadianceA", maxCascades },
{ "voxelCount", maxCascades },
{ "voxelOutput", maxCascades },
});
// shader.buffers.emplace_back( storage.buffers.camera.alias() );

View File

@ -210,10 +210,16 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
shader.setDescriptorCounts({
{ "samplerTextures", maxTextures2D },
{ "samplerCubemaps", maxTexturesCube },
{ "voxelId", maxCascades },
{ "voxelUv", maxCascades },
{ "voxelNormal", maxCascades },
{ "voxelRadiance", maxCascades },
{ "voxelDrawId", maxCascades },
{ "voxelInstanceId", maxCascades },
{ "voxelNormalX", maxCascades },
{ "voxelNormalY", maxCascades },
{ "voxelRadianceR", maxCascades },
{ "voxelRadianceG", maxCascades },
{ "voxelRadianceB", maxCascades },
{ "voxelRadianceA", maxCascades },
{ "voxelCount", maxCascades },
{ "voxelOutput", maxCascades },
});
/*

View File

@ -718,20 +718,27 @@ void ext::ExtSceneBehavior::destroy( uf::Object& self ) {
}
if ( this->hasComponent<pod::SceneTextures>() ) {
auto& sceneTextures = this->getComponent<pod::SceneTextures>();
for ( auto& t : sceneTextures.voxels.id ) t.destroy();
sceneTextures.voxels.id.clear();
for ( auto& t : sceneTextures.voxels.drawId ) t.destroy();
for ( auto& t : sceneTextures.voxels.instanceId ) t.destroy();
for ( auto& t : sceneTextures.voxels.normalX ) t.destroy();
for ( auto& t : sceneTextures.voxels.normalY ) t.destroy();
for ( auto& t : sceneTextures.voxels.radianceR ) t.destroy();
for ( auto& t : sceneTextures.voxels.radianceG ) t.destroy();
for ( auto& t : sceneTextures.voxels.radianceB ) t.destroy();
for ( auto& t : sceneTextures.voxels.radianceA ) t.destroy();
for ( auto& t : sceneTextures.voxels.count ) t.destroy();
for ( auto& t : sceneTextures.voxels.output ) t.destroy();
for ( auto& t : sceneTextures.voxels.normal ) t.destroy();
sceneTextures.voxels.normal.clear();
for ( auto& t : sceneTextures.voxels.uv ) t.destroy();
sceneTextures.voxels.uv.clear();
for ( auto& t : sceneTextures.voxels.radiance ) t.destroy();
sceneTextures.voxels.radiance.clear();
for ( auto& t : sceneTextures.voxels.depth ) t.destroy();
sceneTextures.voxels.depth.clear();
sceneTextures.voxels.drawId.clear();
sceneTextures.voxels.instanceId.clear();
sceneTextures.voxels.normalX.clear();
sceneTextures.voxels.normalY.clear();
sceneTextures.voxels.radianceR.clear();
sceneTextures.voxels.radianceG.clear();
sceneTextures.voxels.radianceB.clear();
sceneTextures.voxels.radianceA.clear();
sceneTextures.voxels.count.clear();
sceneTextures.voxels.output.clear();
sceneTextures.noise.destroy();
sceneTextures.skybox.destroy();
@ -1049,11 +1056,16 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
// attach VXGI voxels
if ( uf::renderer::settings::pipelines::vxgi ) {
for ( auto& t : sceneTextures.voxels.id ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.normal ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.uv ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radiance ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.depth ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.drawId ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.instanceId ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.normalX ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.normalY ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceR ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceG ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceB ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceA ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.count ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.output ) textures3D.emplace_back().aliasTexture(t);
}
// bind textures
while ( textures2D.size() < metadata.max.textures2D ) textures2D.emplace_back().aliasTexture(uf::renderer::Texture2D::empty);

View File

@ -35,23 +35,43 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
for ( size_t i = 0; i < metadata.cascades; ++i ) {
const bool HDR = false;
auto& id = sceneTextures.voxels.id.emplace_back();
id.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
id.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
id.fromBuffers( NULL, 0, uf::renderer::enums::Format::R16G16_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& drawId = sceneTextures.voxels.drawId.emplace_back();
drawId.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
drawId.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
drawId.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
// auto& uv = sceneTextures.voxels.uv.emplace_back();
// uv.fromBuffers( NULL, 0, uf::renderer::enums::Format::R16G16_SFLOAT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& normal = sceneTextures.voxels.normal.emplace_back();
normal.fromBuffers( NULL, 0, uf::renderer::enums::Format::R16G16_SFLOAT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& radiance = sceneTextures.voxels.radiance.emplace_back();
auto& instanceId = sceneTextures.voxels.instanceId.emplace_back();
instanceId.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
instanceId.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
instanceId.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& normalX = sceneTextures.voxels.normalX.emplace_back();
normalX.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& normalY = sceneTextures.voxels.normalY.emplace_back();
normalY.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& radianceR = sceneTextures.voxels.radianceR.emplace_back();
radianceR.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& radianceG = sceneTextures.voxels.radianceG.emplace_back();
radianceG.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& radianceB = sceneTextures.voxels.radianceB.emplace_back();
radianceB.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& radianceA = sceneTextures.voxels.radianceA.emplace_back();
radianceA.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& count = sceneTextures.voxels.count.emplace_back();
count.fromBuffers( NULL, 0, uf::renderer::enums::Format::R32_UINT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& output = sceneTextures.voxels.output.emplace_back();
if ( metadata.filtering == "NEAREST" ) {
radiance.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
radiance.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
output.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
output.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
}
radiance.fromBuffers( NULL, 0, uf::renderer::settings::pipelines::hdr ? uf::renderer::enums::Format::HDR : uf::renderer::enums::Format::SDR, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
// auto& depth = sceneTextures.voxels.depth.emplace_back();
// depth.fromBuffers( (void*) empty.data(), empty.size(), uf::renderer::enums::Format::R16_SFLOAT, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
output.fromBuffers( NULL, 0, uf::renderer::settings::pipelines::hdr ? uf::renderer::enums::Format::HDR : uf::renderer::enums::Format::SDR, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
}
// initialize render mode
{
@ -99,11 +119,16 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
for ( size_t i = 0; i < maxTexturesCube; ++i ) renderMode.blitter.material.textures.emplace_back().aliasTexture(uf::renderer::TextureCube::empty);
for ( size_t i = 0; i < maxTextures3D; ++i ) renderMode.blitter.material.textures.emplace_back().aliasTexture(uf::renderer::Texture3D::empty);
for ( auto& t : sceneTextures.voxels.id ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.normal ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.uv ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radiance ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.depth ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.drawId ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.instanceId ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.normalX ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.normalY ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceR ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceG ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceB ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radianceA ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.count ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.output ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
renderMode.bindCallback( renderMode.CALLBACK_BEGIN, [&]( VkCommandBuffer commandBuffer, size_t _ ){
// clear textures
@ -115,11 +140,16 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
subresourceRange.layerCount = 1;
VkClearColorValue clearColor = { 0.0, 0.0, 0.0, 0.0 };
for ( auto& t : sceneTextures.voxels.id ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.normal ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.uv ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.radiance ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.depth ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.drawId ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.instanceId ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.normalX ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.normalY ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.radianceR ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.radianceG ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.radianceB ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.radianceA ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.count ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.output ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
});
//
@ -136,7 +166,7 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
subresourceRange.baseMipLevel = 0;
subresourceRange.baseArrayLayer = 0;
subresourceRange.layerCount = 1;
for ( auto& t : sceneTextures.voxels.radiance ) {
for ( auto& t : sceneTextures.voxels.output ) {
subresourceRange.levelCount = t.mips;
t.setImageLayout(
commandBuffer,