Commit for 2021.05.06.7z
This commit is contained in:
parent
0c325bb492
commit
7670c8c3af
@ -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];
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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) );
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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>();
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 );
|
||||
|
||||
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 = {};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user