Commit for 2021.05.05.7z

This commit is contained in:
mrq 2021-05-05 00:00:00 -05:00
parent e34f03c3d0
commit 0c325bb492
10 changed files with 260 additions and 115 deletions

View File

@ -4,10 +4,6 @@
#define MULTISAMPLING 1
#define DEFERRED_SAMPLING 1
#define VXGI_NDC 1
#define VXGI_SHADOWS 0
#define VXGI_CASCADES 1
#define FOG 1
#define FOG_RAY_MARCH 1
@ -58,6 +54,8 @@ struct Matrices {
struct Ray {
vec3 origin;
vec3 direction;
vec3 position;
float distance;
};
@ -165,6 +163,14 @@ struct Surface {
vec4 fragment;
} surface;
struct Voxel {
uvec2 id;
vec3 position;
vec3 normal;
vec2 uv;
vec4 color;
};
#if !MULTISAMPLING
layout (input_attachment_index = 0, binding = 0) uniform usubpassInput samplerId;
layout (input_attachment_index = 1, binding = 1) uniform subpassInput samplerNormal;
@ -331,7 +337,7 @@ void fog( in Ray ray, inout vec3 i, float scale ) {
i.rgb = mix(ubo.fog.color.rgb, i.rgb, transmittance);
}
#endif
#if 0
const vec3 color = ubo.fog.color.rgb;
const float inner = ubo.fog.range.x;
const float outer = ubo.fog.range.y * scale;
@ -339,6 +345,7 @@ void fog( in Ray ray, inout vec3 i, float scale ) {
const float factor = clamp( (distance - inner) / (outer - inner), 0.0, 1.0 );
i.rgb = mix(i.rgb, color, factor);
#endif
}
vec3 decodeNormals( vec2 enc ) {
@ -544,6 +551,7 @@ void main() {
} else {
surface.fragment.rgb += surface.material.albedo.rgb * ubo.ambient.rgb * surface.material.occlusion;
}
// corrections
surface.material.roughness *= 4.0;

View File

@ -4,7 +4,7 @@
#define MULTISAMPLING 1
#define DEFERRED_SAMPLING 1
#define VXGI_NDC 0
#define VXGI_NDC 1
#define VXGI_SHADOWS 1
#define FOG 1
@ -42,8 +42,9 @@ const vec2 poissonDisk[16] = vec2[](
vec2( 0.14383161, -0.14100790 )
);
layout (constant_id = 0) const uint TEXTURES = 256;
layout (constant_id = 1) const uint CASCADES = 1;
#define MAX_CASCADES 4
layout (constant_id = 0) const uint CASCADES = MAX_CASCADES;
layout (constant_id = 1) const uint TEXTURES = 256;
struct Matrices {
mat4 view[2];
@ -346,7 +347,7 @@ void fog( in Ray ray, inout vec3 i, float scale ) {
i.rgb = mix(ubo.fog.color.rgb, i.rgb, transmittance);
}
#endif
#if 0
const vec3 color = ubo.fog.color.rgb;
const float inner = ubo.fog.range.x;
const float outer = ubo.fog.range.y * scale;
@ -354,6 +355,7 @@ void fog( in Ray ray, inout vec3 i, float scale ) {
const float factor = clamp( (distance - inner) / (outer - inner), 0.0, 1.0 );
i.rgb = mix(i.rgb, color, factor);
#endif
}
vec3 decodeNormals( vec2 enc ) {
@ -450,17 +452,12 @@ vec4 postProcess() {
return vec4(surface.fragment.rgb,1);
}
Voxel getVoxel( vec3 P ) {
const vec3 uvw = vec3( ubo.matrices.vxgi * vec4( P, 1.0f ) ) * 0.5f + 0.5f;
Voxel voxel;
voxel.id = uvec2(texture(voxelId[0], uvw).xy);
voxel.position = P;
voxel.normal = decodeNormals( texture(voxelNormal[0], uvw).xy );
voxel.uv = texture(voxelUv[0], uvw).xy;
voxel.color = texture(voxelRadiance[0], uvw).rgba;
return voxel;
uint BIASED_ROUND( float x ) {
return uint( x < 255.0 / 256.0 ? floor(x) : ceil(x));
}
#define CASCADE_POWER 2
uint SCALE_CASCADE( uint x ) {
return uint(pow(1 + x, CASCADE_POWER));
}
struct VoxelInfo {
@ -476,24 +473,36 @@ struct VoxelInfo {
} voxelInfo;
vec4 voxelTrace( inout Ray ray, float aperture, float maxDistance ) {
uint CASCADE = 1;
#if VXGI_NDC
ray.origin = vec3( ubo.matrices.vxgi * vec4( ray.origin, 1.0 ) );
ray.direction = vec3( ubo.matrices.vxgi * vec4( ray.direction, 0.0 ) );
const float granularity = 1.0f / 16.0f;
const uint maxSteps = uint(voxelInfo.radianceSize * 2);
const float granularity = 1.0f / 32.0f;
const uint maxSteps = uint(voxelInfo.radianceSize * 2 * CASCADES);
CASCADE = BIASED_ROUND(clamp( max( max( abs(ray.origin.x), abs(ray.origin.y) ), abs(ray.origin.z) ), 0, CASCADES - 1 ));
#else
const float granularity = 10.0f;
const uint maxSteps = uint(voxelInfo.radianceSize * granularity);
const float granularity = 16.0f;
const uint maxSteps = uint(voxelInfo.radianceSize * granularity * CASCADES);
{
vec3 uvw = vec3( ubo.matrices.vxgi * vec4( ray.origin, 1.0 ) );
CASCADE = BIASED_ROUND(clamp( max( max( abs(uvw.x), abs(uvw.y) ), abs(uvw.z) ), 0, CASCADES - 1 ));
}
#endif
const float granularityRecip = 1.0f / granularity;
// box
const vec2 rayBoxInfo = rayBoxDst( voxelInfo.min, voxelInfo.max, ray );
const float tStart = rayBoxInfo.x;
const float tEnd = maxDistance > 0 ? min(maxDistance, rayBoxInfo.y) : rayBoxInfo.y;
const vec2 rayBoxInfoA = rayBoxDst( voxelInfo.min * SCALE_CASCADE(CASCADE), voxelInfo.max * SCALE_CASCADE(CASCADE), ray );
const vec2 rayBoxInfoB = rayBoxDst( voxelInfo.min * SCALE_CASCADE(CASCADES), voxelInfo.max * SCALE_CASCADE(CASCADES), ray );
const float tStart = rayBoxInfoA.x;
const float tEnd = maxDistance > 0 ? min(maxDistance, rayBoxInfoB.y * SCALE_CASCADE(CASCADES)) : rayBoxInfoB.y * SCALE_CASCADE(CASCADES);
// steps
const float tDelta = voxelInfo.voxelSize * granularityRecip;
// marcher
#if VXGI_NDC
ray.distance = tStart + tDelta * granularityRecip * 0.25;
#else
ray.distance = tStart + tDelta * granularity;
#endif
ray.position = vec3(0);
vec4 radiance = vec4(0);
vec3 uvw = vec3(0);
@ -505,22 +514,76 @@ vec4 voxelTrace( inout Ray ray, float aperture, float maxDistance ) {
vec4 color = vec4(0);
float occlusion = 0.0;
uint stepCounter = 0;
const float falloff = 32.0f; // maxDistance > 0.0 ? 0.0f : 256.0f;
const vec3 voxelBoundsRecip = 1.0f / (voxelInfo.max - voxelInfo.min);
// while ( ray.distance < tEnd && color.a < 1.0 && occlusion < 1.0 && stepCounter++ < maxSteps ) {
while ( ray.distance < tEnd && color.a < 1.0 && occlusion < 1.0 ) {
const float falloff = 128.0f; // maxDistance > 0.0 ? 0.0f : 256.0f;
const vec3 voxelBounds = voxelInfo.max - voxelInfo.min;
const vec3 voxelBoundsRecip = 1.0f / voxelBounds;
#if VXGI_NDC
while ( ray.distance < tEnd && color.a < 1.0 && occlusion < 1.0 && stepCounter++ < maxSteps ) {
#else
while ( color.a < 1.0 && stepCounter++ < maxSteps ) {
#endif
ray.distance += tDelta * (aperture > 0 ? coneDiameter : 1);
ray.position = ray.origin + ray.direction * ray.distance;
#if VXGI_NDC
uvw = ray.position * 0.5 + 0.5;
uvw = ray.position;
#else
uvw = (ray.position - voxelInfo.min) * voxelBoundsRecip;
uvw = vec3( ubo.matrices.vxgi * vec4( ray.position, 1.0 ) );
#endif
if ( abs(uvw.x) > 1.0 || abs(uvw.y) > 1.0 || abs(uvw.z) > 1.0 ) break;
CASCADE = BIASED_ROUND(clamp( max( max( abs(uvw.x), abs(uvw.y) ), abs(uvw.z) ), 0, CASCADES - 1 ));
uvw = (uvw / SCALE_CASCADE(CASCADE)) * 0.5 + 0.5;
if ( CASCADE >= CASCADES || uvw.x < 0.0 || uvw.y < 0.0 || uvw.z < 0.0 || uvw.x >= 1.0 || uvw.y >= 1.0 || uvw.z >= 1.0 ) break;
coneDiameter = coneCoefficient * ray.distance;
level = log2( coneDiameter );
level = aperture > 0 ? log2( coneDiameter ) : 0;
if ( level >= voxelInfo.mipmapLevels ) break;
radiance = textureLod(voxelRadiance[0], uvw.xzy, level);
// radiance = textureLod(voxelRadiance[CASCADE], uvw.xzy, level);
#define C 0
#if C < MAX_CASCADES
if ( CASCADE == C && C < CASCADES ) radiance = textureLod(voxelRadiance[C], uvw.xzy, level);
#endif
#undef C
#define C 1
#if C < MAX_CASCADES
if ( CASCADE == C && C < CASCADES ) radiance = textureLod(voxelRadiance[C], uvw.xzy, level);
#endif
#undef C
#define C 2
#if C < MAX_CASCADES
if ( CASCADE == C && C < CASCADES ) radiance = textureLod(voxelRadiance[C], uvw.xzy, level);
#endif
#undef C
#define C 3
#if C < MAX_CASCADES
if ( CASCADE == C && C < CASCADES ) radiance = textureLod(voxelRadiance[C], uvw.xzy, level);
#endif
#undef C
#define C 4
#if C < MAX_CASCADES
if ( CASCADE == C && C < CASCADES ) radiance = textureLod(voxelRadiance[C], uvw.xzy, level);
#endif
#undef C
#define C 5
#if C < MAX_CASCADES
if ( CASCADE == C && C < CASCADES ) radiance = textureLod(voxelRadiance[C], uvw.xzy, level);
#endif
#undef C
#define C 6
#if C < MAX_CASCADES
if ( CASCADE == C && C < CASCADES ) radiance = textureLod(voxelRadiance[C], uvw.xzy, level);
#endif
#undef C
#define C 7
#if C < MAX_CASCADES
if ( CASCADE == C && C < CASCADES ) radiance = textureLod(voxelRadiance[C], uvw.xzy, level);
#endif
#undef C
// else radiance = textureLod(voxelRadiance[CASCADE], uvw.xzy, level);
color += (1.0 - color.a) * radiance;
occlusion += ((1.0f - occlusion) * radiance.a) / (1.0f + falloff * coneDiameter);
@ -543,7 +606,11 @@ float shadowFactor( const Light light, float def ) {
Ray ray;
ray.origin = surface.position.world;
ray.direction = normalize( light.position - surface.position.world );
#if VXGI_NDC
// ray.origin -= ray.direction * 0.125;
#else
ray.origin -= ray.direction * 0.5;
#endif
float z = distance( surface.position.world, light.position ) - DEPTH_BIAS;
return 1.0 - voxelTrace( ray, SHADOW_APERTURE, z ).a;
}
@ -562,7 +629,7 @@ void main() {
surface.position.eye = positionEye.xyz;
surface.position.world = vec3( ubo.matrices.iView[inPushConstantPass] * positionEye );
}
#if 0
#if 1
{
const vec4 near4 = ubo.matrices.iProjectionView[inPushConstantPass] * (vec4(2.0 * inUv - 1.0, -1.0, 1.0));
const vec4 far4 = ubo.matrices.iProjectionView[inPushConstantPass] * (vec4(2.0 * inUv - 1.0, 1.0, 1.0));
@ -720,12 +787,12 @@ void main() {
}
// outFragColor.rgb = voxelConeTrace( surface.ray, 0 ).rgb; return;
Ray ray;
if ( DIFFUSE_INDIRECT_FACTOR > 0.0f ) {
for ( uint i = 0; i < CONES_COUNT; ++i ) {
float weight = i == 0 ? PI * 0.25f : PI * 0.15f;
ray.origin = P;
Ray ray;
ray.direction = CONES[i].xyz;
ray.origin = P; // + ray.direction;
indirectDiffuse += voxelConeTrace( ray, DIFFUSE_CONE_APERTURE ) * weight;
}
surface.material.occlusion = 1.0 - clamp(indirectDiffuse.a, 0.0, 1.0);
@ -733,16 +800,11 @@ void main() {
// outFragColor.rgb = vec3(surface.material.occlusion); return;
}
if ( SPECULAR_INDIRECT_FACTOR > 0.0f ) {
ray.origin = P;
Ray ray;
ray.direction = reflect( normalize(P - surface.ray.origin), N );
ray.origin = P; // + ray.direction;
indirectSpecular = voxelConeTrace( ray, SPECULAR_CONE_APERTURE );
// outFragColor.rgb = indirectSpecular.rgb; return;
/*
if ( indirectSpecular.a < 1.0 ) {
vec4 radiance = texture( samplerSkybox, ray.direction ) * 0.25;
indirectSpecular += (1.0 - indirectSpecular.a) * radiance;
}
*/
}
surface.material.indirect = indirectDiffuse * DIFFUSE_INDIRECT_FACTOR + indirectSpecular * SPECULAR_INDIRECT_FACTOR;
// outFragColor.rgb = surface.material.indirect.rgb; return;

View File

@ -14,8 +14,8 @@ const float EPSILON = 0.00001;
const float LIGHT_POWER_CUTOFF = 0.005;
layout (constant_id = 0) const uint TEXTURES = 256;
layout (constant_id = 1) const uint CASCADES = 1;
layout (constant_id = 0) const uint CASCADES = 4;
layout (constant_id = 1) const uint TEXTURES = 256;
struct Matrices {
mat4 view[2];
@ -280,13 +280,18 @@ float shadowFactor( const Light light, float def ) {
#endif
}
#define CASCADE_POWER 2
uint SCALE_CASCADE( uint x ) {
return uint(pow(1 + x, CASCADE_POWER));
}
void main() {
const vec3 tUvw = gl_GlobalInvocationID.xzy;
for ( uint CASCADE = 0; CASCADE < CASCADES; ++CASCADE ) {
surface.normal.world = decodeNormals( vec2(imageLoad(voxelNormal[CASCADE], ivec3(tUvw) ).xy) );
surface.normal.eye = vec3( ubo.matrices.vxgi * vec4( surface.normal.world, 0.0f ) );
surface.position.eye = vec3(gl_GlobalInvocationID.xyz) / (vec3(imageSize(voxelRadiance[CASCADE])) / (CASCADE + 1)) * 2.0f - 1.0f;
surface.position.eye = (vec3(gl_GlobalInvocationID.xyz) / vec3(imageSize(voxelRadiance[CASCADE])) * 2.0f - 1.0f) * SCALE_CASCADE(CASCADE);
surface.position.world = vec3( inverse(ubo.matrices.vxgi) * vec4( surface.position.eye, 1.0f ) );
const uvec2 ID = uvec2(imageLoad(voxelId[CASCADE], ivec3(tUvw) ).xy);

View File

@ -5,8 +5,8 @@
#define PI 3.1415926536f
layout (constant_id = 0) const uint TEXTURES = 1;
layout (constant_id = 1) const uint CASCADES = 1;
layout (constant_id = 0) const uint CASCADES = 4;
layout (constant_id = 1) const uint TEXTURES = 256;
struct Material {
vec4 colorBase;
@ -86,9 +86,10 @@ bool validTextureIndex( int textureIndex ) {
}
void main() {
const vec3 P = inPosition.xzy;
const uint CASCADE = uint(max( abs(floor(P.x)), max( abs(floor(P.y)), abs(floor(P.z)) ) ));
const uint CASCADE = inId.z;
if ( CASCADES <= CASCADE ) discard;
const vec3 P = inPosition.xzy * 0.5 + 0.5;
if ( abs(P.x) > 1 || abs(P.y) > 1 || abs(P.z) > 1 ) discard;
vec4 A = vec4(0, 0, 0, 0);
const vec3 N = inNormal;
@ -139,8 +140,8 @@ void main() {
const vec2 outNormals = encodeNormals( normalize( N ) );
const vec2 outUvs = wrap(inUv.xy);
imageStore(voxelId[CASCADE], ivec3(P * (1 + CASCADE) * imageSize(voxelId[CASCADE])), uvec4(outId, 0, 0));
imageStore(voxelNormal[CASCADE], ivec3(P * (1 + CASCADE) * imageSize(voxelNormal[CASCADE])), vec4(outNormals, 0, 0));
imageStore(voxelUv[CASCADE], ivec3(P * (1 + CASCADE) * imageSize(voxelUv[CASCADE])), vec4(outUvs, 0, 0));
imageStore(voxelRadiance[CASCADE], ivec3(P * (1 + CASCADE) * imageSize(voxelRadiance[CASCADE])), outAlbedo);
imageStore(voxelId[CASCADE], ivec3(P * imageSize(voxelId[CASCADE])), uvec4(outId, 0, 0));
imageStore(voxelNormal[CASCADE], ivec3(P * imageSize(voxelNormal[CASCADE])), vec4(outNormals, 0, 0));
imageStore(voxelUv[CASCADE], ivec3(P * imageSize(voxelUv[CASCADE])), vec4(outUvs, 0, 0));
imageStore(voxelRadiance[CASCADE], ivec3(P * imageSize(voxelRadiance[CASCADE])), outAlbedo);
}

View File

@ -23,6 +23,11 @@ layout (binding = 6) uniform UBO {
mat4 voxel;
} ubo;
#define CASCADE_POWER 2
uint SCALE_CASCADE( uint x ) {
return uint(pow(1 + x, CASCADE_POWER));
}
void main(){
const float RENDER_RESOLUTION = 256.0;
const float PIXEL_SCALE = 2.0;
@ -36,17 +41,27 @@ void main(){
uint A = N.y > N.x ? 1 : 0;
A = N.z > N[A] ? 2 : A;
#endif
for(uint i = 0; i < 3; ++i){
const uint CASCADE = inId[0].z;
vec3 P[3] = {
vec3( ubo.voxel * vec4( inPosition[0], 1 ) ) / SCALE_CASCADE(CASCADE),
vec3( ubo.voxel * vec4( inPosition[1], 1 ) ) / SCALE_CASCADE(CASCADE),
vec3( ubo.voxel * vec4( inPosition[2], 1 ) ) / SCALE_CASCADE(CASCADE),
};
for( uint i = 0; i < 3; ++i ){
const vec3 D = normalize( inPosition[i] - C ) * HALF_PIXEL;
outUv = inUv[i];
outSt = inSt[i];
outColor = inColor[i];
outNormal = inNormal[i];
outTBN = inTBN[i];
outPosition = vec3( ubo.voxel * vec4( inPosition[i], 1 ) ) + normalize( inPosition[i] - C ) * HALF_PIXEL;
outPosition = P[i]; // + D;
outId = inId[i];
const vec3 P = fract(outPosition);
// const vec3 P = fract(outPosition + normalize( inPosition[i] - C ) * HALF_PIXEL);
const vec3 P = outPosition + D;
#if USE_CROSS
if ( N.z > N.x && N.z > N.y ) gl_Position = vec4(P.x, P.y, 0, 1);
else if ( N.x > N.y && N.x > N.z ) gl_Position = vec4(P.y, P.z, 0, 1);
@ -56,10 +71,6 @@ void main(){
else if ( A == 1 ) gl_Position = vec4(P.xz, 1, 1 );
else if ( A == 2 ) gl_Position = vec4(P.xy, 1, 1 );
#endif
outPosition = outPosition * 0.5 + 0.5;
EmitVertex();
}
EndPrimitive();

View File

@ -93,8 +93,8 @@ namespace {
{
auto& shader = graphic.material.getShader("fragment", "vxgi");
struct SpecializationConstant {
uint32_t cascades = 4;
uint32_t textures = 256;
uint32_t cascades = 2;
};
auto& specializationConstants = shader.specializationConstants.get<SpecializationConstant>();
specializationConstants.textures = texture2Ds;

View File

@ -213,32 +213,31 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
auto& scene = uf::scene::getCurrentScene();
auto& shader = blitter.material.shaders.back();
size_t maxLights = metadata["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>(256);
size_t maxTextures = metadata["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>(256);
UF_DEBUG_MSG( maxLights << "\t" << maxTextures );
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
size_t maxLights = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>(256);
size_t maxTextures = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>(256);
size_t maxCascades = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(4);
if ( ext::vulkan::settings::experimental::deferredMode == "vxgi" ) {
struct SpecializationConstant {
uint32_t maxCascades = 4;
uint32_t maxTextures = 256;
uint32_t maxCascades = 2;
};
auto& specializationConstants = shader.specializationConstants.get<SpecializationConstant>();
auto& metadata = scene.getComponent<uf::Serializer>();
specializationConstants.maxTextures = maxTextures;
specializationConstants.maxCascades = metadata["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(2);
specializationConstants.maxCascades = maxCascades;
ext::json::forEach( shader.metadata["definitions"]["textures"], [&]( ext::json::Value& t ){
size_t binding = t["binding"].as<size_t>();
std::string name = t["name"].as<std::string>();
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
if ( layout.binding != binding ) continue;
if ( name == "samplerTextures" ) layout.descriptorCount = specializationConstants.maxTextures;
else if ( name == "voxelId" ) layout.descriptorCount = specializationConstants.maxCascades;
else if ( name == "voxelUv" ) layout.descriptorCount = specializationConstants.maxCascades;
else if ( name == "voxelNormal" ) layout.descriptorCount = specializationConstants.maxCascades;
else if ( name == "voxelRadiance" ) layout.descriptorCount = specializationConstants.maxCascades;
if ( name == "samplerTextures" ) layout.descriptorCount = maxTextures;
else if ( name == "voxelId" ) layout.descriptorCount = maxCascades;
else if ( name == "voxelUv" ) layout.descriptorCount = maxCascades;
else if ( name == "voxelNormal" ) layout.descriptorCount = maxCascades;
else if ( name == "voxelRadiance" ) layout.descriptorCount = maxCascades;
}
});
} else {
@ -247,14 +246,13 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
};
auto& specializationConstants = shader.specializationConstants.get<SpecializationConstant>();
auto& metadata = scene.getComponent<uf::Serializer>();
specializationConstants.maxTextures = maxTextures;
ext::json::forEach( shader.metadata["definitions"]["textures"], [&]( ext::json::Value& t ){
if ( t["name"].as<std::string>() != "samplerTextures" ) return;
size_t binding = t["binding"].as<size_t>();
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
if ( layout.binding == binding ) layout.descriptorCount = specializationConstants.maxTextures;
if ( layout.binding == binding ) layout.descriptorCount = maxTextures;
}
});
}

View File

@ -37,13 +37,14 @@ ext::vulkan::GraphicDescriptor ext::vulkan::RenderTargetRenderMode::bindGraphicD
descriptor.parse(metadata["descriptor"]);
std::string type = metadata["type"].as<std::string>();
std::string target = metadata["target"].as<std::string>();
if ( pass == 0 && type == "vxgi" ) {
size_t subpasses = metadata["subpasses"].as<size_t>();
if ( 0 <= pass && pass < subpasses && type == "vxgi" ) {
descriptor.cullMode = VK_CULL_MODE_NONE;
descriptor.depth.test = false;
descriptor.depth.write = false;
descriptor.pipeline = "vxgi";
} else if ( type == "depth" ) {
// descriptor.cullMode = VK_CULL_MODE_NONE;
descriptor.cullMode = VK_CULL_MODE_NONE;
}
// invalidate
if ( target != "" && descriptor.renderMode != this->getName() && descriptor.renderMode != target ) {
@ -347,27 +348,29 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
auto& shader = blitter.material.getShader("compute");
struct SpecializationConstant {
uint32_t maxTextures = 512;
uint32_t maxCascades = 1;
uint32_t maxCascades = 4;
uint32_t maxTextures = 256;
};
auto& specializationConstants = shader.specializationConstants.get<SpecializationConstant>();
auto& metadata = scene.getComponent<uf::Serializer>();
size_t maxLights = metadata["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>(256);
specializationConstants.maxTextures = metadata["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>(256);
specializationConstants.maxCascades = metadata["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(2);
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
size_t maxLights = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>(256);
size_t maxTextures = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>(256);
size_t maxCascades = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(4);
specializationConstants.maxTextures = maxTextures;
specializationConstants.maxCascades = maxCascades;
ext::json::forEach( shader.metadata["definitions"]["textures"], [&]( ext::json::Value& t ){
size_t binding = t["binding"].as<size_t>();
std::string name = t["name"].as<std::string>();
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
if ( layout.binding != binding ) continue;
if ( name == "samplerTextures" ) layout.descriptorCount = specializationConstants.maxTextures;
else if ( name == "voxelId" ) layout.descriptorCount = specializationConstants.maxCascades;
else if ( name == "voxelUv" ) layout.descriptorCount = specializationConstants.maxCascades;
else if ( name == "voxelNormal" ) layout.descriptorCount = specializationConstants.maxCascades;
else if ( name == "voxelRadiance" ) layout.descriptorCount = specializationConstants.maxCascades;
if ( name == "samplerTextures" ) layout.descriptorCount = maxTextures;
else if ( name == "voxelId" ) layout.descriptorCount = maxCascades;
else if ( name == "voxelUv" ) layout.descriptorCount = maxCascades;
else if ( name == "voxelNormal" ) layout.descriptorCount = maxCascades;
else if ( name == "voxelRadiance" ) layout.descriptorCount = maxCascades;
}
});
@ -472,7 +475,6 @@ void ext::vulkan::RenderTargetRenderMode::render() {
submitInfo.commandBufferCount = 1;
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( Device::QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
//vkQueueSubmit(device->queues.graphics, 1, &submitInfo, fences[states::currentBuffer]);
/*
VkSemaphoreWaitInfo waitInfo = {};
waitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;

View File

@ -14,7 +14,6 @@
#include "../scene/behavior.h"
#include <uf/ext/ext.h>
#define COMP_SHADER_USED 1
UF_BEHAVIOR_REGISTER_CPP(ext::VoxelizerBehavior)
#define this (&self)
@ -73,19 +72,16 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
uf::renderer::addRenderMode( &renderMode, metadata.renderModeName );
renderMode.metadata["type"] = "vxgi";
renderMode.metadata["samples"] = 2;
renderMode.metadata["subpasses"] = metadata.cascades;
renderMode.blitter.device = &ext::vulkan::device;
renderMode.width = metadata.fragmentSize.x;
renderMode.height = metadata.fragmentSize.y;
#if COMP_SHADER_USED
renderMode.metadata["shaders"]["compute"] = "/shaders/display/vxgi.comp.spv";
renderMode.blitter.descriptor.renderMode = metadata.renderModeName;
renderMode.blitter.descriptor.subpass = -1;
renderMode.blitter.process = true;
#else
renderMode.metadata["shaders"] = false;
renderMode.blitter.process = false;
#endif
for ( auto& t : sceneTextures.voxels.id ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.uv ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
@ -109,16 +105,48 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
for ( auto& t : sceneTextures.voxels.normal ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.uv ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.radiance ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.radiance ) {
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.levelCount = t.mips;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
{
VkPipelineStageFlags srcStageMask, dstStageMask;
imageMemoryBarrier.image = t.image;
imageMemoryBarrier.oldLayout = t.imageLayout;
imageMemoryBarrier.newLayout = t.imageLayout;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
vkCmdPipelineBarrier( commandBuffer,
srcStageMask, dstStageMask,
VK_FLAGS_NONE,
0, NULL,
0, NULL,
1, &imageMemoryBarrier
);
t.imageLayout = imageMemoryBarrier.newLayout;
}
}
});
renderMode.bindCallback( renderMode.CALLBACK_END, [&]( VkCommandBuffer commandBuffer ){
// parse voxel lighting
#if COMP_SHADER_USED
if ( renderMode.blitter.initialized ) {
auto& pipeline = renderMode.blitter.getPipeline();
pipeline.record(renderMode.blitter, commandBuffer);
vkCmdDispatch(commandBuffer, metadata.voxelSize.x / metadata.dispatchSize.x, metadata.voxelSize.y / metadata.dispatchSize.y, metadata.voxelSize.z / metadata.dispatchSize.z);
}
#endif
// generate mipmaps
VkImageSubresourceRange subresourceRange = {};
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -143,6 +171,40 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
subresourceRange
);
}
// sync
for ( auto& t : sceneTextures.voxels.radiance ) {
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.levelCount = t.mips;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
{
VkPipelineStageFlags srcStageMask, dstStageMask;
imageMemoryBarrier.image = t.image;
imageMemoryBarrier.oldLayout = t.imageLayout;
imageMemoryBarrier.newLayout = t.imageLayout;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
vkCmdPipelineBarrier( commandBuffer,
srcStageMask, dstStageMask,
VK_FLAGS_NONE,
0, NULL,
0, NULL,
1, &imageMemoryBarrier
);
t.imageLayout = imageMemoryBarrier.newLayout;
}
}
});
}
#endif
@ -201,11 +263,9 @@ void ext::VoxelizerBehavior::tick( uf::Object& self ) {
}
}
}
#if COMP_SHADER_USED
ext::ExtSceneBehavior::bindBuffers( scene, metadata.renderModeName, true );
ext::ExtSceneBehavior::bindBuffers( scene );
#endif
#endif
}
void ext::VoxelizerBehavior::render( uf::Object& self ){}
void ext::VoxelizerBehavior::destroy( uf::Object& self ){

View File

@ -234,6 +234,13 @@ void EXT_API ext::initialize() {
}
}
/* Create initial scene (kludge) */ {
uf::Scene& scene = uf::instantiator::instantiate<uf::Scene>(); //new uf::Scene;
uf::scene::scenes.push_back(&scene);
auto& metadata = scene.getComponent<uf::Serializer>();
metadata["system"]["config"] = ::config;
}
if ( ::config["engine"]["limiters"]["framerate"].as<std::string>() == "auto" && ::config["window"]["refresh rate"].is<size_t>() ) {
double scale = 1.0;
size_t refreshRate = ::config["window"]["refresh rate"].as<size_t>();
@ -275,9 +282,6 @@ void EXT_API ext::initialize() {
::config["engine"]["threads"]["workers"] = threads;
uf::iostream << "Using " << threads << " worker threads" << "\n";
}
if ( ::config["engine"]["scenes"]["use graph"].is<bool>() ) {
uf::scene::useGraph = ::config["engine"]["scenes"]["use graph"].as<bool>();
}
#if UF_USE_BULLET
// set bullet parameters
@ -423,13 +427,6 @@ void EXT_API ext::initialize() {
#endif
}
/* Create initial scene (kludge) */ {
uf::Scene& scene = uf::instantiator::instantiate<uf::Scene>(); //new uf::Scene;
uf::scene::scenes.push_back(&scene);
auto& metadata = scene.getComponent<uf::Serializer>();
metadata["system"]["config"] = ::config;
}
/* Initialize Vulkan */ {
#if UF_USE_VULKAN
// setup render mode
@ -440,8 +437,9 @@ void EXT_API ext::initialize() {
}
if ( ::config["engine"]["render modes"]["deferred"].as<bool>() ) {
uf::renderer::addRenderMode( new uf::renderer::DeferredRenderMode, "" );
auto& renderMode = uf::renderer::getRenderMode("Deferred", true);
// renderMode.metadata["system"]["config"] = ::config;
if ( ::config["engine"]["render modes"]["stereo deferred"].as<bool>() ) {
auto& renderMode = uf::renderer::getRenderMode("Deferred", true);
renderMode.metadata["eyes"] = 2;
}
}