vxgi optimizations (to-do: fix the stuttering again from the UBO lagging or something)
This commit is contained in:
parent
ec2122ab12
commit
682dd2c794
@ -109,7 +109,7 @@
|
|||||||
"invariant": {
|
"invariant": {
|
||||||
"default stage buffers": true,
|
"default stage buffers": true,
|
||||||
"default defer buffer destroy": true,
|
"default defer buffer destroy": true,
|
||||||
"default command buffer immediate": true,
|
"default command buffer immediate": false,
|
||||||
"multithreaded recording": true
|
"multithreaded recording": true
|
||||||
},
|
},
|
||||||
"pipelines": {
|
"pipelines": {
|
||||||
@ -117,10 +117,10 @@
|
|||||||
"gui": true,
|
"gui": true,
|
||||||
"vsync": true, // vsync on vulkan side rather than engine-side
|
"vsync": true, // vsync on vulkan side rather than engine-side
|
||||||
"hdr": true,
|
"hdr": true,
|
||||||
"vxgi": false,
|
"vxgi": true,
|
||||||
"culling": false,
|
"culling": false,
|
||||||
"bloom": true,
|
"bloom": false,
|
||||||
"dof": true,
|
"dof": false,
|
||||||
"rt": false,
|
"rt": false,
|
||||||
"fsr": false,
|
"fsr": false,
|
||||||
"postProcess": false // "postProcess.chromab" // false
|
"postProcess": false // "postProcess.chromab" // false
|
||||||
@ -299,7 +299,7 @@
|
|||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
"imgui": {
|
"imgui": {
|
||||||
"enabled": true
|
"enabled": false
|
||||||
},
|
},
|
||||||
"fsr": {
|
"fsr": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|||||||
@ -2,6 +2,10 @@
|
|||||||
float random(vec3 seed, int i){ return fract(sin(dot(vec4(seed,i), vec4(12.9898,78.233,45.164,94.673))) * 43758.5453); }
|
float random(vec3 seed, int i){ return fract(sin(dot(vec4(seed,i), vec4(12.9898,78.233,45.164,94.673))) * 43758.5453); }
|
||||||
float rand2(vec2 co){ return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 143758.5453); }
|
float rand2(vec2 co){ return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 143758.5453); }
|
||||||
float rand3(vec3 co){ return fract(sin(dot(co.xyz ,vec3(12.9898,78.233, 37.719))) * 143758.5453); }
|
float rand3(vec3 co){ return fract(sin(dot(co.xyz ,vec3(12.9898,78.233, 37.719))) * 143758.5453); }
|
||||||
|
float interleavedGradientNoise(vec2 co) {
|
||||||
|
vec3 seed = vec3(0.06711056, 0.00583715, 52.9829189);
|
||||||
|
return fract(seed.z * fract(dot(co, seed.xy)));
|
||||||
|
}
|
||||||
//
|
//
|
||||||
float mipLevel( in vec2 dx_vtc, in vec2 dy_vtc ) {
|
float mipLevel( in vec2 dx_vtc, in vec2 dy_vtc ) {
|
||||||
const float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
|
const float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
|
||||||
@ -44,7 +48,8 @@ void gammaCorrect( inout vec3 color, float gamma ) {
|
|||||||
}
|
}
|
||||||
void toneMap( inout vec4 color, float exposure ) { toneMap(color.rgb, exposure); }
|
void toneMap( inout vec4 color, float exposure ) { toneMap(color.rgb, exposure); }
|
||||||
void gammaCorrect( inout vec4 color, float gamma ) { gammaCorrect(color.rgb, gamma); }
|
void gammaCorrect( inout vec4 color, float gamma ) { gammaCorrect(color.rgb, gamma); }
|
||||||
float luma( vec3 color ) { return dot(color, vec3(0.2126, 0.7152, 0.0722)); }
|
float luma( vec3 color ) { return dot(color, vec3(0.2126, 0.7152, 0.0722)); } // REF 709
|
||||||
|
float luminance( vec3 color ) { return dot(color, vec3(0.299, 0.587, 0.114)); } // REF 601
|
||||||
//
|
//
|
||||||
uint tea(uint val0, uint val1) {
|
uint tea(uint val0, uint val1) {
|
||||||
uint v0 = val0;
|
uint v0 = val0;
|
||||||
|
|||||||
@ -94,19 +94,10 @@ layout (binding = 18) uniform sampler2D samplerTextures[TEXTURES];
|
|||||||
layout (binding = 19) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
layout (binding = 19) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||||
layout (binding = 20) uniform sampler3D samplerNoise;
|
layout (binding = 20) uniform sampler3D samplerNoise;
|
||||||
#if VXGI
|
#if VXGI
|
||||||
layout (binding = 21) uniform usampler3D voxelDrawId[CASCADES];
|
layout (binding = 21) uniform sampler3D voxelOutput[CASCADES];
|
||||||
layout (binding = 22) uniform usampler3D voxelInstanceId[CASCADES];
|
|
||||||
layout (binding = 23) uniform sampler3D voxelNormalX[CASCADES];
|
|
||||||
layout (binding = 24) uniform sampler3D voxelNormalY[CASCADES];
|
|
||||||
layout (binding = 25) uniform sampler3D voxelRadianceR[CASCADES];
|
|
||||||
layout (binding = 26) uniform sampler3D voxelRadianceG[CASCADES];
|
|
||||||
layout (binding = 27) uniform sampler3D voxelRadianceB[CASCADES];
|
|
||||||
layout (binding = 28) uniform sampler3D voxelRadianceA[CASCADES];
|
|
||||||
layout (binding = 29) uniform sampler3D voxelCount[CASCADES];
|
|
||||||
layout (binding = 30) uniform sampler3D voxelOutput[CASCADES];
|
|
||||||
#endif
|
#endif
|
||||||
#if RT
|
#if RT
|
||||||
layout (binding = 31) uniform accelerationStructureEXT tlas;
|
layout (binding = 22) uniform accelerationStructureEXT tlas;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUFFER_REFERENCE
|
#if BUFFER_REFERENCE
|
||||||
@ -296,7 +287,7 @@ void directLighting() {
|
|||||||
surface.material.albedo.rgb = radiance.rgb;
|
surface.material.albedo.rgb = radiance.rgb;
|
||||||
surface.material.indirect.rgb = vec3(0);
|
surface.material.indirect.rgb = vec3(0);
|
||||||
surface.fragment.rgb = radiance.rgb;
|
surface.fragment.rgb = radiance.rgb;
|
||||||
surface.fragment.a = radiance.a;
|
surface.fragment.a = 1; // radiance.a;
|
||||||
//return;
|
//return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -50,18 +50,11 @@ layout (std140, binding = 7) readonly buffer Lights {
|
|||||||
|
|
||||||
layout (binding = 8) uniform sampler2D samplerTextures[TEXTURES];
|
layout (binding = 8) uniform sampler2D samplerTextures[TEXTURES];
|
||||||
layout (binding = 9) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
layout (binding = 9) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||||
layout (binding = 10) uniform sampler3D samplerNoise;
|
|
||||||
|
|
||||||
layout (binding = 11, r32ui) uniform readonly uimage3D voxelDrawId[CASCADES];
|
layout (binding = 10, r32ui) uniform readonly uimage3D voxelId[CASCADES];
|
||||||
layout (binding = 12, r32ui) uniform readonly uimage3D voxelInstanceId[CASCADES];
|
layout (binding = 11, r32ui) uniform readonly uimage3D voxelNormal[CASCADES];
|
||||||
layout (binding = 13, r32ui) uniform readonly uimage3D voxelNormalX[CASCADES];
|
layout (binding = 12, r32ui) uniform readonly uimage3D voxelRadiance[CASCADES];
|
||||||
layout (binding = 14, r32ui) uniform readonly uimage3D voxelNormalY[CASCADES];
|
layout (binding = 13, rgba8) uniform writeonly image3D voxelOutput[CASCADES];
|
||||||
layout (binding = 15, r32ui) uniform readonly uimage3D voxelRadianceR[CASCADES];
|
|
||||||
layout (binding = 16, r32ui) uniform readonly uimage3D voxelRadianceG[CASCADES];
|
|
||||||
layout (binding = 17, r32ui) uniform readonly uimage3D voxelRadianceB[CASCADES];
|
|
||||||
layout (binding = 18, r32ui) uniform readonly uimage3D voxelRadianceA[CASCADES];
|
|
||||||
layout (binding = 19, r32ui) uniform readonly uimage3D voxelCount[CASCADES];
|
|
||||||
layout (binding = 20, rgba8) uniform writeonly image3D voxelOutput[CASCADES];
|
|
||||||
|
|
||||||
#include "../../common/functions.h"
|
#include "../../common/functions.h"
|
||||||
#include "../../common/light.h"
|
#include "../../common/light.h"
|
||||||
@ -71,55 +64,27 @@ layout (binding = 20, rgba8) uniform writeonly image3D voxelOutput[CASCADES];
|
|||||||
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 ) {
|
||||||
vec2 N_E = vec2(
|
#if 0
|
||||||
uintBitsToFloat(imageLoad(voxelNormalX[CASCADE], ivec3(tUvw) ).x),
|
vec4 A = unpackUnorm4x8(imageLoad(voxelRadiance[CASCADE], ivec3(tUvw)).r);
|
||||||
uintBitsToFloat(imageLoad(voxelNormalY[CASCADE], ivec3(tUvw) ).x)
|
A.a = length(luma(A.rgb)) > 0.001 ? 1 : 0;
|
||||||
);
|
imageStore(voxelOutput[CASCADE], ivec3(tUvw), A);
|
||||||
|
#else
|
||||||
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(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;
|
surface.pass = 0; // PushConstant.pass;
|
||||||
surface.fragment = vec4(0);
|
surface.fragment = vec4(0);
|
||||||
surface.light = vec4(0);
|
surface.light = vec4(0);
|
||||||
surface.motion = vec2(0);
|
surface.motion = vec2(0);
|
||||||
surface.material.indirect = vec4(0);
|
surface.material.indirect = vec4(0);
|
||||||
|
|
||||||
#if 0
|
const uint packedID = imageLoad(voxelId[CASCADE], ivec3(tUvw) ).x;
|
||||||
#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;
|
|
||||||
|
|
||||||
const bool DISCARD_DUE_TO_DIVERGENCE = surface.material.albedo.a == 0;
|
|
||||||
#else
|
|
||||||
const uvec2 ID = uvec2(
|
const uvec2 ID = uvec2(
|
||||||
imageLoad(voxelDrawId[CASCADE], ivec3(tUvw) ).x,
|
(packedID & 0xFFFF),
|
||||||
imageLoad(voxelInstanceId[CASCADE], ivec3(tUvw) ).x
|
(packedID >> 16)
|
||||||
);
|
);
|
||||||
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;
|
||||||
const uint instanceID = ID.y == 0 ? 0 : ID.y - 1;
|
const uint instanceID = ID.y == 0 ? 0 : ID.y - 1;
|
||||||
|
|
||||||
// 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 ) {
|
||||||
@ -138,15 +103,8 @@ void main() {
|
|||||||
#if 0
|
#if 0
|
||||||
vec4 A = imageLoad(voxelOutput[CASCADE], ivec3(tUvw) );
|
vec4 A = imageLoad(voxelOutput[CASCADE], ivec3(tUvw) );
|
||||||
#else
|
#else
|
||||||
vec4 A = vec4(0);
|
vec4 A = unpackUnorm4x8(imageLoad(voxelRadiance[CASCADE], ivec3(tUvw)).r);
|
||||||
A.r = imageLoad(voxelRadianceR[CASCADE], ivec3(tUvw) ).r;
|
A.a = 1.0;
|
||||||
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
|
#endif
|
||||||
|
|
||||||
surface.material.albedo = A;
|
surface.material.albedo = A;
|
||||||
@ -205,7 +163,6 @@ void main() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
surface.fragment.rgb += surface.light.rgb;
|
surface.fragment.rgb += surface.light.rgb;
|
||||||
#endif
|
|
||||||
|
|
||||||
#if TONE_MAP
|
#if TONE_MAP
|
||||||
toneMap(surface.fragment.rgb, ubo.settings.bloom.exposure);
|
toneMap(surface.fragment.rgb, ubo.settings.bloom.exposure);
|
||||||
@ -214,14 +171,11 @@ void main() {
|
|||||||
gammaCorrect(surface.fragment.rgb, 1.0 / ubo.settings.bloom.gamma);
|
gammaCorrect(surface.fragment.rgb, 1.0 / ubo.settings.bloom.gamma);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(surface.fragment.rgb, surface.material.albedo.a));
|
|
||||||
#else
|
|
||||||
if ( DISCARD_DUE_TO_DIVERGENCE ) {
|
if ( DISCARD_DUE_TO_DIVERGENCE ) {
|
||||||
imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(0));
|
imageStore(voxelOutput[CASCADE], ivec3(tUvw), vec4(0));
|
||||||
} else {
|
} else {
|
||||||
imageStore(voxelOutput[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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,16 +37,10 @@ layout (std140, binding = 12) readonly buffer Lights {
|
|||||||
Light lights[];
|
Light lights[];
|
||||||
};
|
};
|
||||||
|
|
||||||
layout (binding = 13, r32ui) uniform volatile uimage3D voxelDrawId[CASCADES];
|
layout (binding = 13, r32ui) uniform volatile uimage3D voxelId[CASCADES];
|
||||||
layout (binding = 14, r32ui) uniform volatile uimage3D voxelInstanceId[CASCADES];
|
layout (binding = 14, r32ui) uniform volatile uimage3D voxelNormal[CASCADES];
|
||||||
layout (binding = 15, r32ui) uniform volatile uimage3D voxelNormalX[CASCADES];
|
layout (binding = 15, r32ui) uniform volatile uimage3D voxelRadiance[CASCADES];
|
||||||
layout (binding = 16, r32ui) uniform volatile uimage3D voxelNormalY[CASCADES];
|
layout (binding = 16, rgba8) uniform writeonly image3D voxelOutput[CASCADES];
|
||||||
layout (binding = 17, r32ui) uniform volatile uimage3D voxelRadianceR[CASCADES];
|
|
||||||
layout (binding = 18, r32ui) uniform volatile uimage3D voxelRadianceG[CASCADES];
|
|
||||||
layout (binding = 19, r32ui) uniform volatile uimage3D voxelRadianceB[CASCADES];
|
|
||||||
layout (binding = 20, r32ui) uniform volatile uimage3D voxelRadianceA[CASCADES];
|
|
||||||
layout (binding = 21, r32ui) uniform volatile uimage3D voxelCount[CASCADES];
|
|
||||||
layout (binding = 22, rgba8) uniform writeonly 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;
|
||||||
@ -94,7 +88,8 @@ void main() {
|
|||||||
A.a = 1;
|
A.a = 1;
|
||||||
// alpha mode BLEND
|
// alpha mode BLEND
|
||||||
} else if ( material.modeAlpha == 1 ) {
|
} else if ( material.modeAlpha == 1 ) {
|
||||||
|
float dither = interleavedGradientNoise(gl_FragCoord.xy);
|
||||||
|
// if ( A.a < dither ) discard;
|
||||||
// alpha mode MASK
|
// alpha mode MASK
|
||||||
} else if ( material.modeAlpha == 2 ) {
|
} else if ( material.modeAlpha == 2 ) {
|
||||||
if ( A.a < abs(material.factorAlphaCutoff) ) discard;
|
if ( A.a < abs(material.factorAlphaCutoff) ) discard;
|
||||||
@ -121,16 +116,13 @@ void main() {
|
|||||||
|
|
||||||
const ivec3 uvw = ivec3(P * imageSize(voxelOutput[CASCADE]));
|
const ivec3 uvw = ivec3(P * imageSize(voxelOutput[CASCADE]));
|
||||||
|
|
||||||
imageAtomicMax(voxelDrawId[CASCADE], ivec3(uvw), uint( drawID + 1 ) );
|
uint packedId = ( instanceID + 1 ) << 16 | ( drawID + 1 );
|
||||||
imageAtomicMax(voxelInstanceId[CASCADE], ivec3(uvw), uint( instanceID + 1 ) );
|
imageAtomicMax(voxelId[CASCADE], ivec3(uvw), packedId);
|
||||||
|
|
||||||
vec2 N_E = encodeNormals( normalize( N ) );
|
vec2 N_E = encodeNormals( normalize( N ) );
|
||||||
imageAtomicMin(voxelNormalX[CASCADE], ivec3(uvw), uint( floatBitsToUint( N_E.x ) ) );
|
uint packedNormal = packHalf2x16(N_E);
|
||||||
imageAtomicMin(voxelNormalY[CASCADE], ivec3(uvw), uint( floatBitsToUint( N_E.y ) ) );
|
imageAtomicMin(voxelNormal[CASCADE], uvw, packedNormal);
|
||||||
|
|
||||||
imageAtomicAdd(voxelRadianceR[CASCADE], ivec3(uvw), uint( A.r * 256 ) );
|
uint packedRadiance = packUnorm4x8(vec4(A.rgb, luminance(A.rgb)));
|
||||||
imageAtomicAdd(voxelRadianceG[CASCADE], ivec3(uvw), uint( A.g * 256 ) );
|
imageAtomicMax(voxelRadiance[CASCADE], uvw, packedRadiance);
|
||||||
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 ) );
|
|
||||||
}
|
}
|
||||||
@ -5,15 +5,9 @@ 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> drawId;
|
uf::stl::vector<uf::renderer::Texture3D> id;
|
||||||
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> 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;
|
uf::stl::vector<uf::renderer::Texture3D> output;
|
||||||
} voxels;
|
} voxels;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -59,6 +59,7 @@ namespace ext {
|
|||||||
VkImageViewType viewType = enums::Image::VIEW_TYPE_2D;
|
VkImageViewType viewType = enums::Image::VIEW_TYPE_2D;
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
VkImageUsageFlags usage = {};
|
VkImageUsageFlags usage = {};
|
||||||
|
VkImageCreateFlags flags = {};
|
||||||
VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
|
VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
|
||||||
VkDescriptorImageInfo descriptor = {};
|
VkDescriptorImageInfo descriptor = {};
|
||||||
VkFormat format = enums::Format::R8G8B8A8_UNORM;
|
VkFormat format = enums::Format::R8G8B8A8_UNORM;
|
||||||
@ -102,29 +103,45 @@ namespace ext {
|
|||||||
const uf::stl::string& filename,
|
const uf::stl::string& filename,
|
||||||
VkFormat format = DefaultFormat,
|
VkFormat format = DefaultFormat,
|
||||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
|
VkImageCreateFlags flags = {}
|
||||||
);
|
);
|
||||||
void loadFromFile(
|
void loadFromFile(
|
||||||
const uf::stl::string& filename,
|
const uf::stl::string& filename,
|
||||||
Device& device,
|
Device& device,
|
||||||
VkFormat format = DefaultFormat,
|
VkFormat format = DefaultFormat,
|
||||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
|
VkImageCreateFlags flags = {}
|
||||||
);
|
);
|
||||||
void loadFromImage(
|
void loadFromImage(
|
||||||
const uf::Image& image,
|
const uf::Image& image,
|
||||||
Device& device,
|
Device& device,
|
||||||
VkFormat format = DefaultFormat,
|
VkFormat format = DefaultFormat,
|
||||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
|
VkImageCreateFlags flags = {}
|
||||||
);
|
);
|
||||||
void loadFromImage(
|
void loadFromImage(
|
||||||
const uf::Image& image,
|
const uf::Image& image,
|
||||||
VkFormat format = DefaultFormat,
|
VkFormat format = DefaultFormat,
|
||||||
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
|
VkImageCreateFlags flags = {}
|
||||||
|
);
|
||||||
|
void fromBuffers(
|
||||||
|
void* buffer,
|
||||||
|
VkDeviceSize bufferSize,
|
||||||
|
VkFormat format,
|
||||||
|
uint32_t texWidth,
|
||||||
|
uint32_t texHeight,
|
||||||
|
uint32_t texDepth,
|
||||||
|
uint32_t layers,
|
||||||
|
Device& device,
|
||||||
|
VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
|
VkImageCreateFlags flags = {}
|
||||||
);
|
);
|
||||||
void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, uint32_t texDepth, uint32_t layers, Device& device, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL );
|
|
||||||
void asRenderTarget( Device& device, uint32_t texWidth, uint32_t texHeight, VkFormat format = DefaultFormat );
|
void asRenderTarget( Device& device, uint32_t texWidth, uint32_t texHeight, VkFormat format = DefaultFormat );
|
||||||
|
|
||||||
Texture alias() const;
|
Texture alias() const;
|
||||||
@ -136,14 +153,14 @@ namespace ext {
|
|||||||
void update( uf::Image& image, VkImageLayout, uint32_t layer = 1 );
|
void update( uf::Image& image, VkImageLayout, uint32_t layer = 1 );
|
||||||
void update( void*, VkDeviceSize, VkImageLayout, uint32_t layer = 1 );
|
void update( void*, VkDeviceSize, VkImageLayout, uint32_t layer = 1 );
|
||||||
|
|
||||||
inline void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, Device& device, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ) { return this->fromBuffers(buffer, bufferSize, format, texWidth, texHeight, 1, 1, device, usage, layout); }
|
inline void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, Device& device, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VkImageCreateFlags flags = {} ) { return this->fromBuffers(buffer, bufferSize, format, texWidth, texHeight, 1, 1, device, usage, layout, flags); }
|
||||||
inline void update( uf::Image& image, uint32_t layer = 1 ) { return this->update(image, this->layout, layer); }
|
inline void update( uf::Image& image, uint32_t layer = 1 ) { return this->update(image, this->layout, layer); }
|
||||||
inline void update( void* data, VkDeviceSize size, uint32_t layer = 1 ) { return this->update(data, size, this->layout, layer); }
|
inline void update( void* data, VkDeviceSize size, uint32_t layer = 1 ) { return this->update(data, size, this->layout, layer); }
|
||||||
|
|
||||||
void generateMipmaps(VkCommandBuffer commandBuffer, uint32_t layer = 0);
|
void generateMipmaps(VkCommandBuffer commandBuffer, uint32_t layer = 0);
|
||||||
|
|
||||||
void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, uint32_t texDepth, uint32_t layers, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL );
|
void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, uint32_t texDepth, uint32_t layers, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VkImageCreateFlags flags = {} );
|
||||||
inline void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ) { return this->fromBuffers(buffer, bufferSize, format, texWidth, texHeight, 1, 1, usage, layout); }
|
inline void fromBuffers( void* buffer, VkDeviceSize bufferSize, VkFormat format, uint32_t texWidth, uint32_t texHeight, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VkImageCreateFlags flags = {} ) { return this->fromBuffers(buffer, bufferSize, format, texWidth, texHeight, 1, 1, usage, layout, flags); }
|
||||||
};
|
};
|
||||||
class UF_API Texture2D : public Texture {
|
class UF_API Texture2D : public Texture {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -384,7 +384,9 @@ void ext::GuiGlyphBehavior::initialize( uf::Object& self ) {
|
|||||||
bool forced = payload["force"].as(false);
|
bool forced = payload["force"].as(false);
|
||||||
|
|
||||||
// override
|
// override
|
||||||
// metadata.sdf = false;
|
#if UF_USE_OPENGL
|
||||||
|
metadata.sdf = false;
|
||||||
|
#endif
|
||||||
metadataGui.scaling = "none";
|
metadataGui.scaling = "none";
|
||||||
|
|
||||||
auto& scene = uf::scene::getCurrentScene();
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
|
|||||||
@ -225,39 +225,11 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
|
|||||||
shader.setDescriptorCounts({
|
shader.setDescriptorCounts({
|
||||||
{ "samplerTextures", maxTextures2D },
|
{ "samplerTextures", maxTextures2D },
|
||||||
{ "samplerCubemaps", maxTexturesCube },
|
{ "samplerCubemaps", maxTexturesCube },
|
||||||
{ "voxelDrawId", maxCascades },
|
{ "voxelId", maxCascades },
|
||||||
{ "voxelInstanceId", maxCascades },
|
{ "voxelNormal", maxCascades },
|
||||||
{ "voxelNormalX", maxCascades },
|
{ "voxelRadiance", maxCascades },
|
||||||
{ "voxelNormalY", maxCascades },
|
|
||||||
{ "voxelRadianceR", maxCascades },
|
|
||||||
{ "voxelRadianceG", maxCascades },
|
|
||||||
{ "voxelRadianceB", maxCascades },
|
|
||||||
{ "voxelRadianceA", maxCascades },
|
|
||||||
{ "voxelCount", maxCascades },
|
|
||||||
{ "voxelOutput", maxCascades },
|
{ "voxelOutput", maxCascades },
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;
|
|
||||||
for ( auto pair : shader.metadata.definitions.specializationConstants ) {
|
|
||||||
auto& sc = pair.second;
|
|
||||||
if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures2D);
|
|
||||||
else if ( sc.name == "CUBEMAPS" ) sc.value.ui = (specializationConstants[sc.index] = maxTexturesCube);
|
|
||||||
else if ( sc.name == "CASCADES" ) sc.value.ui = (specializationConstants[sc.index] = maxCascades);
|
|
||||||
}
|
|
||||||
for ( auto pair : shader.metadata.definitions.textures ) {
|
|
||||||
auto& tx = pair.second;
|
|
||||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
|
||||||
if ( layout.binding != tx.binding ) continue;
|
|
||||||
if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures2D;
|
|
||||||
else if ( tx.name == "samplerCubemaps" ) layout.descriptorCount = maxTexturesCube;
|
|
||||||
else if ( tx.name == "voxelId" ) layout.descriptorCount = maxCascades;
|
|
||||||
else if ( tx.name == "voxelUv" ) layout.descriptorCount = maxCascades;
|
|
||||||
else if ( tx.name == "voxelNormal" ) layout.descriptorCount = maxCascades;
|
|
||||||
else if ( tx.name == "voxelRadiance" ) layout.descriptorCount = maxCascades;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -740,26 +740,14 @@ 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.drawId ) t.destroy();
|
for ( auto& t : sceneTextures.voxels.id ) t.destroy();
|
||||||
for ( auto& t : sceneTextures.voxels.instanceId ) t.destroy();
|
for ( auto& t : sceneTextures.voxels.normal ) t.destroy();
|
||||||
for ( auto& t : sceneTextures.voxels.normalX ) t.destroy();
|
for ( auto& t : sceneTextures.voxels.radiance ) 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.output ) t.destroy();
|
||||||
|
|
||||||
sceneTextures.voxels.drawId.clear();
|
sceneTextures.voxels.id.clear();
|
||||||
sceneTextures.voxels.instanceId.clear();
|
sceneTextures.voxels.normal.clear();
|
||||||
sceneTextures.voxels.normalX.clear();
|
sceneTextures.voxels.radiance.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.voxels.output.clear();
|
||||||
|
|
||||||
sceneTextures.noise.destroy();
|
sceneTextures.noise.destroy();
|
||||||
@ -1136,17 +1124,14 @@ 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.drawId ) textures3D.emplace_back().aliasTexture(t);
|
/*
|
||||||
for ( auto& t : sceneTextures.voxels.instanceId ) textures3D.emplace_back().aliasTexture(t);
|
for ( auto& t : sceneTextures.voxels.id ) textures3D.emplace_back().aliasTexture(t);
|
||||||
for ( auto& t : sceneTextures.voxels.normalX ) textures3D.emplace_back().aliasTexture(t);
|
for ( auto& t : sceneTextures.voxels.normal ) textures3D.emplace_back().aliasTexture(t);
|
||||||
for ( auto& t : sceneTextures.voxels.normalY ) textures3D.emplace_back().aliasTexture(t);
|
for ( auto& t : sceneTextures.voxels.radiance ) 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);
|
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);
|
||||||
while ( texturesCube.size() < metadata.max.texturesCube ) texturesCube.emplace_back().aliasTexture(uf::renderer::TextureCube::empty);
|
while ( texturesCube.size() < metadata.max.texturesCube ) texturesCube.emplace_back().aliasTexture(uf::renderer::TextureCube::empty);
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include "../scene/behavior.h"
|
#include "../scene/behavior.h"
|
||||||
#include <uf/engine/ext.h>
|
#include <uf/engine/ext.h>
|
||||||
|
|
||||||
|
#define ALIAS_OUTPUT_TO_RADIANCE 1
|
||||||
|
|
||||||
UF_BEHAVIOR_REGISTER_CPP(ext::VoxelizerSceneBehavior)
|
UF_BEHAVIOR_REGISTER_CPP(ext::VoxelizerSceneBehavior)
|
||||||
UF_BEHAVIOR_TRAITS_CPP(ext::VoxelizerSceneBehavior, ticks = true, renders = false, thread = "")
|
UF_BEHAVIOR_TRAITS_CPP(ext::VoxelizerSceneBehavior, ticks = true, renders = false, thread = "")
|
||||||
@ -35,44 +36,46 @@ 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& drawId = sceneTextures.voxels.drawId.emplace_back();
|
auto& id = sceneTextures.voxels.id.emplace_back();
|
||||||
drawId.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
|
id.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
|
||||||
drawId.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
|
id.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 );
|
id.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& 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();
|
auto& normal = sceneTextures.voxels.normal.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 );
|
normal.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();
|
auto& radiance = sceneTextures.voxels.radiance.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 );
|
radiance.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();
|
auto& output = sceneTextures.voxels.output.emplace_back();
|
||||||
|
/*
|
||||||
if ( metadata.filtering == "NEAREST" ) {
|
if ( metadata.filtering == "NEAREST" ) {
|
||||||
output.sampler.descriptor.filter.min = 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;
|
output.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// 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 );
|
// 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 );
|
||||||
|
#if ALIAS_OUTPUT_TO_RADIANCE
|
||||||
|
output.aliasTexture( radiance );
|
||||||
|
{
|
||||||
|
VkImageViewCreateInfo viewCreateInfo = {};
|
||||||
|
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
viewCreateInfo.image = radiance.image;
|
||||||
|
viewCreateInfo.viewType = radiance.viewType;
|
||||||
|
viewCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
|
||||||
|
viewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
viewCreateInfo.subresourceRange.baseMipLevel = 0;
|
||||||
|
viewCreateInfo.subresourceRange.levelCount = radiance.mips;
|
||||||
|
viewCreateInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
|
viewCreateInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
VK_CHECK_RESULT(vkCreateImageView(uf::renderer::device.logicalDevice, &viewCreateInfo, nullptr, &output.view));
|
||||||
|
VK_REGISTER_HANDLE( output.view );
|
||||||
|
}
|
||||||
|
#else
|
||||||
output.fromBuffers( NULL, 0, uf::renderer::enums::Format::R8G8B8A8_UNORM, 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::enums::Format::R8G8B8A8_UNORM, metadata.voxelSize.x, metadata.voxelSize.y, metadata.voxelSize.z, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// initialize render mode
|
// initialize render mode
|
||||||
{
|
{
|
||||||
@ -120,15 +123,9 @@ 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.drawId ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
|
for ( auto& t : sceneTextures.voxels.id ) 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.normal ) 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.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);
|
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 _ ){
|
||||||
@ -141,15 +138,9 @@ 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.drawId ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
for ( auto& t : sceneTextures.voxels.id ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||||
for ( auto& t : sceneTextures.voxels.instanceId ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
for ( auto& t : sceneTextures.voxels.normal ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||||
for ( auto& t : sceneTextures.voxels.normalX ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
for ( auto& t : sceneTextures.voxels.radiance ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||||
for ( auto& t : sceneTextures.voxels.normalY ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
|
||||||
for ( auto& t : sceneTextures.voxels.radianceR ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
|
||||||
for ( auto& t : sceneTextures.voxels.radianceG ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
|
||||||
for ( auto& t : sceneTextures.voxels.radianceB ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
|
||||||
for ( auto& t : sceneTextures.voxels.radianceA ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
|
||||||
for ( auto& t : sceneTextures.voxels.count ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
|
||||||
for ( auto& t : sceneTextures.voxels.output ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
for ( auto& t : sceneTextures.voxels.output ) vkCmdClearColorImage( commandBuffer, t.image, t.layout, &clearColor, 1, &subresourceRange );
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -287,15 +278,16 @@ void ext::VoxelizerSceneBehavior::tick( uf::Object& self ) {
|
|||||||
}
|
}
|
||||||
void ext::VoxelizerSceneBehavior::render( uf::Object& self ){}
|
void ext::VoxelizerSceneBehavior::render( uf::Object& self ){}
|
||||||
void ext::VoxelizerSceneBehavior::destroy( uf::Object& self ){
|
void ext::VoxelizerSceneBehavior::destroy( uf::Object& self ){
|
||||||
#if UF_USE_VULKAN
|
#if ALIAS_OUTPUT_TO_RADIANCE
|
||||||
/*
|
auto& sceneTextures = this->getComponent<pod::SceneTextures>();
|
||||||
if ( this->hasComponent<uf::renderer::RenderTargetRenderMode>() ) {
|
for ( auto& t : sceneTextures.voxels.output ) {
|
||||||
auto& renderMode = this->getComponent<uf::renderer::RenderTargetRenderMode>();
|
ext::vulkan::mutex.lock();
|
||||||
|
auto& texture = uf::renderer::device.transient.textures.emplace_back();
|
||||||
uf::renderer::removeRenderMode( &renderMode, false );
|
ext::vulkan::mutex.unlock();
|
||||||
// this->deleteComponent<uf::renderer::RenderTargetRenderMode>();
|
|
||||||
|
texture.device = &uf::renderer::device;
|
||||||
|
texture.view = t.view;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void ext::VoxelizerSceneBehavior::Metadata::serialize( uf::Object& self, uf::Serializer& serializer ) {
|
void ext::VoxelizerSceneBehavior::Metadata::serialize( uf::Object& self, uf::Serializer& serializer ) {
|
||||||
|
|||||||
@ -80,20 +80,23 @@ namespace {
|
|||||||
for ( auto& key : storage.texture2Ds.keys ) graphic.material.textures.emplace_back().aliasTexture( storage.texture2Ds.map[key] );
|
for ( auto& key : storage.texture2Ds.keys ) graphic.material.textures.emplace_back().aliasTexture( storage.texture2Ds.map[key] );
|
||||||
|
|
||||||
// bind scene's voxel texture
|
// bind scene's voxel texture
|
||||||
#if UF_USE_VULKAN
|
#if 0 && UF_USE_VULKAN
|
||||||
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.drawId ) graphic.material.textures.emplace_back().aliasTexture(t);
|
for ( auto& t : sceneTextures.voxels.id ) 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.normal ) 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.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);
|
for ( auto& t : sceneTextures.voxels.output ) graphic.material.textures.emplace_back().aliasTexture(t);
|
||||||
|
/*
|
||||||
|
auto& shader = graphic.material.getShader("fragment", uf::renderer::settings::pipelines::names::vxgi);
|
||||||
|
shader.textures.clear();
|
||||||
|
|
||||||
|
for ( auto& t : sceneTextures.voxels.id ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
|
for ( auto& t : sceneTextures.voxels.normal ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
|
for ( auto& t : sceneTextures.voxels.radiance ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
|
for ( auto& t : sceneTextures.voxels.output ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -219,21 +222,9 @@ namespace {
|
|||||||
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY, uf::renderer::settings::pipelines::names::vxgi);
|
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY, uf::renderer::settings::pipelines::names::vxgi);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t voxelTypes = 0;
|
|
||||||
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 maxTextures = texture2Ds;
|
||||||
uint32_t maxCascades = texture3Ds / voxelTypes;
|
uint32_t maxCascades = sceneTextures.voxels.id.size();
|
||||||
|
|
||||||
// fragment shader
|
// fragment shader
|
||||||
{
|
{
|
||||||
auto& shader = graphic.material.getShader("fragment", uf::renderer::settings::pipelines::names::vxgi);
|
auto& shader = graphic.material.getShader("fragment", uf::renderer::settings::pipelines::names::vxgi);
|
||||||
@ -243,17 +234,16 @@ namespace {
|
|||||||
});
|
});
|
||||||
shader.setDescriptorCounts({
|
shader.setDescriptorCounts({
|
||||||
{ "samplerTextures", maxTextures },
|
{ "samplerTextures", maxTextures },
|
||||||
{ "voxelDrawId", maxCascades },
|
{ "voxelId", maxCascades },
|
||||||
{ "voxelInstanceId", maxCascades },
|
{ "voxelNormal", maxCascades },
|
||||||
{ "voxelNormalX", maxCascades },
|
{ "voxelRadiance", maxCascades },
|
||||||
{ "voxelNormalY", maxCascades },
|
|
||||||
{ "voxelRadianceR", maxCascades },
|
|
||||||
{ "voxelRadianceG", maxCascades },
|
|
||||||
{ "voxelRadianceB", maxCascades },
|
|
||||||
{ "voxelRadianceA", maxCascades },
|
|
||||||
{ "voxelCount", maxCascades },
|
|
||||||
{ "voxelOutput", maxCascades },
|
{ "voxelOutput", maxCascades },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for ( auto& t : sceneTextures.voxels.id ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
|
for ( auto& t : sceneTextures.voxels.normal ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
|
for ( auto& t : sceneTextures.voxels.radiance ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
|
for ( auto& t : sceneTextures.voxels.output ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// baking pipeline
|
// baking pipeline
|
||||||
|
|||||||
@ -273,17 +273,17 @@ for ( auto& p : m.primitives ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
float r = 1.0f / (deltaTriUV[0].x * deltaTriUV[1].y - deltaTriUV[0].y * deltaTriUV[1].x);
|
float r = 1.0f / (deltaTriUV[0].x * deltaTriUV[1].y - deltaTriUV[0].y * deltaTriUV[1].x);
|
||||||
auto tangent_tri = (deltaTriPosition[0] * deltaTriUV[1].y - deltaTriPosition[1] * deltaTriUV[0].y) * r;
|
auto tangent_tri = (deltaTriPosition[0] * deltaTriUV[1].y - deltaTriPosition[1] * deltaTriUV[0].y) * r;
|
||||||
auto bitangent_tri = (deltaTriPosition[1] * deltaTriUV[0].x - deltaTriPosition[0] * deltaTriUV[1].x) * r;
|
auto bitangent_tri = (deltaTriPosition[1] * deltaTriUV[0].x - deltaTriPosition[0] * deltaTriUV[1].x) * r;
|
||||||
|
|
||||||
for ( auto i = 0; i < 3; ++i ) {
|
for ( auto i = 0; i < 3; ++i ) {
|
||||||
auto& normal = meshlet.vertices[indices[0]].normal;
|
auto& normal = meshlet.vertices[indices[0]].normal;
|
||||||
auto& tangent = meshlet.vertices[indices[0]].tangent;
|
auto& tangent = meshlet.vertices[indices[0]].tangent;
|
||||||
tangent = uf::vector::normalize(tangent_tri - normal * uf::vector::dot(normal, tangent_tri));
|
tangent = uf::vector::normalize(tangent_tri - normal * uf::vector::dot(normal, tangent_tri));
|
||||||
|
|
||||||
if (uf::vector::dot(uf::vector::cross(normal, tangent), bitangent_tri) < 0.0f)
|
if (uf::vector::dot(uf::vector::cross(normal, tangent), bitangent_tri) < 0.0f)
|
||||||
tangent = tangent * -1.0f;
|
tangent = tangent * -1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for ( size_t i = 0; i < meshlet.vertices.size() / 3; ++i ) {
|
for ( size_t i = 0; i < meshlet.vertices.size() / 3; ++i ) {
|
||||||
@ -313,17 +313,17 @@ for ( auto& p : m.primitives ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
float r = 1.0f / (deltaTriUV[0].x * deltaTriUV[1].y - deltaTriUV[0].y * deltaTriUV[1].x);
|
float r = 1.0f / (deltaTriUV[0].x * deltaTriUV[1].y - deltaTriUV[0].y * deltaTriUV[1].x);
|
||||||
auto tangent_tri = (deltaTriPosition[0] * deltaTriUV[1].y - deltaTriPosition[1] * deltaTriUV[0].y) * r;
|
auto tangent_tri = (deltaTriPosition[0] * deltaTriUV[1].y - deltaTriPosition[1] * deltaTriUV[0].y) * r;
|
||||||
auto bitangent_tri = (deltaTriPosition[1] * deltaTriUV[0].x - deltaTriPosition[0] * deltaTriUV[1].x) * r;
|
auto bitangent_tri = (deltaTriPosition[1] * deltaTriUV[0].x - deltaTriPosition[0] * deltaTriUV[1].x) * r;
|
||||||
|
|
||||||
for ( auto i = 0; i < 3; ++i ) {
|
for ( auto i = 0; i < 3; ++i ) {
|
||||||
auto& normal = meshlet.vertices[indices[0]].normal;
|
auto& normal = meshlet.vertices[indices[0]].normal;
|
||||||
auto& tangent = meshlet.vertices[indices[0]].tangent;
|
auto& tangent = meshlet.vertices[indices[0]].tangent;
|
||||||
tangent = uf::vector::normalize(tangent_tri - normal * uf::vector::dot(normal, tangent_tri));
|
tangent = uf::vector::normalize(tangent_tri - normal * uf::vector::dot(normal, tangent_tri));
|
||||||
|
|
||||||
if (uf::vector::dot(uf::vector::cross(normal, tangent), bitangent_tri) < 0.0f)
|
if (uf::vector::dot(uf::vector::cross(normal, tangent), bitangent_tri) < 0.0f)
|
||||||
tangent = tangent * -1.0f;
|
tangent = tangent * -1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -173,10 +173,12 @@ void ext::imgui::tick() {
|
|||||||
auto& renderMode = uf::renderer::getRenderMode("Gui", true);
|
auto& renderMode = uf::renderer::getRenderMode("Gui", true);
|
||||||
|
|
||||||
// check if rendermode changed
|
// check if rendermode changed
|
||||||
|
#if UF_USE_VULKAN
|
||||||
if ( ::boundRenderMode != &renderMode ) {
|
if ( ::boundRenderMode != &renderMode ) {
|
||||||
::shutdownRenderer();
|
::shutdownRenderer();
|
||||||
::initRenderer();
|
::initRenderer();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.DeltaTime = uf::physics::time::delta;
|
io.DeltaTime = uf::physics::time::delta;
|
||||||
|
|||||||
@ -19,6 +19,7 @@ namespace {
|
|||||||
struct Pair {
|
struct Pair {
|
||||||
bool aliased = false;
|
bool aliased = false;
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
size_t size = 0;
|
||||||
};
|
};
|
||||||
uf::stl::vector<void*> local;
|
uf::stl::vector<void*> local;
|
||||||
uf::stl::vector<void*> aliases;
|
uf::stl::vector<void*> aliases;
|
||||||
@ -105,7 +106,7 @@ void ext::opengl::Device::initialize() {
|
|||||||
#endif
|
#endif
|
||||||
#if UF_USE_OPENGL_FIXED_FUNCTION
|
#if UF_USE_OPENGL_FIXED_FUNCTION
|
||||||
{
|
{
|
||||||
::buffers::type.emplace_back(::buffers::Pair{.aliased = false, .index = 0});
|
::buffers::type.emplace_back(::buffers::Pair{.aliased = false, .index = 0, .size = 0});
|
||||||
::buffers::local.emplace_back((void*) NULL);
|
::buffers::local.emplace_back((void*) NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -172,7 +173,7 @@ GLuint ext::opengl::Device::createBuffer( enums::Buffer::type_t usage, GLsizeipt
|
|||||||
#else
|
#else
|
||||||
// CPU-based buffer
|
// CPU-based buffer
|
||||||
index = ::buffers::type.size();
|
index = ::buffers::type.size();
|
||||||
::buffers::type.emplace_back( ::buffers::Pair{.aliased = aliased, .index = index} );
|
::buffers::type.emplace_back( ::buffers::Pair{.aliased = aliased, .index = index, .size = size} );
|
||||||
|
|
||||||
if ( aliased ) {
|
if ( aliased ) {
|
||||||
::buffers::aliases.emplace_back( data );
|
::buffers::aliases.emplace_back( data );
|
||||||
@ -215,11 +216,11 @@ void ext::opengl::Device::destroyBuffer( GLuint& index ) {
|
|||||||
auto& buffer = ::buffers::local[type.index];
|
auto& buffer = ::buffers::local[type.index];
|
||||||
if ( buffer ) {
|
if ( buffer ) {
|
||||||
#if UF_MEMORYPOOL_INVALID_FREE
|
#if UF_MEMORYPOOL_INVALID_FREE
|
||||||
uf::memoryPool::global.free( buffer );
|
uf::memoryPool::global.free( buffer, type.size );
|
||||||
#else
|
#else
|
||||||
uf::MemoryPool* memoryPool = uf::memoryPool::global.size() > 0 ? &uf::memoryPool::global : NULL;
|
uf::MemoryPool* memoryPool = uf::memoryPool::global.size() > 0 ? &uf::memoryPool::global : NULL;
|
||||||
if ( memoryPool ) memoryPool->free( buffer );
|
if ( memoryPool ) memoryPool->free( buffer, type.size );
|
||||||
else free( buffer );
|
else free( buffer, type.size );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1226,13 +1226,13 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
|
|||||||
uf::stl::vector<VkAccelerationStructureBuildRangeInfoKHR> asBuildOffsetInfo;
|
uf::stl::vector<VkAccelerationStructureBuildRangeInfoKHR> asBuildOffsetInfo;
|
||||||
VkBuildAccelerationStructureFlagsKHR flags{};
|
VkBuildAccelerationStructureFlagsKHR flags{};
|
||||||
|
|
||||||
VkAccelerationStructureBuildGeometryInfoKHR buildInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
|
VkAccelerationStructureBuildGeometryInfoKHR buildInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
|
||||||
VkAccelerationStructureBuildSizesInfoKHR sizeInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR};
|
VkAccelerationStructureBuildSizesInfoKHR sizeInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR};
|
||||||
|
|
||||||
const VkAccelerationStructureBuildRangeInfoKHR* rangeInfo;
|
const VkAccelerationStructureBuildRangeInfoKHR* rangeInfo;
|
||||||
uf::renderer::AccelerationStructure as;
|
uf::renderer::AccelerationStructure as;
|
||||||
|
|
||||||
uf::renderer::AccelerationStructure previous;
|
uf::renderer::AccelerationStructure previous;
|
||||||
};
|
};
|
||||||
uf::stl::vector<BlasData> blasDatas;
|
uf::stl::vector<BlasData> blasDatas;
|
||||||
|
|
||||||
@ -1297,7 +1297,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
|
|||||||
triangles.indexData.deviceAddress = indexBufferAddress;
|
triangles.indexData.deviceAddress = indexBufferAddress;
|
||||||
|
|
||||||
VkAccelerationStructureBuildRangeInfoKHR& offset = blasData.asBuildOffsetInfo.emplace_back();
|
VkAccelerationStructureBuildRangeInfoKHR& offset = blasData.asBuildOffsetInfo.emplace_back();
|
||||||
offset.firstVertex = vertexInput.first;
|
offset.firstVertex = vertexInput.first;
|
||||||
offset.primitiveCount = vertexInput.count / 3;
|
offset.primitiveCount = vertexInput.count / 3;
|
||||||
offset.primitiveOffset = indexInput.first * indexInput.size;
|
offset.primitiveOffset = indexInput.first * indexInput.size;
|
||||||
offset.transformOffset = 0;
|
offset.transformOffset = 0;
|
||||||
@ -1334,7 +1334,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
|
|||||||
triangles.indexData.deviceAddress = indexBufferAddress;
|
triangles.indexData.deviceAddress = indexBufferAddress;
|
||||||
|
|
||||||
VkAccelerationStructureBuildRangeInfoKHR& offset = blasData.asBuildOffsetInfo.emplace_back();
|
VkAccelerationStructureBuildRangeInfoKHR& offset = blasData.asBuildOffsetInfo.emplace_back();
|
||||||
offset.firstVertex = vertexInput.first;
|
offset.firstVertex = vertexInput.first;
|
||||||
offset.primitiveCount = vertexInput.count / 3;
|
offset.primitiveCount = vertexInput.count / 3;
|
||||||
offset.primitiveOffset = indexInput.first * indexInput.size;
|
offset.primitiveOffset = indexInput.first * indexInput.size;
|
||||||
offset.transformOffset = 0;
|
offset.transformOffset = 0;
|
||||||
@ -1715,7 +1715,7 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
|
|||||||
buildInfo.dstAccelerationStructure = tlas.handle;
|
buildInfo.dstAccelerationStructure = tlas.handle;
|
||||||
buildInfo.scratchData.deviceAddress = scratchBuffer.getAddress();
|
buildInfo.scratchData.deviceAddress = scratchBuffer.getAddress();
|
||||||
|
|
||||||
VkAccelerationStructureBuildRangeInfoKHR buildOffsetInfo{countInstance, 0, 0, 0};
|
VkAccelerationStructureBuildRangeInfoKHR buildOffsetInfo{countInstance, 0, 0, 0};
|
||||||
const VkAccelerationStructureBuildRangeInfoKHR* rangeInfo = &buildOffsetInfo;
|
const VkAccelerationStructureBuildRangeInfoKHR* rangeInfo = &buildOffsetInfo;
|
||||||
|
|
||||||
auto commandBuffer = device.fetchCommandBuffer(uf::renderer::QueueEnum::COMPUTE);
|
auto commandBuffer = device.fetchCommandBuffer(uf::renderer::QueueEnum::COMPUTE);
|
||||||
|
|||||||
@ -329,15 +329,9 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
|
|||||||
shader.setDescriptorCounts({
|
shader.setDescriptorCounts({
|
||||||
{ "samplerTextures", maxTextures2D },
|
{ "samplerTextures", maxTextures2D },
|
||||||
{ "samplerCubemaps", maxTexturesCube },
|
{ "samplerCubemaps", maxTexturesCube },
|
||||||
{ "voxelDrawId", maxCascades },
|
{ "voxelId", maxCascades },
|
||||||
{ "voxelInstanceId", maxCascades },
|
{ "voxelNormal", maxCascades },
|
||||||
{ "voxelNormalX", maxCascades },
|
{ "voxelRadiance", maxCascades },
|
||||||
{ "voxelNormalY", maxCascades },
|
|
||||||
{ "voxelRadianceR", maxCascades },
|
|
||||||
{ "voxelRadianceG", maxCascades },
|
|
||||||
{ "voxelRadianceB", maxCascades },
|
|
||||||
{ "voxelRadianceA", maxCascades },
|
|
||||||
{ "voxelCount", maxCascades },
|
|
||||||
{ "voxelOutput", maxCascades },
|
{ "voxelOutput", maxCascades },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -316,6 +316,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
|||||||
{uf::io::resolveURI(fragmentShaderFilename), VK_SHADER_STAGE_FRAGMENT_BIT}
|
{uf::io::resolveURI(fragmentShaderFilename), VK_SHADER_STAGE_FRAGMENT_BIT}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( metadata.type == uf::renderer::settings::pipelines::names::vxgi ) {
|
if ( metadata.type == uf::renderer::settings::pipelines::names::vxgi ) {
|
||||||
auto& shader = blitter.material.getShader("compute");
|
auto& shader = blitter.material.getShader("compute");
|
||||||
|
|
||||||
@ -333,17 +334,21 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
|||||||
shader.setDescriptorCounts({
|
shader.setDescriptorCounts({
|
||||||
{ "samplerTextures", maxTextures2D },
|
{ "samplerTextures", maxTextures2D },
|
||||||
{ "samplerCubemaps", maxTexturesCube },
|
{ "samplerCubemaps", maxTexturesCube },
|
||||||
{ "voxelDrawId", maxCascades },
|
{ "voxelId", maxCascades },
|
||||||
{ "voxelInstanceId", maxCascades },
|
{ "voxelNormal", maxCascades },
|
||||||
{ "voxelNormalX", maxCascades },
|
{ "voxelRadiance", maxCascades },
|
||||||
{ "voxelNormalY", maxCascades },
|
|
||||||
{ "voxelRadianceR", maxCascades },
|
|
||||||
{ "voxelRadianceG", maxCascades },
|
|
||||||
{ "voxelRadianceB", maxCascades },
|
|
||||||
{ "voxelRadianceA", maxCascades },
|
|
||||||
{ "voxelCount", maxCascades },
|
|
||||||
{ "voxelOutput", maxCascades },
|
{ "voxelOutput", maxCascades },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
|
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
|
||||||
|
|
||||||
|
shader.textures.clear();
|
||||||
|
|
||||||
|
for ( auto& t : sceneTextures.voxels.id ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
|
for ( auto& t : sceneTextures.voxels.normal ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
|
for ( auto& t : sceneTextures.voxels.radiance ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
|
for ( auto& t : sceneTextures.voxels.output ) shader.textures.emplace_back().aliasTexture(t);
|
||||||
} else if ( metadata.type == uf::renderer::settings::pipelines::names::rt ) {
|
} else if ( metadata.type == uf::renderer::settings::pipelines::names::rt ) {
|
||||||
#if 0
|
#if 0
|
||||||
auto& shader = blitter.material.getShader("fragment");
|
auto& shader = blitter.material.getShader("fragment");
|
||||||
|
|||||||
@ -36,14 +36,14 @@ namespace {
|
|||||||
}
|
}
|
||||||
if ( image == VK_NULL_HANDLE ) continue;
|
if ( image == VK_NULL_HANDLE ) continue;
|
||||||
subresourceRange.baseMipLevel = 0;
|
subresourceRange.baseMipLevel = 0;
|
||||||
subresourceRange.levelCount = 1;
|
subresourceRange.levelCount = 1;
|
||||||
subresourceRange.aspectMask = descriptor.name == "depth" ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
subresourceRange.aspectMask = descriptor.name == "depth" ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
uf::renderer::Texture::setImageLayout( commandBuffer, image, layout, descriptor.layout, subresourceRange );
|
uf::renderer::Texture::setImageLayout( commandBuffer, image, layout, descriptor.layout, subresourceRange );
|
||||||
if ( mips > 1 ) {
|
if ( mips > 1 ) {
|
||||||
subresourceRange.baseMipLevel = 1;
|
subresourceRange.baseMipLevel = 1;
|
||||||
subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
uf::renderer::Texture::setImageLayout( commandBuffer, image, initialLayout, descriptor.layout, subresourceRange );
|
uf::renderer::Texture::setImageLayout( commandBuffer, image, initialLayout, descriptor.layout, subresourceRange );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void transitionAttachmentsFrom(
|
void transitionAttachmentsFrom(
|
||||||
@ -83,14 +83,14 @@ namespace {
|
|||||||
}
|
}
|
||||||
if ( image == VK_NULL_HANDLE ) continue;
|
if ( image == VK_NULL_HANDLE ) continue;
|
||||||
subresourceRange.baseMipLevel = 0;
|
subresourceRange.baseMipLevel = 0;
|
||||||
subresourceRange.levelCount = 1;
|
subresourceRange.levelCount = 1;
|
||||||
subresourceRange.aspectMask = descriptor.name == "depth" ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
subresourceRange.aspectMask = descriptor.name == "depth" ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
uf::renderer::Texture::setImageLayout( commandBuffer, image, descriptor.layout, layout, subresourceRange );
|
uf::renderer::Texture::setImageLayout( commandBuffer, image, descriptor.layout, layout, subresourceRange );
|
||||||
if ( mips > 1 ) {
|
if ( mips > 1 ) {
|
||||||
subresourceRange.baseMipLevel = 1;
|
subresourceRange.baseMipLevel = 1;
|
||||||
subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
|
||||||
uf::renderer::Texture::setImageLayout( commandBuffer, image, descriptor.layout, initialLayout, subresourceRange );
|
uf::renderer::Texture::setImageLayout( commandBuffer, image, descriptor.layout, initialLayout, subresourceRange );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -371,35 +371,39 @@ void ext::vulkan::Texture::loadFromFile(
|
|||||||
const uf::stl::string& filename,
|
const uf::stl::string& filename,
|
||||||
VkFormat format,
|
VkFormat format,
|
||||||
VkImageUsageFlags usage,
|
VkImageUsageFlags usage,
|
||||||
VkImageLayout layout
|
VkImageLayout layout,
|
||||||
|
VkImageCreateFlags flags
|
||||||
) {
|
) {
|
||||||
return loadFromFile( filename, ext::vulkan::device, format, usage, layout );
|
return loadFromFile( filename, ext::vulkan::device, format, usage, layout, flags );
|
||||||
}
|
}
|
||||||
void ext::vulkan::Texture::loadFromFile(
|
void ext::vulkan::Texture::loadFromFile(
|
||||||
const uf::stl::string& filename,
|
const uf::stl::string& filename,
|
||||||
Device& device,
|
Device& device,
|
||||||
VkFormat format,
|
VkFormat format,
|
||||||
VkImageUsageFlags usage,
|
VkImageUsageFlags usage,
|
||||||
VkImageLayout layout
|
VkImageLayout layout,
|
||||||
|
VkImageCreateFlags flags
|
||||||
) {
|
) {
|
||||||
uf::Image image;
|
uf::Image image;
|
||||||
image.open( filename );
|
image.open( filename );
|
||||||
return loadFromImage( image, device, format, usage, layout );
|
return loadFromImage( image, device, format, usage, layout, flags );
|
||||||
}
|
}
|
||||||
void ext::vulkan::Texture::loadFromImage(
|
void ext::vulkan::Texture::loadFromImage(
|
||||||
const uf::Image& image,
|
const uf::Image& image,
|
||||||
VkFormat format,
|
VkFormat format,
|
||||||
VkImageUsageFlags usage,
|
VkImageUsageFlags usage,
|
||||||
VkImageLayout layout
|
VkImageLayout layout,
|
||||||
|
VkImageCreateFlags flags
|
||||||
) {
|
) {
|
||||||
return loadFromImage( image, ext::vulkan::device, format, usage, layout );
|
return loadFromImage( image, ext::vulkan::device, format, usage, layout, flags );
|
||||||
}
|
}
|
||||||
void ext::vulkan::Texture::loadFromImage(
|
void ext::vulkan::Texture::loadFromImage(
|
||||||
const uf::Image& image,
|
const uf::Image& image,
|
||||||
Device& device,
|
Device& device,
|
||||||
VkFormat format,
|
VkFormat format,
|
||||||
VkImageUsageFlags usage,
|
VkImageUsageFlags usage,
|
||||||
VkImageLayout layout
|
VkImageLayout layout,
|
||||||
|
VkImageCreateFlags flags
|
||||||
) {
|
) {
|
||||||
/*
|
/*
|
||||||
switch ( format ) {
|
switch ( format ) {
|
||||||
@ -474,7 +478,8 @@ void ext::vulkan::Texture::loadFromImage(
|
|||||||
1,
|
1,
|
||||||
device,
|
device,
|
||||||
usage,
|
usage,
|
||||||
layout
|
layout,
|
||||||
|
flags
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,9 +492,10 @@ void ext::vulkan::Texture::fromBuffers(
|
|||||||
uint32_t texDepth,
|
uint32_t texDepth,
|
||||||
uint32_t layers,
|
uint32_t layers,
|
||||||
VkImageUsageFlags usage,
|
VkImageUsageFlags usage,
|
||||||
VkImageLayout layout
|
VkImageLayout layout,
|
||||||
|
VkImageCreateFlags flags
|
||||||
) {
|
) {
|
||||||
return this->fromBuffers( buffer, bufferSize, format, texWidth, texHeight, texDepth, layers, ext::vulkan::device, usage, layout );
|
return this->fromBuffers( buffer, bufferSize, format, texWidth, texHeight, texDepth, layers, ext::vulkan::device, usage, layout, flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -503,11 +509,13 @@ void ext::vulkan::Texture::fromBuffers(
|
|||||||
uint32_t layers,
|
uint32_t layers,
|
||||||
Device& device,
|
Device& device,
|
||||||
VkImageUsageFlags usage,
|
VkImageUsageFlags usage,
|
||||||
VkImageLayout layout
|
VkImageLayout layout,
|
||||||
|
VkImageCreateFlags flags
|
||||||
) {
|
) {
|
||||||
this->initialize(device, texWidth, texHeight, texDepth, layers);
|
this->initialize( device, texWidth, texHeight, texDepth, layers );
|
||||||
this->layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
this->usage = usage;
|
this->usage = usage;
|
||||||
|
this->layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
this->flags = flags;
|
||||||
|
|
||||||
if ( this->mips == 0 ) {
|
if ( this->mips == 0 ) {
|
||||||
this->mips = 1;
|
this->mips = 1;
|
||||||
@ -545,6 +553,7 @@ void ext::vulkan::Texture::fromBuffers(
|
|||||||
imageCreateInfo.initialLayout = this->layout;
|
imageCreateInfo.initialLayout = this->layout;
|
||||||
imageCreateInfo.extent = { width, height, depth };
|
imageCreateInfo.extent = { width, height, depth };
|
||||||
imageCreateInfo.usage = this->usage;
|
imageCreateInfo.usage = this->usage;
|
||||||
|
imageCreateInfo.flags = this->flags;
|
||||||
// Ensure that the TRANSFER_SRC bit is set for mip creation
|
// Ensure that the TRANSFER_SRC bit is set for mip creation
|
||||||
if ( this->mips > 1 && !(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT)) {
|
if ( this->mips > 1 && !(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT)) {
|
||||||
imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
@ -555,7 +564,7 @@ void ext::vulkan::Texture::fromBuffers(
|
|||||||
}
|
}
|
||||||
// Ensure cube maps get the compat flag bit
|
// Ensure cube maps get the compat flag bit
|
||||||
if ( this->viewType == ext::vulkan::enums::Image::VIEW_TYPE_CUBE || this->viewType == ext::vulkan::enums::Image::VIEW_TYPE_CUBE_ARRAY ) {
|
if ( this->viewType == ext::vulkan::enums::Image::VIEW_TYPE_CUBE || this->viewType == ext::vulkan::enums::Image::VIEW_TYPE_CUBE_ARRAY ) {
|
||||||
imageCreateInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
imageCreateInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
VmaAllocationCreateInfo allocInfo = {};
|
VmaAllocationCreateInfo allocInfo = {};
|
||||||
@ -955,8 +964,8 @@ void ext::vulkan::Texture::generateMipmaps( VkCommandBuffer commandBuffer, uint3
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (mipWidth > 1) mipWidth /= 2;
|
if (mipWidth > 1) mipWidth /= 2;
|
||||||
if (mipHeight > 1) mipHeight /= 2;
|
if (mipHeight > 1) mipHeight /= 2;
|
||||||
if (mipDepth > 1) mipDepth /= 2;
|
if (mipDepth > 1) mipDepth /= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#if UF_USE_XATLAS
|
#if UF_USE_XATLAS
|
||||||
#include <xatlas/xatlas.h>
|
#include <xatlas/xatlas.h>
|
||||||
|
|
||||||
#define UF_XATLAS_UNWRAP_MULTITHREAD 1 // prone to crashing
|
#define UF_XATLAS_UNWRAP_MULTITHREAD 1
|
||||||
|
|
||||||
size_t ext::xatlas::unwrap( pod::Graph& graph ) {
|
size_t ext::xatlas::unwrap( pod::Graph& graph ) {
|
||||||
struct Entry {
|
struct Entry {
|
||||||
@ -56,50 +56,49 @@ size_t ext::xatlas::unwrap( pod::Graph& graph ) {
|
|||||||
if ( !should ) continue;
|
if ( !should ) continue;
|
||||||
|
|
||||||
source = mesh;
|
source = mesh;
|
||||||
source.updateDescriptor();
|
source.updateDescriptor();
|
||||||
|
|
||||||
for ( size_t viewIdx = 0; viewIdx < source.buffer_views.size(); ++viewIdx ) {
|
for ( size_t viewIdx = 0; viewIdx < source.buffer_views.size(); ++viewIdx ) {
|
||||||
const auto& view = source.buffer_views[viewIdx];
|
const auto& view = source.buffer_views[viewIdx];
|
||||||
|
|
||||||
size_t atlasID = 0;
|
size_t atlasID = 0;
|
||||||
if ( view.indirectIndex != -1 ) {
|
if ( view.indirectIndex != -1 ) {
|
||||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer(mesh.indirect).data();
|
pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer(mesh.indirect).data();
|
||||||
atlasID = drawCommands[view.indirectIndex].auxID;
|
atlasID = drawCommands[view.indirectIndex].auxID;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& atlas = atlases[atlasID];
|
auto& atlas = atlases[atlasID];
|
||||||
auto& entry = atlas.entries.emplace_back();
|
auto& entry = atlas.entries.emplace_back();
|
||||||
entry.index = index;
|
entry.index = index;
|
||||||
entry.commandID = viewIdx;
|
entry.commandID = viewIdx;
|
||||||
|
|
||||||
auto& decl = entry.decl;
|
auto& decl = entry.decl;
|
||||||
auto posView = view["position"];
|
auto posView = view["position"];
|
||||||
auto uvView = view["uv"];
|
auto uvView = view["uv"];
|
||||||
auto idxView = view["index"];
|
auto idxView = view["index"];
|
||||||
|
|
||||||
UF_ASSERT( posView.valid() && uvView.valid() );
|
UF_ASSERT( posView.valid() && uvView.valid() );
|
||||||
|
|
||||||
decl.vertexCount = view.vertex.count;
|
decl.vertexCount = view.vertex.count;
|
||||||
decl.vertexPositionData = posView.data(view.vertex.first);
|
decl.vertexPositionData = posView.data(view.vertex.first);
|
||||||
decl.vertexPositionStride = posView.stride();
|
decl.vertexPositionStride = posView.stride();
|
||||||
decl.vertexUvData = uvView.data(view.vertex.first);
|
decl.vertexUvData = uvView.data(view.vertex.first);
|
||||||
decl.vertexUvStride = uvView.stride();
|
decl.vertexUvStride = uvView.stride();
|
||||||
|
|
||||||
if ( idxView.valid() ) {
|
if ( idxView.valid() ) {
|
||||||
decl.indexCount = view.index.count;
|
decl.indexCount = view.index.count;
|
||||||
// Pass view.index.first to offset the index pointer!
|
decl.indexData = idxView.data(view.index.first);
|
||||||
decl.indexData = idxView.data(view.index.first);
|
|
||||||
|
|
||||||
switch ( idxView.attribute.descriptor.size ) {
|
switch ( idxView.attribute.descriptor.size ) {
|
||||||
case 1: UF_EXCEPTION("xatlas does not support 8-bit indices"); break;
|
case 1: UF_EXCEPTION("xatlas does not support 8-bit indices"); break;
|
||||||
case 2: decl.indexFormat = ::xatlas::IndexFormat::UInt16; break;
|
case 2: decl.indexFormat = ::xatlas::IndexFormat::UInt16; break;
|
||||||
case 4: decl.indexFormat = ::xatlas::IndexFormat::UInt32; break;
|
case 4: decl.indexFormat = ::xatlas::IndexFormat::UInt32; break;
|
||||||
default: UF_EXCEPTION("unsupported index type"); break;
|
default: UF_EXCEPTION("unsupported index type"); break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
decl.indexCount = 0;
|
decl.indexCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::xatlas::ChartOptions chartOptions{};
|
::xatlas::ChartOptions chartOptions{};
|
||||||
@ -236,70 +235,63 @@ size_t ext::xatlas::unwrap( pod::Graph& graph ) {
|
|||||||
|
|
||||||
// update vertices
|
// update vertices
|
||||||
for ( auto& pair : atlases ) {
|
for ( auto& pair : atlases ) {
|
||||||
auto& atlas = pair.second;
|
auto& atlas = pair.second;
|
||||||
|
|
||||||
for ( auto i = 0; i < atlas.pointer->meshCount; i++ ) {
|
for ( auto i = 0; i < atlas.pointer->meshCount; i++ ) {
|
||||||
auto& xmesh = atlas.pointer->meshes[i];
|
auto& xmesh = atlas.pointer->meshes[i];
|
||||||
auto& entry = atlas.entries[i];
|
auto& entry = atlas.entries[i];
|
||||||
|
|
||||||
auto& name = graph.meshes[entry.index];
|
auto& name = graph.meshes[entry.index];
|
||||||
auto& mesh = storage.meshes[name];
|
auto& mesh = storage.meshes[name];
|
||||||
auto& source = sources[entry.index];
|
auto& source = sources[entry.index];
|
||||||
|
|
||||||
if ( source.vertex.count == 0 ) continue;
|
if ( source.vertex.count == 0 ) continue;
|
||||||
|
|
||||||
// Grab the read-only view from our unmodified source mesh
|
const auto& srcView = source.buffer_views[entry.commandID];
|
||||||
const auto& srcView = source.buffer_views[entry.commandID];
|
|
||||||
|
|
||||||
// We dynamically calculate the destination offsets using the updated draw commands
|
size_t dstVertexFirst = 0;
|
||||||
// Or if it's direct, it's just 0.
|
size_t dstIndexFirst = 0;
|
||||||
size_t dstVertexFirst = 0;
|
if ( mesh.indirect.count > 0 ) {
|
||||||
size_t dstIndexFirst = 0;
|
pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer(mesh.indirect).data();
|
||||||
if ( mesh.indirect.count > 0 ) {
|
dstVertexFirst = drawCommands[entry.commandID].vertexID;
|
||||||
pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer(mesh.indirect).data();
|
dstIndexFirst = drawCommands[entry.commandID].indexID;
|
||||||
dstVertexFirst = drawCommands[entry.commandID].vertexID;
|
}
|
||||||
dstIndexFirst = drawCommands[entry.commandID].indexID;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. Copy over the vertices based on the xref mapping
|
for ( auto j = 0; j < xmesh.vertexCount; ++j ) {
|
||||||
for ( auto j = 0; j < xmesh.vertexCount; ++j ) {
|
auto& vertex = xmesh.vertexArray[j];
|
||||||
auto& vertex = xmesh.vertexArray[j];
|
uint32_t ref = vertex.xref; // original vertex index relative to the sub-mesh
|
||||||
uint32_t ref = vertex.xref; // original vertex index relative to the sub-mesh
|
|
||||||
|
|
||||||
for ( auto attrIdx = 0; attrIdx < mesh.vertex.attributes.size(); ++attrIdx ) {
|
for ( auto attrIdx = 0; attrIdx < mesh.vertex.attributes.size(); ++attrIdx ) {
|
||||||
auto srcAttribute = srcView.vertex.attributes[attrIdx];
|
auto srcAttribute = srcView.vertex.attributes[attrIdx];
|
||||||
auto dstAttribute = mesh.vertex.attributes[attrIdx];
|
auto dstAttribute = mesh.vertex.attributes[attrIdx];
|
||||||
|
|
||||||
uint8_t* dstPtr = static_cast<uint8_t*>(dstAttribute.pointer) + dstAttribute.stride * (dstVertexFirst + j);
|
uint8_t* dstPtr = static_cast<uint8_t*>(dstAttribute.pointer) + dstAttribute.stride * (dstVertexFirst + j);
|
||||||
|
|
||||||
if ( dstAttribute.descriptor.name == "st" ) {
|
if ( dstAttribute.descriptor.name == "st" ) {
|
||||||
// Write new lightmap STs!
|
pod::Vector2f& st = *(pod::Vector2f*)dstPtr;
|
||||||
pod::Vector2f& st = *(pod::Vector2f*)dstPtr;
|
st = pod::Vector2f{ vertex.uv[0] / atlas.pointer->width, vertex.uv[1] / atlas.pointer->height };
|
||||||
st = pod::Vector2f{ vertex.uv[0] / atlas.pointer->width, vertex.uv[1] / atlas.pointer->height };
|
} else {
|
||||||
} else {
|
const uint8_t* srcPtr = static_cast<const uint8_t*>(srcAttribute.pointer) + srcAttribute.stride * (srcView.vertex.first + ref);
|
||||||
// Copy original vertex data
|
memcpy(dstPtr, srcPtr, srcAttribute.descriptor.size);
|
||||||
const uint8_t* srcPtr = static_cast<const uint8_t*>(srcAttribute.pointer) + srcAttribute.stride * (srcView.vertex.first + ref);
|
}
|
||||||
memcpy(dstPtr, srcPtr, srcAttribute.descriptor.size);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Write new indices
|
if ( mesh.index.count ) {
|
||||||
if ( mesh.index.count ) {
|
uf::Mesh::Attribute indexAttribute = mesh.index.attributes.front();
|
||||||
uf::Mesh::Attribute indexAttribute = mesh.index.attributes.front();
|
uint8_t* dstIndexPtr = static_cast<uint8_t*>(indexAttribute.pointer) + indexAttribute.stride * dstIndexFirst;
|
||||||
uint8_t* dstIndexPtr = static_cast<uint8_t*>(indexAttribute.pointer) + indexAttribute.stride * dstIndexFirst;
|
|
||||||
|
|
||||||
for ( auto idx = 0; idx < xmesh.indexCount; ++idx ) {
|
for ( auto idx = 0; idx < xmesh.indexCount; ++idx ) {
|
||||||
switch ( mesh.index.size ) {
|
switch ( mesh.index.size ) {
|
||||||
case 1: (( uint8_t*) dstIndexPtr)[idx] = (uint8_t) xmesh.indexArray[idx]; break;
|
case 1: (( uint8_t*) dstIndexPtr)[idx] = (uint8_t) xmesh.indexArray[idx]; break;
|
||||||
case 2: ((uint16_t*) dstIndexPtr)[idx] = (uint16_t) xmesh.indexArray[idx]; break;
|
case 2: ((uint16_t*) dstIndexPtr)[idx] = (uint16_t) xmesh.indexArray[idx]; break;
|
||||||
case 4: ((uint32_t*) dstIndexPtr)[idx] = (uint32_t) xmesh.indexArray[idx]; break;
|
case 4: ((uint32_t*) dstIndexPtr)[idx] = (uint32_t) xmesh.indexArray[idx]; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mesh.updateDescriptor();
|
mesh.updateDescriptor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
size_t atlasCount = 0;
|
size_t atlasCount = 0;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -57,10 +57,10 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LRESULT CALLBACK globalOnEvent(spec::win32::Window::handle_t handle, UINT message, WPARAM wParam, LPARAM lParam) {
|
LRESULT CALLBACK globalOnEvent(spec::win32::Window::handle_t handle, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||||
#if UF_USE_IMGUI
|
#if UF_USE_IMGUI
|
||||||
if (ImGui_ImplWin32_WndProcHandler(handle, message, wParam, lParam))
|
if (ImGui_ImplWin32_WndProcHandler(handle, message, wParam, lParam))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
if (message == WM_CREATE) {
|
if (message == WM_CREATE) {
|
||||||
LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams;
|
LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams;
|
||||||
SetWindowLongPtrW(handle, GWLP_USERDATA, window);
|
SetWindowLongPtrW(handle, GWLP_USERDATA, window);
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
size_t writeFunction(void *ptr, size_t size, size_t nmemb, uf::stl::string* data) {
|
size_t writeFunction(void *ptr, size_t size, size_t nmemb, uf::stl::string* data) {
|
||||||
data->append((char*) ptr, size * nmemb);
|
data->append((char*) ptr, size * nmemb);
|
||||||
return size * nmemb;
|
return size * nmemb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,5 +39,5 @@ uf::Http uf::http::get( const uf::stl::string& url ) {
|
|||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
curl = NULL;
|
curl = NULL;
|
||||||
#endif
|
#endif
|
||||||
return http;
|
return http;
|
||||||
}
|
}
|
||||||
@ -190,11 +190,11 @@ uf::stl::vector<uint8_t>& uf::io::readAsBuffer( uf::stl::vector<uint8_t>& buffer
|
|||||||
|
|
||||||
// Read each range
|
// Read each range
|
||||||
size_t currentOffset = 0;
|
size_t currentOffset = 0;
|
||||||
for (const auto& r : ranges) {
|
for (const auto& r : ranges) {
|
||||||
is.seekg(r.start, std::ios::beg);
|
is.seekg(r.start, std::ios::beg);
|
||||||
is.read(reinterpret_cast<char*>(buffer.data() + currentOffset), r.len);
|
is.read(reinterpret_cast<char*>(buffer.data() + currentOffset), r.len);
|
||||||
currentOffset += static_cast<size_t>(is.gcount());
|
currentOffset += static_cast<size_t>(is.gcount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uf::stl::string expected;
|
uf::stl::string expected;
|
||||||
|
|||||||
@ -3,18 +3,18 @@
|
|||||||
// credit: https://github.com/zeux/meshoptimizer/blob/master/src/quantization.cpp
|
// credit: https://github.com/zeux/meshoptimizer/blob/master/src/quantization.cpp
|
||||||
uint16_t UF_API uf::quant::quantize_f32u16( float v ) {
|
uint16_t UF_API uf::quant::quantize_f32u16( float v ) {
|
||||||
union { float f; uint32_t ui; } u = {v};
|
union { float f; uint32_t ui; } u = {v};
|
||||||
uint32_t ui = u.ui;
|
uint32_t ui = u.ui;
|
||||||
|
|
||||||
int s = (ui >> 16) & 0x8000;
|
int s = (ui >> 16) & 0x8000;
|
||||||
int em = ui & 0x7fffffff;
|
int em = ui & 0x7fffffff;
|
||||||
|
|
||||||
int h = (em - (112 << 23) + (1 << 12)) >> 13;
|
int h = (em - (112 << 23) + (1 << 12)) >> 13;
|
||||||
h = (em < (113 << 23)) ? 0 : h;
|
h = (em < (113 << 23)) ? 0 : h;
|
||||||
h = (em >= (143 << 23)) ? 0x7c00 : h;
|
h = (em >= (143 << 23)) ? 0x7c00 : h;
|
||||||
h = (em > (255 << 23)) ? 0x7e00 : h;
|
h = (em > (255 << 23)) ? 0x7e00 : h;
|
||||||
|
|
||||||
uint16_t res = (s | h);
|
uint16_t res = (s | h);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
float UF_API uf::quant::dequantize_u16f32( uint16_t h ) {
|
float UF_API uf::quant::dequantize_u16f32( uint16_t h ) {
|
||||||
uint32_t s = unsigned(h & 0x8000) << 16;
|
uint32_t s = unsigned(h & 0x8000) << 16;
|
||||||
|
|||||||
@ -10,78 +10,78 @@ static const int B64index[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|||||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 };
|
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 };
|
||||||
|
|
||||||
static const uint8_t base64_table[65] =
|
static const uint8_t base64_table[65] =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
uf::stl::string uf::base64::encode( const uint8_t* src, size_t len ) {
|
uf::stl::string uf::base64::encode( const uint8_t* src, size_t len ) {
|
||||||
uint8_t *out, *pos;
|
uint8_t *out, *pos;
|
||||||
const uint8_t *end, *in;
|
const uint8_t *end, *in;
|
||||||
|
|
||||||
size_t olen;
|
size_t olen;
|
||||||
|
|
||||||
olen = 4*((len + 2) / 3);
|
olen = 4*((len + 2) / 3);
|
||||||
|
|
||||||
if (olen < len)
|
if (olen < len)
|
||||||
return uf::stl::string();
|
return uf::stl::string();
|
||||||
|
|
||||||
uf::stl::string outStr;
|
uf::stl::string outStr;
|
||||||
outStr.resize(olen);
|
outStr.resize(olen);
|
||||||
out = (uint8_t*)&outStr[0];
|
out = (uint8_t*)&outStr[0];
|
||||||
|
|
||||||
end = src + len;
|
end = src + len;
|
||||||
in = src;
|
in = src;
|
||||||
pos = out;
|
pos = out;
|
||||||
while (end - in >= 3) {
|
while (end - in >= 3) {
|
||||||
*pos++ = base64_table[in[0] >> 2];
|
*pos++ = base64_table[in[0] >> 2];
|
||||||
*pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
|
*pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
|
||||||
*pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
|
*pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
|
||||||
*pos++ = base64_table[in[2] & 0x3f];
|
*pos++ = base64_table[in[2] & 0x3f];
|
||||||
in += 3;
|
in += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end - in) {
|
if (end - in) {
|
||||||
*pos++ = base64_table[in[0] >> 2];
|
*pos++ = base64_table[in[0] >> 2];
|
||||||
if (end - in == 1) {
|
if (end - in == 1) {
|
||||||
*pos++ = base64_table[(in[0] & 0x03) << 4];
|
*pos++ = base64_table[(in[0] & 0x03) << 4];
|
||||||
*pos++ = '=';
|
*pos++ = '=';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*pos++ = base64_table[((in[0] & 0x03) << 4) |
|
*pos++ = base64_table[((in[0] & 0x03) << 4) |
|
||||||
(in[1] >> 4)];
|
(in[1] >> 4)];
|
||||||
*pos++ = base64_table[(in[1] & 0x0f) << 2];
|
*pos++ = base64_table[(in[1] & 0x0f) << 2];
|
||||||
}
|
}
|
||||||
*pos++ = '=';
|
*pos++ = '=';
|
||||||
}
|
}
|
||||||
|
|
||||||
return outStr;
|
return outStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// uf::stl::vector<uint8_t> uf::base64::decode( const uint8_t* data, size_t len ) {
|
// uf::stl::vector<uint8_t> uf::base64::decode( const uint8_t* data, size_t len ) {
|
||||||
uf::stl::vector<uint8_t> uf::base64::decode( const uf::stl::string& data ) {
|
uf::stl::vector<uint8_t> uf::base64::decode( const uf::stl::string& data ) {
|
||||||
size_t len = data.size();
|
size_t len = data.size();
|
||||||
uint8_t* p = (uint8_t*) &data[0];
|
uint8_t* p = (uint8_t*) &data[0];
|
||||||
int pad = len > 0 && (len % 4 || p[len - 1] == '=');
|
int pad = len > 0 && (len % 4 || p[len - 1] == '=');
|
||||||
const size_t L = ((len + 3) / 4 - pad) * 4;
|
const size_t L = ((len + 3) / 4 - pad) * 4;
|
||||||
uf::stl::vector<uint8_t> str(L / 4 * 3 + pad, '\0');
|
uf::stl::vector<uint8_t> str(L / 4 * 3 + pad, '\0');
|
||||||
|
|
||||||
for (size_t i = 0, j = 0; i < L; i += 4)
|
for (size_t i = 0, j = 0; i < L; i += 4)
|
||||||
{
|
{
|
||||||
int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
|
int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
|
||||||
str[j++] = n >> 16;
|
str[j++] = n >> 16;
|
||||||
str[j++] = n >> 8 & 0xFF;
|
str[j++] = n >> 8 & 0xFF;
|
||||||
str[j++] = n & 0xFF;
|
str[j++] = n & 0xFF;
|
||||||
}
|
}
|
||||||
if (pad)
|
if (pad)
|
||||||
{
|
{
|
||||||
int n = B64index[p[L]] << 18 | B64index[p[L + 1]] << 12;
|
int n = B64index[p[L]] << 18 | B64index[p[L + 1]] << 12;
|
||||||
str[str.size() - 1] = n >> 16;
|
str[str.size() - 1] = n >> 16;
|
||||||
|
|
||||||
if (len > L + 2 && p[L + 2] != '=')
|
if (len > L + 2 && p[L + 2] != '=')
|
||||||
{
|
{
|
||||||
n |= B64index[p[L + 2]] << 6;
|
n |= B64index[p[L + 2]] << 6;
|
||||||
str.push_back(n >> 8 & 0xFF);
|
str.push_back(n >> 8 & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
uf::stl::string uf::string::base64::encode( const uf::stl::string& input ) {
|
uf::stl::string uf::string::base64::encode( const uf::stl::string& input ) {
|
||||||
@ -95,9 +95,9 @@ uf::stl::string uf::string::base64::decode( const uf::stl::string& input ) {
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
static const uf::stl::string base64_chars =
|
static const uf::stl::string base64_chars =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
"abcdefghijklmnopqrstuvwxyz"
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
"0123456789+/";
|
"0123456789+/";
|
||||||
|
|
||||||
|
|
||||||
static inline bool is_base64(uint8_t c) {
|
static inline bool is_base64(uint8_t c) {
|
||||||
@ -112,34 +112,34 @@ uf::stl::string uf::base64::encode(const uint8_t* buf, std::size_t bufLen) {
|
|||||||
uint8_t char_array_4[4];
|
uint8_t char_array_4[4];
|
||||||
|
|
||||||
while (bufLen--) {
|
while (bufLen--) {
|
||||||
char_array_3[i++] = *(buf++);
|
char_array_3[i++] = *(buf++);
|
||||||
if (i == 3) {
|
if (i == 3) {
|
||||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
for(i = 0; (i <4) ; i++)
|
for(i = 0; (i <4) ; i++)
|
||||||
ret += base64_chars[char_array_4[i]];
|
ret += base64_chars[char_array_4[i]];
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i)
|
if (i)
|
||||||
{
|
{
|
||||||
for(j = i; j < 3; j++)
|
for(j = i; j < 3; j++)
|
||||||
char_array_3[j] = '\0';
|
char_array_3[j] = '\0';
|
||||||
|
|
||||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
for (j = 0; (j < i + 1); j++)
|
for (j = 0; (j < i + 1); j++)
|
||||||
ret += base64_chars[char_array_4[j]];
|
ret += base64_chars[char_array_4[j]];
|
||||||
|
|
||||||
while((i++ < 3))
|
while((i++ < 3))
|
||||||
ret += '=';
|
ret += '=';
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -154,33 +154,33 @@ uf::stl::vector<uint8_t> uf::base64::decode(const uf::stl::string& encoded_strin
|
|||||||
uf::stl::vector<uint8_t> ret;
|
uf::stl::vector<uint8_t> ret;
|
||||||
|
|
||||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||||
if (i ==4) {
|
if (i ==4) {
|
||||||
for (i = 0; i <4; i++)
|
for (i = 0; i <4; i++)
|
||||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||||
|
|
||||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
for (i = 0; (i < 3); i++)
|
for (i = 0; (i < 3); i++)
|
||||||
ret.push_back(char_array_3[i]);
|
ret.push_back(char_array_3[i]);
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i) {
|
if (i) {
|
||||||
for (j = i; j <4; j++)
|
for (j = i; j <4; j++)
|
||||||
char_array_4[j] = 0;
|
char_array_4[j] = 0;
|
||||||
|
|
||||||
for (j = 0; j <4; j++)
|
for (j = 0; j <4; j++)
|
||||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||||
|
|
||||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]);
|
for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@ -9,10 +9,10 @@ namespace {
|
|||||||
|
|
||||||
int status = -4;
|
int status = -4;
|
||||||
std::unique_ptr<char, void(*)(void*)> demangled{
|
std::unique_ptr<char, void(*)(void*)> demangled{
|
||||||
abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status),
|
abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status),
|
||||||
std::free
|
std::free
|
||||||
};
|
};
|
||||||
return ( status == 0 ) ? demangled.get() : mangled;
|
return ( status == 0 ) ? demangled.get() : mangled;
|
||||||
/*
|
/*
|
||||||
int status;
|
int status;
|
||||||
char* pointer = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
|
char* pointer = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user