repaired barycentric-based deferred rendering

This commit is contained in:
ecker 2025-08-01 21:11:55 -05:00
parent 85696bd8f6
commit 8ba6214cc4
11 changed files with 64 additions and 47 deletions

View File

@ -31,19 +31,19 @@
"vxgi": {
"limiter": 0,
// "limiter": 0.5,
"size": 128,
"dispatch": 8,
"size": 192,
"dispatch": 16,
"cascades": 3,
"cascadePower": 2.0,
"cascadePower": 1.5,
"granularity": 16,
"voxelizeScale": 1,
"occlusionFalloff": 2,
"traceStartOffsetFactor": 1,
"filtering": "LINEAR",
"filtering": "NEAREST",
"shadows": 0,
"extents": {
"min": [ -8, -8, -8 ],
"max": [ 8, 8, 8 ]
"min": [ -16, -16, -16 ],
"max": [ 16, 16, 16 ]
}
},
"rt": {
@ -70,8 +70,8 @@
"messages": false,
"checkpoints": false,
"filters": [
"0xe5d1743c" // VUID-vkCmdDispatch-None-02699 (problem when using VXGI)
,"0x6714bd0c" // VUID-vkCmdDispatch-format-07753 (for some dumb shit)
// "0xe5d1743c" // VUID-vkCmdDispatch-None-02699 (problem when using VXGI) (seems to be fixed?)
// ,"0x6714bd0c" // VUID-vkCmdDispatch-format-07753 (for some dumb shit) (seems to be fixed?)
// ,"0x71500fba" // VUID-vkDestroyDevice-device-00378 (don't care about a clean cleanup)
// ,"0x141cb623" // UNASSIGNED-Threading-MultipleThreads ("false-positive" multithreading)
@ -406,6 +406,7 @@
"size" : [ 1280, 720 ],
// "size" : [ 960, 540 ],
// "size" : [ 640, 480 ],
// "size" : [ 480, 640 ],
// "size" : [ 256, 224 ],
"title" : "Grimgram",
"visible" : true

View File

@ -55,8 +55,8 @@
}
},
"movement": {
"walk": 12,
"move": 12,
"walk": 8,
"move": 8,
"run": 20,
// "rotate": 1.5,
"rotate": 6,

View File

@ -6,7 +6,7 @@
],
"metadata": {
"light": {
"fog-0": {
"fog": {
// "color": [ 0.1, 0.1, 0.1 ],
// "color": [ 0.2, 0.2, 0.2 ],
"color": [ 0.3, 0.3, 0.3 ],

View File

@ -340,8 +340,7 @@ uvec4 uvec2_16x4( uvec2 i ) {
void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
Triangle triangle;
Vertex points[3];
if ( isValidAddress(instanceAddresses.vertex) ) {
if ( false && isValidAddress(instanceAddresses.vertex) ) {
// Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex));
// #pragma unroll 3
// for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_] = vertices.v[/*triangle.*/indices[_]];
@ -349,7 +348,8 @@ void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
if ( isValidAddress(instanceAddresses.position) ) {
VPos buf = VPos(nonuniformEXT(instanceAddresses.position));
#pragma unroll 3
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].position[_] = buf.v[/*triangle.*/indices[_]*3+_];
for ( uint _ = 0; _ < 3; ++_ ) points[_].position = vec3( buf.v[indices[_]*3+0], buf.v[indices[_]*3+1], buf.v[indices[_]*3+2] );
//for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].position[_] = buf.v[/*triangle.*/indices[_]*3+_];
}
if ( isValidAddress(instanceAddresses.uv) ) {
VUv buf = VUv(nonuniformEXT(instanceAddresses.uv));
@ -364,7 +364,8 @@ void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
if ( isValidAddress(instanceAddresses.normal) ) {
VNormal buf = VNormal(nonuniformEXT(instanceAddresses.normal));
#pragma unroll 3
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal[_] = buf.v[/*triangle.*/indices[_]*3+_];
for ( uint _ = 0; _ < 3; ++_ ) points[_].normal = vec3( buf.v[indices[_]*3+0], buf.v[indices[_]*3+1], buf.v[indices[_]*3+2] );
// for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal[_] = buf.v[/*triangle.*/indices[_]*3+_];
}
if ( isValidAddress(instanceAddresses.tangent) ) {
VTangent buf = VTangent(nonuniformEXT(instanceAddresses.tangent));
@ -399,14 +400,14 @@ void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
}
#endif
triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
triangle.point.normal = /*triangle.*/points[0].normal * surface.barycentric[0] + /*triangle.*/points[1].normal * surface.barycentric[1] + /*triangle.*/points[2].normal * surface.barycentric[2];
// triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
triangle.point.position = /*triangle.*/points[0].position * surface.barycentric[0] + /*triangle.*/points[1].position * surface.barycentric[1] + /*triangle.*/points[2].position * surface.barycentric[2];
triangle.point.normal = /*triangle.*/points[0].normal * surface.barycentric[0] + /*triangle.*/points[1].normal * surface.barycentric[1] + /*triangle.*/points[2].normal * surface.barycentric[2];
triangle.point.uv = /*triangle.*/points[0].uv * surface.barycentric[0] + /*triangle.*/points[1].uv * surface.barycentric[1] + /*triangle.*/points[2].uv * surface.barycentric[2];
triangle.point.st = /*triangle.*/points[0].st * surface.barycentric[0] + /*triangle.*/points[1].st * surface.barycentric[1] + /*triangle.*/points[2].st * surface.barycentric[2];
triangle.point.tangent = /*triangle.*/points[0].tangent * surface.barycentric[0] + /*triangle.*/points[1].tangent * surface.barycentric[1] + /*triangle.*/points[2].tangent * surface.barycentric[2];
// triangle.point.normal = triangle.geomNormal;
if ( triangle.point.tangent != vec3(0) ) {
surface.tangent.world = normalize(vec3( surface.instance.model * vec4(triangle.point.tangent, 0.0) ));
@ -414,8 +415,8 @@ void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
surface.tbn = mat3(surface.tangent.world, bitangent, triangle.point.normal);
}
// bind position
#if 1 || BARYCENTRIC_CALCULATE
// bind position (seems to muck with the skybox + fog)
#if 0 && BARYCENTRIC_CALCULATE
{
surface.position.world = vec3( surface.instance.model * vec4(triangle.point.position, 1.0 ) );
surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.position.world, 1.0) );

View File

@ -69,13 +69,10 @@
#extension GL_EXT_nonuniform_qualifier : enable
#endif
#if !UINT64_ENABLED
#define uint64_t uvec2
#endif
// easy and accessible in one place
#ifndef BARYCENTRIC
#define BARYCENTRIC 0
#define BARYCENTRIC 1
#endif
#if BARYCENTRIC
#ifndef BARYCENTRIC_CALCULATE
@ -86,6 +83,15 @@
#endif
#endif
#if RT || BARYCENTRIC
#define BUFFER_REFERENCE 1
#define UINT64_ENABLED 1
#endif
#if !UINT64_ENABLED
#define uint64_t uvec2
#endif
#if BUFFER_REFERENCE
#extension GL_EXT_scalar_block_layout : enable
#extension GL_EXT_buffer_reference : enable

View File

@ -287,9 +287,9 @@ struct Vertex {
vec2 st;
vec3 normal;
vec3 tangent;
uint id;
uvec2 joints;
vec4 weights;
uint id;
};
struct Triangle {

View File

@ -14,10 +14,6 @@ layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
#define PBR 1
#define LAMBERT 0
#if RT || BARYCENTRIC
#define BUFFER_REFERENCE 1
#define UINT64_ENABLED 1
#endif
#define FOG 1
#define FOG_RAY_MARCH 1
@ -170,7 +166,8 @@ void postProcess() {
if ( ubo.settings.mode.type > 0x0000 ) {
uvec2 renderSize = imageSize(imageColor);
vec2 inUv = (vec2(gl_GlobalInvocationID.xy) / vec2(renderSize)) * 2.0f - 1.0f;
if ( inUv.x < 0 ) {
if ( true ) {
// if ( ubo.settings.mode.type == 0x0001 ) outFragColor = vec4(surface.barycentric.rgb, 1);
if ( ubo.settings.mode.type == 0x0001 ) outFragColor = vec4(surface.material.albedo.rgb, 1);
else if ( ubo.settings.mode.type == 0x0002 ) outFragColor = vec4(surface.light.rgb, 1);
else if ( ubo.settings.mode.type == 0x0003 ) outFragColor = vec4(vec3(surface.light.a), 1);
@ -182,7 +179,7 @@ void postProcess() {
else if ( ubo.settings.mode.type == 0x0009 ) outFragColor = vec4(vec3(surface.material.occlusion), 1);
}
}
IMAGE_STORE( imageColor, outFragColor );
IMAGE_STORE( imageBright, outFragBright );
IMAGE_STORE( imageMotion, vec4(outFragMotion, 0, 0) );
@ -288,13 +285,15 @@ void directLighting() {
Ray ray;
ray.direction = surface.ray.direction;
ray.origin = surface.ray.origin;
vec4 radiance = voxelConeTrace( ray, 0.0000001f );
ray.origin -= ray.direction;
vec4 radiance = voxelConeTrace( ray, 0 );
surface.material.albedo.rgb = radiance.rgb;
surface.material.indirect.rgb = vec3(0);
surface.fragment.rgb = radiance.rgb;
surface.fragment.a = radiance.a;
return;
//return;
}
#endif

View File

@ -68,9 +68,10 @@ layout (binding = 19, rgba8) uniform volatile coherent image3D voxelOutput[CASCA
void main() {
const vec3 tUvw = gl_GlobalInvocationID.xzy;
for ( uint CASCADE = 0; CASCADE < CASCADES; ++CASCADE ) {
vec2 N_E;
N_E.x = uintBitsToFloat(imageLoad(voxelNormalX[CASCADE], ivec3(tUvw) ).x);
N_E.y = uintBitsToFloat(imageLoad(voxelNormalY[CASCADE], ivec3(tUvw) ).x);
vec2 N_E = vec2(
uintBitsToFloat(imageLoad(voxelNormalX[CASCADE], ivec3(tUvw) ).x),
uintBitsToFloat(imageLoad(voxelNormalY[CASCADE], ivec3(tUvw) ).x)
);
surface.normal.world = decodeNormals( N_E );
surface.normal.eye = vec3( ubo.settings.vxgi.matrix * vec4( surface.normal.world, 0.0f ) );
@ -160,6 +161,7 @@ void main() {
#if 0
pbr();
#else
/*
surface.material.roughness *= 4.0;
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
const vec3 Lo = normalize( surface.position.world );
@ -197,6 +199,7 @@ void main() {
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
surface.light.a += light.power * La * Ls;
}
*/
#endif
}
surface.fragment.rgb += surface.light.rgb;

View File

@ -15,11 +15,16 @@ layout (constant_id = 0) const uint TEXTURES = 1;
#include "../../common/structs.h"
#if BARYCENTRIC && !BARYCENTRIC_CALCULATE
#define BARYCENTRIC_STABILIZE 1
// #define BARY_COORD gl_BaryCoordEXT
// #extension GL_EXT_fragment_shader_barycentric : enable
#define BARY_COORD gl_BaryCoordSmoothAMD
#extension GL_AMD_shader_explicit_vertex_parameter : enable
// AMD has a specific extension with a helpful intrinsic, but it's not necessary
#if AMD
#define BARYCENTRIC_STABILIZE 1
#define BARY_COORD gl_BaryCoordSmoothAMD
#extension GL_AMD_shader_explicit_vertex_parameter : enable
#else
#define BARYCENTRIC_STABILIZE 0
#define BARY_COORD gl_BaryCoordEXT
#extension GL_EXT_fragment_shader_barycentric : enable
#endif
#endif
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES];
@ -110,8 +115,11 @@ void main() {
outId = uvec2(triangleID + 1, instanceID + 1);
#if BARYCENTRIC && !BARYCENTRIC_CALCULATE
vec3 bary = vec3(gl_BaryCoordSmoothAMD.xy, 1 - gl_BaryCoordSmoothAMD.x - gl_BaryCoordSmoothAMD.y);
bary = bary.yzx;
vec3 bary = vec3(BARY_COORD.xy, 1 - BARY_COORD.x - BARY_COORD.y);
// AMD's barycentric emits a different order for coords
#if AMD
bary = bary.yzx;
#endif
#if BARYCENTRIC_STABILIZE
vec4 v0 = interpolateAtVertexAMD(inPOS1, 0);
vec4 v1 = interpolateAtVertexAMD(inPOS1, 1);

View File

@ -35,7 +35,7 @@ namespace {
vkGetPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
// Discrete GPUs have a significant performance advantage
if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) score += 1000;
if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) score += 1000000000000;
{
score += deviceProperties.limits.maxImageDimension1D;
score += deviceProperties.limits.maxImageDimension2D;

View File

@ -15,10 +15,9 @@
#include <uf/engine/graph/graph.h>
#include <uf/ext/ext.h>
// to-do: fix this
#define BARYCENTRIC 0
#define BARYCENTRIC 1
#if BARYCENTRIC
// agnostic for all devices, setting to 0 is only supported on AMD for little differences anyways
// 0 keeps a buffer for barycentric coordinates, 1 will reconstruct in the deferred pass
#ifndef BARYCENTRIC_CALCULATE
#define BARYCENTRIC_CALCULATE 1
#endif