Commit for 2021.05.06.7z

This commit is contained in:
mrq 2021-05-06 00:00:00 -05:00
parent 0c325bb492
commit 7670c8c3af
14 changed files with 121 additions and 152 deletions

View File

@ -39,7 +39,7 @@ const vec2 poissonDisk[16] = vec2[](
vec2( 0.14383161, -0.14100790 )
);
layout (constant_id = 0) const uint TEXTURES = 256;
layout (constant_id = 0) const uint TEXTURES = 512;
struct Matrices {
mat4 view[2];

View File

@ -1,5 +1,6 @@
#version 450
#extension GL_EXT_samplerless_texture_functions : require
#extension GL_EXT_nonuniform_qualifier : enable
#define MULTISAMPLING 1
#define DEFERRED_SAMPLING 1
@ -21,7 +22,7 @@ const float PI = 3.14159265359;
const float EPSILON = 0.00001;
const float SQRT2 = 1.41421356237;
const float LIGHT_POWER_CUTOFF = 0.005;
const float LIGHT_POWER_CUTOFF = 0.0005;
const vec2 poissonDisk[16] = vec2[](
vec2( -0.94201624, -0.39906216 ),
@ -42,9 +43,8 @@ const vec2 poissonDisk[16] = vec2[](
vec2( 0.14383161, -0.14100790 )
);
#define MAX_CASCADES 4
layout (constant_id = 0) const uint CASCADES = MAX_CASCADES;
layout (constant_id = 1) const uint TEXTURES = 256;
layout (constant_id = 0) const uint CASCADES = 16;
layout (constant_id = 1) const uint TEXTURES = 512;
struct Matrices {
mat4 view[2];
@ -213,7 +213,7 @@ layout (binding = 4) uniform UBO {
float exposure;
uint msaa;
uint shadowSamples;
uint padding1;
float cascadePower;
} ubo;
layout (std140, binding = 5) readonly buffer Lights {
@ -425,10 +425,10 @@ float shadowFactor( const Light light, float def ) {
const float bias = light.depthBias;
const float eyeDepth = positionClip.z;
const int samples = int(ubo.shadowSamples);
if ( samples < 1 ) return eyeDepth < texture(samplerTextures[light.mapIndex], uv).r - bias ? 0.0 : factor;
if ( samples < 1 ) return eyeDepth < texture(samplerTextures[nonuniformEXT(light.mapIndex)], uv).r - bias ? 0.0 : factor;
for ( int i = 0; i < samples; ++i ) {
const int index = int( float(samples) * random(floor(surface.position.world.xyz * 1000.0), i)) % samples;
const float lightDepth = texture(samplerTextures[light.mapIndex], uv + poissonDisk[index] / 700.0 ).r;
const float lightDepth = texture(samplerTextures[nonuniformEXT(light.mapIndex)], uv + poissonDisk[index] / 700.0 ).r;
if ( eyeDepth < lightDepth - bias ) factor -= 1.0 / samples;
}
return factor;
@ -452,71 +452,64 @@ vec4 postProcess() {
return vec4(surface.fragment.rgb,1);
}
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 {
vec3 min;
vec3 max;
float mipmapLevels;
float radianceSize;
float voxelSize;
float radianceSizeRecip;
float voxelSizeRecip;
} voxelInfo;
uint BIASED_ROUND( float x ) {
return uint( (x < 1 - voxelInfo.radianceSizeRecip) ? floor(x) : ceil(x));
}
float SCALE_CASCADE( uint x ) {
return pow(1 + x, ubo.cascadePower);
}
vec4 voxelTrace( inout Ray ray, float aperture, float maxDistance ) {
uint CASCADE = 1;
uint CASCADE = 0;
#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 / 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 = 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 ));
}
{
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;
const float granularityRecip = 12.0f;
const float granularity = 1.0f / granularityRecip;
const float occlusionFalloff = 128.0f;
const vec3 voxelBounds = voxelInfo.max - voxelInfo.min;
const vec3 voxelBoundsRecip = 1.0f / voxelBounds;
const float coneCoefficient = 2.0 * tan(aperture * 0.5);
const uint maxSteps = uint(voxelInfo.radianceSize * CASCADES * granularityRecip);
// box
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;
const float tDelta = voxelInfo.radianceSizeRecip * granularityRecip;
// marcher
#if VXGI_NDC
ray.distance = tStart + tDelta * granularityRecip * 0.25;
#else
ray.distance = tStart + tDelta * granularity;
#endif
ray.distance = tStart + tDelta * 4 * (1 + CASCADE);
ray.position = vec3(0);
vec4 radiance = vec4(0);
vec3 uvw = vec3(0);
// cone mipmap shit
const float coneCoefficient = 2.0 * tan(aperture * 0.5);
float coneDiameter = coneCoefficient * ray.distance;
float level = aperture > 0 ? log2( coneDiameter ) : 0;
// results
vec4 color = vec4(0);
float occlusion = 0.0;
uint stepCounter = 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
@ -541,52 +534,10 @@ vec4 voxelTrace( inout Ray ray, float aperture, float maxDistance ) {
if ( level >= voxelInfo.mipmapLevels ) break;
// 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);
radiance = textureLod(voxelRadiance[nonuniformEXT(CASCADE)], uvw.xzy, level);
color += (1.0 - color.a) * radiance;
occlusion += ((1.0f - occlusion) * radiance.a) / (1.0f + falloff * coneDiameter);
occlusion += ((1.0f - occlusion) * radiance.a) / (1.0f + occlusionFalloff * coneDiameter);
}
return maxDistance > 0 ? color : vec4(color.rgb, occlusion);
// return vec4(color.rgb, occlusion);
@ -604,13 +555,8 @@ float shadowFactor( const Light light, float def ) {
const float DEPTH_BIAS = 0.0;
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
ray.origin = surface.position.world + ray.direction * 0.5;
float z = distance( surface.position.world, light.position ) - DEPTH_BIAS;
return 1.0 - voxelTrace( ray, SHADOW_APERTURE, z ).a;
}
@ -694,7 +640,7 @@ void main() {
if ( useAtlas ) textureAtlas = textures[drawCall.textureIndex + material.indexAtlas];
if ( validTextureIndex( drawCall.textureIndex + material.indexAlbedo ) ) {
const Texture t = textures[drawCall.textureIndex + material.indexAlbedo];
surface.material.albedo = textureLod( samplerTextures[(useAtlas)?textureAtlas.index:t.index], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, surface.uv ) : surface.uv, mip );
surface.material.albedo = textureLod( samplerTextures[nonuniformEXT((useAtlas)?textureAtlas.index:t.index)], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, surface.uv ) : surface.uv, mip );
}
// OPAQUE
if ( material.modeAlpha == 0 ) {
@ -709,7 +655,7 @@ void main() {
// Emissive textures
if ( validTextureIndex( drawCall.textureIndex + material.indexEmissive ) ) {
const Texture t = textures[drawCall.textureIndex + material.indexEmissive];
surface.fragment += textureLod( samplerTextures[(useAtlas)?textureAtlas.index:t.index], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, surface.uv ) : surface.uv, mip );
surface.fragment += textureLod( samplerTextures[nonuniformEXT((useAtlas)?textureAtlas.index:t.index)], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, surface.uv ) : surface.uv, mip );
}
#else
#if !MULTISAMPLING
@ -722,6 +668,19 @@ void main() {
surface.material.roughness = material.factorRoughness;
surface.material.occlusion = material.factorOcclusion;
// GI
{
voxelInfo.radianceSize = textureSize( voxelRadiance[0], 0 ).x;
voxelInfo.radianceSizeRecip = 1.0 / voxelInfo.radianceSize;
voxelInfo.mipmapLevels = log2(voxelInfo.radianceSize) + 1;
#if VXGI_NDC
voxelInfo.min = vec3( -1 );
voxelInfo.max = vec3( 1 );
#else
const mat4 inverseOrtho = inverse( ubo.matrices.vxgi );
voxelInfo.min = vec3( inverseOrtho * vec4( -1, -1, -1, 1 ) );
voxelInfo.max = vec3( inverseOrtho * vec4( 1, 1, 1, 1 ) );
#endif
}
{
const vec3 P = surface.position.world;
const vec3 N = surface.normal.world;
@ -769,22 +728,6 @@ void main() {
vec4 indirectDiffuse = vec4(0);
vec4 indirectSpecular = vec4(0);
{
voxelInfo.radianceSize = textureSize( voxelRadiance[0], 0 ).x;
voxelInfo.radianceSizeRecip = 1.0 / voxelInfo.radianceSize;
voxelInfo.mipmapLevels = log2(voxelInfo.radianceSize) + 1;
#if VXGI_NDC
voxelInfo.min = vec3( -1 );
voxelInfo.max = vec3( 1 );
voxelInfo.voxelSize = voxelInfo.radianceSizeRecip;
#else
const mat4 inverseOrtho = inverse( ubo.matrices.vxgi );
voxelInfo.min = vec3( inverseOrtho * vec4( -1, -1, -1, 1 ) );
voxelInfo.max = vec3( inverseOrtho * vec4( 1, 1, 1, 1 ) );
voxelInfo.voxelSize = 1;
#endif
voxelInfo.voxelSizeRecip = 1.0 / voxelInfo.voxelSize;
}
// outFragColor.rgb = voxelConeTrace( surface.ray, 0 ).rgb; return;
if ( DIFFUSE_INDIRECT_FACTOR > 0.0f ) {
@ -869,7 +812,7 @@ void main() {
// point light, compute only diffuse
// else if ( abs(light.type) == 1 ) surface.fragment.rgb += (diffuse) * Lr * cosLi;
else surface.fragment.rgb += (diffuse + specular) * Lr * cosLi;
surface.fragment.a += light.power * La * Ls;
// surface.fragment.a += light.power * La * Ls;
}
}

View File

@ -1,5 +1,6 @@
#version 450
#extension GL_EXT_samplerless_texture_functions : require
#extension GL_EXT_nonuniform_qualifier : enable
layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
@ -14,8 +15,8 @@ const float EPSILON = 0.00001;
const float LIGHT_POWER_CUTOFF = 0.005;
layout (constant_id = 0) const uint CASCADES = 4;
layout (constant_id = 1) const uint TEXTURES = 256;
layout (constant_id = 0) const uint CASCADES = 16;
layout (constant_id = 1) const uint TEXTURES = 512;
struct Matrices {
mat4 view[2];
@ -156,7 +157,7 @@ layout (binding = 4) uniform UBO {
float exposure;
uint msaa;
uint shadowSamples;
uint padding1;
float cascadePower;
} ubo;
layout (std140, binding = 5) readonly buffer Lights {
@ -269,20 +270,19 @@ float shadowFactor( const Light light, float def ) {
const float bias = light.depthBias;
const float eyeDepth = positionClip.z;
const int samples = int(ubo.shadowSamples);
return eyeDepth < texture(samplerTextures[light.mapIndex], uv).r - bias ? 0.0 : factor;
return eyeDepth < texture(samplerTextures[nonuniformEXT(light.mapIndex)], uv).r - bias ? 0.0 : factor;
#if 0
for ( int i = 0; i < samples; ++i ) {
const int index = int( float(samples) * random(floor(surface.position.world.xyz * 1000.0), i)) % samples;
const float lightDepth = texture(samplerTextures[light.mapIndex], uv + poissonDisk[index] / 700.0 ).r;
const float lightDepth = texture(samplerTextures[nonuniformEXT(light.mapIndex)], uv + poissonDisk[index] / 700.0 ).r;
if ( eyeDepth < lightDepth - bias ) factor -= 1.0 / samples;
}
return factor;
#endif
}
#define CASCADE_POWER 2
uint SCALE_CASCADE( uint x ) {
return uint(pow(1 + x, CASCADE_POWER));
float SCALE_CASCADE( uint x ) {
return pow(1 + x, ubo.cascadePower);
}
void main() {
@ -313,7 +313,7 @@ void main() {
if ( useAtlas ) textureAtlas = textures[drawCall.textureIndex + material.indexAtlas];
if ( validTextureIndex( drawCall.textureIndex + material.indexAlbedo ) ) {
const Texture t = textures[drawCall.textureIndex + material.indexAlbedo];
surface.material.albedo = texture( samplerTextures[(useAtlas)?textureAtlas.index:t.index], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, surface.uv ) : surface.uv );
surface.material.albedo = texture( samplerTextures[nonuniformEXT((useAtlas)?textureAtlas.index:t.index)], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, surface.uv ) : surface.uv );
}
// OPAQUE
@ -329,7 +329,7 @@ void main() {
// Emissive textures
if ( validTextureIndex( drawCall.textureIndex + material.indexEmissive ) ) {
const Texture t = textures[drawCall.textureIndex + material.indexEmissive];
surface.fragment += texture( samplerTextures[(useAtlas)?textureAtlas.index:t.index], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, surface.uv ) : surface.uv );
surface.fragment += texture( samplerTextures[nonuniformEXT((useAtlas)?textureAtlas.index:t.index)], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, surface.uv ) : surface.uv );
}
#else
surface.material.albedo = imageLoad(voxelRadiance[CASCADE], ivec3(tUvw) );

View File

@ -1,4 +1,5 @@
#version 450
#extension GL_EXT_nonuniform_qualifier : enable
#define LAMBERT 1
#define PBR 0
@ -226,10 +227,10 @@ float shadowFactor( const Light light, float def ) {
const float bias = light.depthBias;
const float eyeDepth = positionClip.z;
const int samples = 16; //int(ubo.poissonSamples);
if ( samples <= 1 ) return eyeDepth < texture(samplerTextures[light.mapIndex], uv).r - bias ? 0.0 : factor;
if ( samples <= 1 ) return eyeDepth < texture(samplerTextures[nonuniformEXT(light.mapIndex)], uv).r - bias ? 0.0 : factor;
for ( int i = 0; i < samples; ++i ) {
const int index = int( float(samples) * random(floor(surface.position.world * 1000.0), i)) % samples;
const float lightDepth = texture(samplerTextures[light.mapIndex], uv + poissonDisk[index] / 700.0 ).r;
const float lightDepth = texture(samplerTextures[nonuniformEXT(light.mapIndex)], uv + poissonDisk[index] / 700.0 ).r;
if ( eyeDepth < lightDepth - bias ) factor -= 1.0 / samples;
}
return factor;
@ -257,7 +258,7 @@ void main() {
if ( !validTextureIndex( material.indexAlbedo ) ) discard;
{
const Texture t = textures[material.indexAlbedo];
surface.material.albedo = textureLod( samplerTextures[(useAtlas) ? textureAtlas.index : t.index], (useAtlas) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip );
surface.material.albedo = textureLod( samplerTextures[nonuniformEXT((useAtlas) ? textureAtlas.index : t.index)], (useAtlas) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip );
// alpha mode OPAQUE
if ( material.modeAlpha == 0 ) {
surface.material.albedo.a = 1;
@ -275,13 +276,13 @@ void main() {
// sample normal
if ( validTextureIndex( material.indexNormal ) ) {
const Texture t = textures[material.indexNormal];
surfacem.normal.world = inTBN * normalize( textureLod( samplerTextures[(useAtlas)?textureAtlas.index:t.index], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip ).xyz * 2.0 - vec3(1.0));
surfacem.normal.world = inTBN * normalize( textureLod( samplerTextures[nonuniformEXT((useAtlas)?textureAtlas.index:t.index)], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip ).xyz * 2.0 - vec3(1.0));
}
// sample emissive
if ( validTextureIndex( material.indexEmissive ) ) {
const Texture t = textures[material.indexEmissive];
surface.fragment = textureLod( samplerTextures[(useAtlas) ? textureAtlas.index : t.index], (useAtlas) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip );
surface.fragment = textureLod( samplerTextures[nonuniformEXT((useAtlas) ? textureAtlas.index : t.index)], (useAtlas) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip );
}
#else
surface.material.albedo = vec4(1);

View File

@ -1,4 +1,5 @@
#version 450
#extension GL_EXT_nonuniform_qualifier : enable
#define DEFERRED_SAMPLING 1
#define CAN_DISCARD 1
@ -100,7 +101,7 @@ void main() {
if ( useAtlas ) textureAtlas = textures[material.indexAtlas];
if ( !validTextureIndex( material.indexAlbedo ) ) discard; {
Texture t = textures[material.indexAlbedo];
A = textureLod( samplerTextures[(useAtlas) ? textureAtlas.index : t.index], (useAtlas) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip );
A = textureLod( samplerTextures[nonuniformEXT((useAtlas) ? textureAtlas.index : t.index)], (useAtlas) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip );
// alpha mode OPAQUE
if ( material.modeAlpha == 0 ) {
A.a = 1;
@ -121,7 +122,7 @@ void main() {
#else
Texture t = textures[material.indexLightmap];
const float gamma = 1.6;
const vec4 L = pow(textureLod( samplerTextures[t.index], inSt, mip ), vec4(1.0 / gamma));
const vec4 L = pow(textureLod( samplerTextures[nonuniformEXT(t.index)], inSt, mip ), vec4(1.0 / gamma));
A *= L;
#endif
}
@ -131,13 +132,13 @@ void main() {
// sample normal
if ( validTextureIndex( material.indexNormal ) ) {
Texture t = textures[material.indexNormal];
N = inTBN * normalize( textureLod( samplerTextures[(useAtlas)?textureAtlas.index:t.index], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip ).xyz * 2.0 - vec3(1.0));
N = inTBN * normalize( textureLod( samplerTextures[nonuniformEXT((useAtlas)?textureAtlas.index:t.index)], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip ).xyz * 2.0 - vec3(1.0));
}
#if 0
// sample metallic/roughness
if ( validTextureIndex( material.indexMetallicRoughness ) ) {
Texture t = textures[material.indexMetallicRoughness];
const vec4 sampled = textureLod( samplerTextures[(useAtlas)?textureAtlas.index:t.index], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip );
const vec4 sampled = textureLod( samplerTextures[nonuniformEXT((useAtlas)?textureAtlas.index:t.index)], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip );
M = sampled.b;
R = sampled.g;
}
@ -145,7 +146,7 @@ void main() {
AO = material.factorOcclusion;
if ( validTextureIndex( material.indexOcclusion ) ) {
Texture t = textures[material.indexOcclusion];
AO = textureLod( samplerTextures[(useAtlas)?textureAtlas.index:t.index], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv ).r;
AO = textureLod( samplerTextures[nonuniformEXT((useAtlas)?textureAtlas.index:t.index)], ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv ).r;
}
#endif
outAlbedo = A * inColor;

View File

@ -1,12 +1,13 @@
#version 450
#extension GL_EXT_nonuniform_qualifier : enable
#define DEFERRED_SAMPLING 1
#define USE_LIGHTMAP 1
#define PI 3.1415926536f
layout (constant_id = 0) const uint CASCADES = 4;
layout (constant_id = 1) const uint TEXTURES = 256;
layout (constant_id = 0) const uint CASCADES = 16;
layout (constant_id = 1) const uint TEXTURES = 512;
struct Material {
vec4 colorBase;
@ -108,7 +109,7 @@ void main() {
if ( useAtlas ) textureAtlas = textures[material.indexAtlas];
if ( !validTextureIndex( material.indexAlbedo ) ) discard; {
Texture t = textures[material.indexAlbedo];
A = textureLod( samplerTextures[(useAtlas) ? textureAtlas.index : t.index], (useAtlas) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip );
A = textureLod( samplerTextures[nonuniformEXT((useAtlas) ? textureAtlas.index : t.index)], (useAtlas) ? mix( t.lerp.xy, t.lerp.zw, uv ) : uv, mip );
// alpha mode OPAQUE
if ( material.modeAlpha == 0 ) {
A.a = 1;
@ -129,7 +130,7 @@ void main() {
#else
Texture t = textures[material.indexLightmap];
const float gamma = 1.6;
const vec4 L = pow(textureLod( samplerTextures[t.index], inSt, mip ), vec4(1.0 / gamma));
const vec4 L = pow(textureLod( samplerTextures[nonuniformEXT(t.index)], inSt, mip ), vec4(1.0 / gamma));
A *= L;
#endif
}

View File

@ -21,11 +21,14 @@ layout (location = 8) flat out ivec4 outId;
layout (binding = 6) uniform UBO {
mat4 voxel;
float cascadePower;
float padding1;
float padding2;
float padding3;
} ubo;
#define CASCADE_POWER 2
uint SCALE_CASCADE( uint x ) {
return uint(pow(1 + x, CASCADE_POWER));
float SCALE_CASCADE( uint x ) {
return pow(1 + x, ubo.cascadePower);
}
void main(){
@ -61,7 +64,7 @@ void main(){
outPosition = P[i]; // + D;
outId = inId[i];
const vec3 P = outPosition + D;
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);

View File

@ -14,7 +14,9 @@ namespace pod {
std::vector<uf::renderer::Texture3D> uv;
std::vector<uf::renderer::Texture3D> normal;
std::vector<uf::renderer::Texture3D> radiance;
pod::Matrix4f matrix;
float cascadePower = 2.0;
} voxels;
};

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 = 16;
uint32_t textures = 1;
};
auto& specializationConstants = shader.specializationConstants.get<SpecializationConstant>();
specializationConstants.textures = texture2Ds;

View File

@ -214,14 +214,14 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
auto& shader = blitter.material.shaders.back();
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);
size_t maxLights = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>(512);
size_t maxTextures = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>(512);
size_t maxCascades = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(16);
if ( ext::vulkan::settings::experimental::deferredMode == "vxgi" ) {
struct SpecializationConstant {
uint32_t maxCascades = 4;
uint32_t maxTextures = 256;
uint32_t maxCascades = 16;
uint32_t maxTextures = 512;
};
auto& specializationConstants = shader.specializationConstants.get<SpecializationConstant>();

View File

@ -348,15 +348,15 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
auto& shader = blitter.material.getShader("compute");
struct SpecializationConstant {
uint32_t maxCascades = 4;
uint32_t maxTextures = 256;
uint32_t maxCascades = 16;
uint32_t maxTextures = 512;
};
auto& specializationConstants = shader.specializationConstants.get<SpecializationConstant>();
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);
size_t maxLights = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>(512);
size_t maxTextures = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"].as<size_t>(512);
size_t maxCascades = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(16);
specializationConstants.maxTextures = maxTextures;
specializationConstants.maxCascades = maxCascades;

View File

@ -497,7 +497,7 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const std::string& re
alignas(4) float exposure;
alignas(4) uint32_t msaa;
alignas(4) uint32_t shadowSamples;
alignas(4) uint32_t padding1;
alignas(4) float cascadePower;
};
struct SpecializationConstant {
uint32_t maxTextures = 512;
@ -659,6 +659,8 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const std::string& re
}
}
uniforms->matrices.vxgi = sceneTextures.voxels.matrix;
uniforms->cascadePower = sceneTextures.voxels.cascadePower;
uniforms->lengths.materials = std::min( materials.size(), maxTextures );
uniforms->lengths.textures = std::min( textures.size(), maxTextures );
uniforms->lengths.drawCalls = std::min( drawCalls.size(), maxTextures );

View File

@ -29,6 +29,7 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
const float DEFAULT_VOXELIZE_LIMITER = ext::config["engine"]["scenes"]["vxgi"]["limiter"].as<float>(0);
const uint32_t DEFAULT_DISPATCH_SIZE = ext::config["engine"]["scenes"]["vxgi"]["dispatch"].as<uint32_t>(8);
const uint32_t DEFAULT_CASCADES = ext::config["engine"]["scenes"]["vxgi"]["cascades"].as<uint32_t>(8);
const float DEFAULT_CASCADE_POWER = ext::config["engine"]["scenes"]["vxgi"]["cascadePower"].as<float>(1.5);
if ( metadata.voxelSize.x == 0 ) metadata.voxelSize.x = DEFAULT_VOXEL_SIZE;
if ( metadata.voxelSize.y == 0 ) metadata.voxelSize.y = DEFAULT_VOXEL_SIZE;
@ -41,6 +42,8 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
if ( metadata.dispatchSize.z == 0 ) metadata.dispatchSize.z = DEFAULT_DISPATCH_SIZE;
if ( metadata.cascades == 0 ) metadata.cascades = DEFAULT_CASCADES;
if ( metadata.cascadePower == 0 ) metadata.cascadePower = DEFAULT_CASCADE_POWER;
metadata.extents.min = uf::vector::decode( ext::config["engine"]["scenes"]["vxgi"]["extents"]["min"], pod::Vector3f{-32, -32, -32} );
metadata.extents.max = uf::vector::decode( ext::config["engine"]["scenes"]["vxgi"]["extents"]["max"], pod::Vector3f{ 32, 32, 32} );
@ -106,6 +109,7 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
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 );
#if 0
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
@ -138,6 +142,7 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
t.imageLayout = imageMemoryBarrier.newLayout;
}
}
#endif
});
renderMode.bindCallback( renderMode.CALLBACK_END, [&]( VkCommandBuffer commandBuffer ){
// parse voxel lighting
@ -172,6 +177,7 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
);
}
#if 0
// sync
for ( auto& t : sceneTextures.voxels.radiance ) {
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
@ -205,6 +211,7 @@ void ext::VoxelizerBehavior::initialize( uf::Object& self ) {
t.imageLayout = imageMemoryBarrier.newLayout;
}
}
#endif
});
}
#endif
@ -243,6 +250,7 @@ void ext::VoxelizerBehavior::tick( uf::Object& self ) {
pod::Vector3f min = metadata.extents.min + controllerPosition;
pod::Vector3f max = metadata.extents.max + controllerPosition;
sceneTextures.voxels.matrix = uf::matrix::ortho<float>( min.x, max.x, min.y, max.y, min.z, max.z );
sceneTextures.voxels.cascadePower = metadata.cascadePower;
auto graph = uf::scene::generateGraph();
for ( auto entity : graph ) {
@ -254,10 +262,17 @@ void ext::VoxelizerBehavior::tick( uf::Object& self ) {
auto& sceneTextures = scene.getComponent<pod::SceneTextures>();
struct UniformDescriptor {
alignas(16) pod::Matrix4f matrix;
alignas(4) float cascadePower;
alignas(4) float padding1;
alignas(4) float padding2;
alignas(4) float padding3;
};
auto& uniform = shader.getUniform("UBO");
auto& uniforms = uniform.get<UniformDescriptor>();
uniforms.matrix = sceneTextures.voxels.matrix;
uniforms.cascadePower = sceneTextures.voxels.cascadePower;
shader.updateUniform( "UBO", uniform );
}
}

View File

@ -21,6 +21,7 @@ namespace ext {
pod::Vector3ui dispatchSize = { 0, 0, 0 };
std::string renderModeName = "VXGI";
size_t cascades = 0;
float cascadePower = 0;
struct {
pod::Vector3f min = {};
pod::Vector3f max = {};