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": { "vxgi": {
// "limiter": 0, "limiter": 0,
"limiter": 0.5, // "limiter": 0.5,
"size": 128, "size": 256,
"dispatch": 8, "dispatch": 8,
"cascades": 3, "cascades": 3,
"cascadePower": 2.0, "cascadePower": 2.0,
@ -288,7 +288,7 @@
"compression": "gz" "compression": "gz"
}, },
"imgui": { "imgui": {
"enabled": false "enabled": true
}, },
"fsr": { "fsr": {
"enabled": true, "enabled": true,

View File

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

View File

@ -17,6 +17,25 @@ float mipLevels( ivec2 size ) {
return floor(log2(max(size.x, size.y))); 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 ) { void toneMap( inout vec3 color, float exposure ) {
color.rgb = vec3(1.0) - exp(-color.rgb * 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 LIGHT_POWER_CUTOFF = 0.0005;
const float LIGHTMAP_GAMMA = 1.0; 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 mipmapLevels;
float radianceSize; float radianceSize;
float radianceSizeRecip; float radianceSizeRecip;
uint state; // yuck
} voxelInfo; } voxelInfo;
// Raytrace stuff // Raytrace stuff

View File

@ -55,7 +55,7 @@ vec4 voxelTrace( inout Ray ray, float aperture, float maxDistance ) {
coneDiameter = coneCoefficient * ray.distance; coneDiameter = coneCoefficient * ray.distance;
level = aperture > 0 ? log2( coneDiameter ) : 0; level = aperture > 0 ? log2( coneDiameter ) : 0;
if ( level >= voxelInfo.mipmapLevels ) break; 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; color += (1.0 - color.a) * radiance;
occlusion += ((1.0f - occlusion) * radiance.a) / (1.0f + occlusionFalloff * coneDiameter); 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; return 1.0 - voxelTrace( ray, SHADOW_APERTURE, z ).a;
} }
void indirectLightingVXGI() { void indirectLightingVXGI() {
voxelInfo.radianceSize = textureSize( voxelRadiance[0], 0 ).x; voxelInfo.radianceSize = textureSize( voxelOutput[0], 0 ).x;
voxelInfo.radianceSizeRecip = 1.0 / voxelInfo.radianceSize; voxelInfo.radianceSizeRecip = 1.0 / voxelInfo.radianceSize;
voxelInfo.mipmapLevels = log2(voxelInfo.radianceSize) + 1; voxelInfo.mipmapLevels = log2(voxelInfo.radianceSize) + 1;
#if VXGI_NDC #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 = 18) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 19) uniform sampler3D samplerNoise; layout (binding = 19) uniform sampler3D samplerNoise;
#if VXGI #if VXGI
layout (binding = 20) uniform usampler3D voxelId[CASCADES]; layout (binding = 20) uniform usampler3D voxelDrawId[CASCADES];
layout (binding = 21) uniform sampler3D voxelNormal[CASCADES]; layout (binding = 21) uniform usampler3D voxelInstanceId[CASCADES];
layout (binding = 22) uniform sampler3D voxelRadiance[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 #endif
#if RT #if RT
layout (binding = 23) uniform accelerationStructureEXT tlas; layout (binding = 30) uniform accelerationStructureEXT tlas;
#endif #endif
#if BUFFER_REFERENCE #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 = 8) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 9) uniform sampler3D samplerNoise; layout (binding = 9) uniform sampler3D samplerNoise;
layout (binding = 10, rg16ui) uniform volatile coherent uimage3D voxelId[CASCADES]; layout (binding = 10, r32ui) uniform volatile coherent uimage3D voxelDrawId[CASCADES];
layout (binding = 11, rg16f) uniform volatile coherent image3D voxelNormal[CASCADES]; layout (binding = 11, r32ui) uniform volatile coherent uimage3D voxelInstanceId[CASCADES];
#if VXGI_HDR layout (binding = 12, r32ui) uniform volatile coherent uimage3D voxelNormalX[CASCADES];
layout (binding = 12, rgba32f) uniform volatile coherent image3D voxelRadiance[CASCADES]; layout (binding = 13, r32ui) uniform volatile coherent uimage3D voxelNormalY[CASCADES];
#else layout (binding = 14, r32ui) uniform volatile coherent uimage3D voxelRadianceR[CASCADES];
layout (binding = 12, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES]; layout (binding = 15, r32ui) uniform volatile coherent uimage3D voxelRadianceG[CASCADES];
#endif 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/functions.h"
#include "../../common/light.h" #include "../../common/light.h"
@ -65,10 +68,14 @@ layout (binding = 11, rg16f) uniform volatile coherent image3D voxelNormal[CASCA
void main() { void main() {
const vec3 tUvw = gl_GlobalInvocationID.xzy; const vec3 tUvw = gl_GlobalInvocationID.xzy;
for ( uint CASCADE = 0; CASCADE < CASCADES; ++CASCADE ) { 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.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.position.world = vec3( inverse(ubo.settings.vxgi.matrix) * vec4( surface.position.eye, 1.0f ) );
surface.pass = 0; // PushConstant.pass; surface.pass = 0; // PushConstant.pass;
@ -78,10 +85,32 @@ void main() {
surface.material.indirect = vec4(0); surface.material.indirect = vec4(0);
#if 0 #if 0
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;
/*
vec4 A = vec4(surface.normal.world, 1.0);
*/
#endif
surface.material.albedo = A;
surface.fragment.rgb = surface.material.albedo.rgb; surface.fragment.rgb = surface.material.albedo.rgb;
const bool DISCARD_DUE_TO_DIVERGENCE = surface.material.albedo.a == 0;
#else #else
const uvec2 ID = uvec2(imageLoad(voxelId[CASCADE], ivec3(tUvw) ).xy); 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 bool DISCARD_DUE_TO_DIVERGENCE = ID.x == 0 || ID.y == 0;
const uint drawID = ID.x == 0 ? 0 : ID.x - 1; const uint drawID = ID.x == 0 ? 0 : ID.x - 1;
@ -90,7 +119,7 @@ void main() {
// if ( ID.x == 0 || ID.y == 0 ) { // if ( ID.x == 0 || ID.y == 0 ) {
#if 1 #if 1
if ( DISCARD_DUE_TO_DIVERGENCE ) { if ( DISCARD_DUE_TO_DIVERGENCE ) {
imageStore(voxelRadiance[CASCADE], ivec3(tUvw), vec4(0)); imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(0));
continue; continue;
} }
#endif #endif
@ -101,7 +130,21 @@ void main() {
surface.material.albedo = material.colorBase; surface.material.albedo = material.colorBase;
surface.fragment = material.colorEmissive; 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.metallic = material.factorMetallic;
surface.material.roughness = material.factorRoughness; surface.material.roughness = material.factorRoughness;
surface.material.occlusion = material.factorOcclusion; surface.material.occlusion = material.factorOcclusion;
@ -167,12 +210,12 @@ void main() {
#endif #endif
#if 0 #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 #else
if ( DISCARD_DUE_TO_DIVERGENCE ) { if ( DISCARD_DUE_TO_DIVERGENCE ) {
imageStore(voxelRadiance[CASCADE], ivec3(tUvw), vec4(0)); imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(0));
} else { } 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 #endif
} }

View File

@ -12,7 +12,11 @@ layout( push_constant ) uniform PushBlock {
uint mip; uint mip;
} PushConstant; } 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[] = { const float gaussianWeights[] = {
//Top slice //Top slice

View File

@ -7,8 +7,7 @@
#define DEFERRED_SAMPLING 0 #define DEFERRED_SAMPLING 0
#define CUBEMAPS 1 #define CUBEMAPS 1
#define BLEND 1 #define BLEND 0
#define DEPTH_TEST 0
#define USE_LIGHTMAP 1 #define USE_LIGHTMAP 1
layout (constant_id = 0) const uint TEXTURES = 512; layout (constant_id = 0) const uint TEXTURES = 512;
layout (constant_id = 1) const uint CASCADES = 16; layout (constant_id = 1) const uint CASCADES = 16;
@ -38,16 +37,16 @@ layout (std140, binding = 11) readonly buffer Lights {
Light lights[]; Light lights[];
}; };
layout (binding = 12, rg16ui) uniform volatile coherent uimage3D voxelId[CASCADES]; layout (binding = 12, r32ui) uniform volatile coherent uimage3D voxelDrawId[CASCADES];
layout (binding = 13, rg16f) uniform volatile coherent image3D voxelNormal[CASCADES]; layout (binding = 13, r32ui) uniform volatile coherent uimage3D voxelInstanceId[CASCADES];
#if VXGI_HDR layout (binding = 14, r32ui) uniform volatile coherent uimage3D voxelNormalX[CASCADES];
layout (binding = 14, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES]; layout (binding = 15, r32ui) uniform volatile coherent uimage3D voxelNormalY[CASCADES];
#else layout (binding = 16, r32ui) uniform volatile coherent uimage3D voxelRadianceR[CASCADES];
layout (binding = 14, rgba8) uniform volatile coherent image3D voxelRadiance[CASCADES]; layout (binding = 17, r32ui) uniform volatile coherent uimage3D voxelRadianceG[CASCADES];
#endif layout (binding = 18, r32ui) uniform volatile coherent uimage3D voxelRadianceB[CASCADES];
#if DEPTH_TEST layout (binding = 19, r32ui) uniform volatile coherent uimage3D voxelRadianceA[CASCADES];
layout (binding = 15, r16f) uniform volatile coherent image3D voxelDepth[CASCADES]; layout (binding = 20, r32ui) uniform volatile coherent uimage3D voxelCount[CASCADES];
#endif layout (binding = 21, rgba16f) uniform volatile coherent image3D voxelOutput[CASCADES];
layout (location = 0) flat in uvec4 inId; layout (location = 0) flat in uvec4 inId;
layout (location = 1) flat in vec4 inPOS0; layout (location = 1) flat in vec4 inPOS0;
@ -120,23 +119,20 @@ void main() {
N = TBN * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - 1.0 ); 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 imageAtomicMax(voxelDrawId[CASCADE], ivec3(uvw), uint( drawID + 1 ) );
const float outDepth = length(inPosition.xzy); imageAtomicMax(voxelInstanceId[CASCADE], ivec3(uvw), uint( instanceID + 1 ) );
const float inDepth = imageLoad(voxelDepth[CASCADE], uvw).r;
if ( inDepth != 0 && inDepth < outDepth ) discard;
imageStore(voxelDepth[CASCADE], uvw, vec4(inDepth, 0, 0, 0));
#endif
imageStore(voxelId[CASCADE], uvw, uvec4(uvec2(drawID + 1, instanceID + 1), 0, 0)); vec2 N_E = encodeNormals( normalize( N ) );
imageStore(voxelNormal[CASCADE], uvw, vec4(encodeNormals( normalize( N ) ), 0, 0)); imageAtomicMin(voxelNormalX[CASCADE], ivec3(uvw), uint( floatBitsToUint( N_E.x ) ) );
#if BLEND imageAtomicMin(voxelNormalY[CASCADE], ivec3(uvw), uint( floatBitsToUint( N_E.y ) ) );
// GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
const vec4 src = A * inColor; imageAtomicAdd(voxelRadianceR[CASCADE], ivec3(uvw), uint( A.r * 256 ) );
const vec4 dst = imageLoad(voxelRadiance[CASCADE], uvw); imageAtomicAdd(voxelRadianceG[CASCADE], ivec3(uvw), uint( A.g * 256 ) );
imageStore(voxelRadiance[CASCADE], uvw, blend( src, dst, src.a ) ); imageAtomicAdd(voxelRadianceB[CASCADE], ivec3(uvw), uint( A.b * 256 ) );
#else imageAtomicAdd(voxelRadianceA[CASCADE], ivec3(uvw), uint( A.a * 256 ) );
imageStore(voxelRadiance[CASCADE], uvw, A ); imageAtomicAdd(voxelCount[CASCADE], ivec3(uvw), uint( 1 ) );
#endif
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::Texture3D noise;
uf::renderer::TextureCube skybox; uf::renderer::TextureCube skybox;
struct { struct {
uf::stl::vector<uf::renderer::Texture3D> id; uf::stl::vector<uf::renderer::Texture3D> drawId;
uf::stl::vector<uf::renderer::Texture3D> uv; uf::stl::vector<uf::renderer::Texture3D> instanceId;
uf::stl::vector<uf::renderer::Texture3D> normal; uf::stl::vector<uf::renderer::Texture3D> normalX;
uf::stl::vector<uf::renderer::Texture3D> radiance; uf::stl::vector<uf::renderer::Texture3D> normalY;
uf::stl::vector<uf::renderer::Texture3D> depth; 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; } 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 ) { if ( uf::renderer::settings::pipelines::vxgi ) {
auto& scene = uf::scene::getCurrentScene(); auto& scene = uf::scene::getCurrentScene();
auto& sceneTextures = scene.getComponent<pod::SceneTextures>(); auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
for ( auto& t : sceneTextures.voxels.id ) 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.normal ) 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.uv ) 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.radiance ) 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.depth ) 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 #endif
} }
@ -361,11 +366,16 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
} }
{ {
uint32_t voxelTypes = 0; uint32_t voxelTypes = 0;
if ( !sceneTextures.voxels.id.empty() ) ++voxelTypes; if ( !sceneTextures.voxels.drawId.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.normal.empty() ) ++voxelTypes; if ( !sceneTextures.voxels.instanceId.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.uv.empty() ) ++voxelTypes; if ( !sceneTextures.voxels.normalX.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.radiance.empty() ) ++voxelTypes; if ( !sceneTextures.voxels.normalY.empty() ) ++voxelTypes;
if ( !sceneTextures.voxels.depth.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 maxTextures = texture2Ds;
uint32_t maxCascades = texture3Ds / voxelTypes; uint32_t maxCascades = texture3Ds / voxelTypes;
@ -377,10 +387,16 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
}); });
shader.setDescriptorCounts({ shader.setDescriptorCounts({
{ "samplerTextures", maxTextures }, { "samplerTextures", maxTextures },
{ "voxelId", maxCascades }, { "voxelDrawId", maxCascades },
{ "voxelUv", maxCascades }, { "voxelInstanceId", maxCascades },
{ "voxelNormal", maxCascades }, { "voxelNormalX", maxCascades },
{ "voxelRadiance", maxCascades }, { "voxelNormalY", maxCascades },
{ "voxelRadianceR", maxCascades },
{ "voxelRadianceG", maxCascades },
{ "voxelRadianceB", maxCascades },
{ "voxelRadianceA", maxCascades },
{ "voxelCount", maxCascades },
{ "voxelOutput", maxCascades },
}); });
shader.buffers.emplace_back( storage.buffers.drawCommands.alias() ); shader.buffers.emplace_back( storage.buffers.drawCommands.alias() );

View File

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

View File

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

View File

@ -210,10 +210,16 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
shader.setDescriptorCounts({ shader.setDescriptorCounts({
{ "samplerTextures", maxTextures2D }, { "samplerTextures", maxTextures2D },
{ "samplerCubemaps", maxTexturesCube }, { "samplerCubemaps", maxTexturesCube },
{ "voxelId", maxCascades }, { "voxelDrawId", maxCascades },
{ "voxelUv", maxCascades }, { "voxelInstanceId", maxCascades },
{ "voxelNormal", maxCascades }, { "voxelNormalX", maxCascades },
{ "voxelRadiance", 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>() ) { if ( this->hasComponent<pod::SceneTextures>() ) {
auto& sceneTextures = this->getComponent<pod::SceneTextures>(); auto& sceneTextures = this->getComponent<pod::SceneTextures>();
for ( auto& t : sceneTextures.voxels.id ) t.destroy(); for ( auto& t : sceneTextures.voxels.drawId ) t.destroy();
sceneTextures.voxels.id.clear(); 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.drawId.clear();
sceneTextures.voxels.normal.clear(); sceneTextures.voxels.instanceId.clear();
sceneTextures.voxels.normalX.clear();
for ( auto& t : sceneTextures.voxels.uv ) t.destroy(); sceneTextures.voxels.normalY.clear();
sceneTextures.voxels.uv.clear(); sceneTextures.voxels.radianceR.clear();
sceneTextures.voxels.radianceG.clear();
for ( auto& t : sceneTextures.voxels.radiance ) t.destroy(); sceneTextures.voxels.radianceB.clear();
sceneTextures.voxels.radiance.clear(); sceneTextures.voxels.radianceA.clear();
sceneTextures.voxels.count.clear();
for ( auto& t : sceneTextures.voxels.depth ) t.destroy(); sceneTextures.voxels.output.clear();
sceneTextures.voxels.depth.clear();
sceneTextures.noise.destroy(); sceneTextures.noise.destroy();
sceneTextures.skybox.destroy(); sceneTextures.skybox.destroy();
@ -1049,11 +1056,16 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
// attach VXGI voxels // attach VXGI voxels
if ( uf::renderer::settings::pipelines::vxgi ) { if ( uf::renderer::settings::pipelines::vxgi ) {
for ( auto& t : sceneTextures.voxels.id ) textures3D.emplace_back().aliasTexture(t); for ( auto& t : sceneTextures.voxels.drawId ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.normal ) textures3D.emplace_back().aliasTexture(t); for ( auto& t : sceneTextures.voxels.instanceId ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.uv ) textures3D.emplace_back().aliasTexture(t); for ( auto& t : sceneTextures.voxels.normalX ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.radiance ) textures3D.emplace_back().aliasTexture(t); for ( auto& t : sceneTextures.voxels.normalY ) textures3D.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.depth ) 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 // bind textures
while ( textures2D.size() < metadata.max.textures2D ) textures2D.emplace_back().aliasTexture(uf::renderer::Texture2D::empty); 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 ) { for ( size_t i = 0; i < metadata.cascades; ++i ) {
const bool HDR = false; const bool HDR = false;
auto& id = sceneTextures.voxels.id.emplace_back(); auto& drawId = sceneTextures.voxels.drawId.emplace_back();
id.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST; drawId.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
id.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST; drawId.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 ); 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(); auto& instanceId = sceneTextures.voxels.instanceId.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 ); instanceId.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
auto& normal = sceneTextures.voxels.normal.emplace_back(); instanceId.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
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 ); 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& radiance = sceneTextures.voxels.radiance.emplace_back();
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" ) { if ( metadata.filtering == "NEAREST" ) {
radiance.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST; output.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
radiance.sampler.descriptor.filter.mag = 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 ); 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 );
// 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 );
} }
// initialize render mode // 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 < 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 ( 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.drawId ) 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.instanceId ) 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.normalX ) 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.normalY ) 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.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 _ ){ renderMode.bindCallback( renderMode.CALLBACK_BEGIN, [&]( VkCommandBuffer commandBuffer, size_t _ ){
// clear textures // clear textures
@ -115,11 +140,16 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
subresourceRange.layerCount = 1; subresourceRange.layerCount = 1;
VkClearColorValue clearColor = { 0.0, 0.0, 0.0, 0.0 }; 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.drawId ) 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.instanceId ) 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.normalX ) 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.normalY ) 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.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.baseMipLevel = 0;
subresourceRange.baseArrayLayer = 0; subresourceRange.baseArrayLayer = 0;
subresourceRange.layerCount = 1; subresourceRange.layerCount = 1;
for ( auto& t : sceneTextures.voxels.radiance ) { for ( auto& t : sceneTextures.voxels.output ) {
subresourceRange.levelCount = t.mips; subresourceRange.levelCount = t.mips;
t.setImageLayout( t.setImageLayout(
commandBuffer, commandBuffer,