removed storing model/prev-model matricies and color for every instance entry (by adding another indirection via objectID...), fixed rt pipeline because the BLAS's weren't being generated

This commit is contained in:
ecker 2025-08-21 22:54:49 -05:00
parent a099c562a2
commit 0fb2e3b750
25 changed files with 345 additions and 260 deletions

View File

@ -376,7 +376,7 @@ void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
#if BARYCENTRIC_CALCULATE #if BARYCENTRIC_CALCULATE
{ {
const vec3 p = vec3(inverse( surface.instance.model ) * vec4(surface.position.world, 1)); const vec3 p = vec3(inverse( surface.object.model ) * vec4(surface.position.world, 1));
const vec3 a = points[0].position; const vec3 a = points[0].position;
const vec3 b = points[1].position; const vec3 b = points[1].position;
@ -410,21 +410,21 @@ void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
// triangle.point.normal = triangle.geomNormal; // triangle.point.normal = triangle.geomNormal;
if ( triangle.point.tangent != vec3(0) ) { if ( triangle.point.tangent != vec3(0) ) {
surface.tangent.world = normalize(vec3( surface.instance.model * vec4(triangle.point.tangent, 0.0) )); surface.tangent.world = normalize(vec3( surface.object.model * vec4(triangle.point.tangent, 0.0) ));
vec3 bitangent = normalize(vec3( surface.instance.model * vec4(cross( triangle.point.normal, triangle.point.tangent ), 0.0) )); vec3 bitangent = normalize(vec3( surface.object.model * vec4(cross( triangle.point.normal, triangle.point.tangent ), 0.0) ));
surface.tbn = mat3(surface.tangent.world, bitangent, triangle.point.normal); surface.tbn = mat3(surface.tangent.world, bitangent, triangle.point.normal);
} }
// bind position (seems to muck with the skybox + fog) // bind position (seems to muck with the skybox + fog)
#if 0 && BARYCENTRIC_CALCULATE #if 0 && BARYCENTRIC_CALCULATE
{ {
surface.position.world = vec3( surface.instance.model * vec4(triangle.point.position, 1.0 ) ); surface.position.world = vec3( surface.object.model * vec4(triangle.point.position, 1.0 ) );
surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.position.world, 1.0) ); surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.position.world, 1.0) );
} }
#endif #endif
// bind normals // bind normals
{ {
surface.normal.world = normalize(vec3( surface.instance.model * vec4(triangle.point.normal, 0.0 ) )); surface.normal.world = normalize(vec3( surface.object.model * vec4(triangle.point.normal, 0.0 ) ));
// surface.normal.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) ); // surface.normal.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) );
} }
// bind UVs // bind UVs
@ -441,6 +441,7 @@ void populateSurface( uint instanceID, uint primitiveID ) {
surface.fragment = vec4(0); surface.fragment = vec4(0);
surface.light = vec4(0); surface.light = vec4(0);
surface.instance = instances[instanceID]; surface.instance = instances[instanceID];
surface.object = objects[surface.instance.objectID];
const InstanceAddresses instanceAddresses = instanceAddresses[instanceID]; const InstanceAddresses instanceAddresses = instanceAddresses[instanceID];
if ( !isValidAddress(instanceAddresses.index) ) return; if ( !isValidAddress(instanceAddresses.index) ) return;
@ -464,6 +465,7 @@ void populateSurface( RayTracePayload payload ) {
surface.fragment = vec4(0); surface.fragment = vec4(0);
surface.light = vec4(0); surface.light = vec4(0);
surface.instance = instances[payload.instanceID]; surface.instance = instances[payload.instanceID];
surface.object = objects[surface.instance.objectID];
if ( !payload.hit ) return; if ( !payload.hit ) return;
surface.barycentric = decodeBarycentrics(payload.attributes); surface.barycentric = decodeBarycentrics(payload.attributes);

View File

@ -100,11 +100,6 @@ struct Bounds {
}; };
struct Instance { struct Instance {
mat4 model;
mat4 previous;
vec4 color;
uint materialID; uint materialID;
uint primitiveID; uint primitiveID;
uint meshID; uint meshID;
@ -143,6 +138,13 @@ struct InstanceAddresses {
uint64_t padding1; uint64_t padding1;
}; };
struct Object {
mat4 model;
mat4 previous;
vec4 color;
};
struct SurfaceMaterial { struct SurfaceMaterial {
vec4 albedo; vec4 albedo;
vec4 indirect; vec4 indirect;
@ -170,6 +172,7 @@ struct Surface {
SurfaceMaterial material; SurfaceMaterial material;
Instance instance; Instance instance;
Object object;
vec4 light; vec4 light;
vec4 fragment; vec4 fragment;

View File

@ -77,33 +77,36 @@ layout (std140, binding = 12) readonly buffer Instances {
layout (std140, binding = 13) readonly buffer InstanceAddresseses { layout (std140, binding = 13) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[]; InstanceAddresses instanceAddresses[];
}; };
layout (std140, binding = 14) readonly buffer Materials { layout (std140, binding = 14) readonly buffer Objects {
Object objects[];
};
layout (std140, binding = 15) readonly buffer Materials {
Material materials[]; Material materials[];
}; };
layout (std140, binding = 15) readonly buffer Textures { layout (std140, binding = 16) readonly buffer Textures {
Texture textures[]; Texture textures[];
}; };
layout (std140, binding = 16) readonly buffer Lights { layout (std140, binding = 17) readonly buffer Lights {
Light lights[]; Light lights[];
}; };
layout (binding = 17) uniform sampler2D samplerTextures[TEXTURES]; layout (binding = 18) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 18) uniform samplerCube samplerCubemaps[CUBEMAPS]; layout (binding = 19) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 19) uniform sampler3D samplerNoise; layout (binding = 20) uniform sampler3D samplerNoise;
#if VXGI #if VXGI
layout (binding = 20) uniform usampler3D voxelDrawId[CASCADES]; layout (binding = 21) uniform usampler3D voxelDrawId[CASCADES];
layout (binding = 21) uniform usampler3D voxelInstanceId[CASCADES]; layout (binding = 22) uniform usampler3D voxelInstanceId[CASCADES];
layout (binding = 22) uniform sampler3D voxelNormalX[CASCADES]; layout (binding = 23) uniform sampler3D voxelNormalX[CASCADES];
layout (binding = 23) uniform sampler3D voxelNormalY[CASCADES]; layout (binding = 24) uniform sampler3D voxelNormalY[CASCADES];
layout (binding = 24) uniform sampler3D voxelRadianceR[CASCADES]; layout (binding = 25) uniform sampler3D voxelRadianceR[CASCADES];
layout (binding = 25) uniform sampler3D voxelRadianceG[CASCADES]; layout (binding = 26) uniform sampler3D voxelRadianceG[CASCADES];
layout (binding = 26) uniform sampler3D voxelRadianceB[CASCADES]; layout (binding = 27) uniform sampler3D voxelRadianceB[CASCADES];
layout (binding = 27) uniform sampler3D voxelRadianceA[CASCADES]; layout (binding = 28) uniform sampler3D voxelRadianceA[CASCADES];
layout (binding = 28) uniform sampler3D voxelCount[CASCADES]; layout (binding = 29) uniform sampler3D voxelCount[CASCADES];
layout (binding = 29) uniform sampler3D voxelOutput[CASCADES]; layout (binding = 30) uniform sampler3D voxelOutput[CASCADES];
#endif #endif
#if RT #if RT
layout (binding = 30) uniform accelerationStructureEXT tlas; layout (binding = 31) uniform accelerationStructureEXT tlas;
#endif #endif
#if BUFFER_REFERENCE #if BUFFER_REFERENCE
@ -262,14 +265,15 @@ void populateSurface() {
// surface.tangent.world = decodeNormals(normaltangent.zw); // surface.tangent.world = decodeNormals(normaltangent.zw);
surface.instance = instances[instanceID >= instances.length() ? 0 : instanceID]; surface.instance = instances[instanceID >= instances.length() ? 0 : instanceID];
surface.object = objects[surface.instance.objectID];
populateSurfaceMaterial(); populateSurfaceMaterial();
#endif #endif
} }
{ {
vec4 pNDC = ubo.eyes[surface.pass].previous * surface.instance.previous * vec4(surface.position.world, 1); vec4 pNDC = ubo.eyes[surface.pass].previous * surface.object.previous * vec4(surface.position.world, 1);
vec4 cNDC = ubo.eyes[surface.pass].model * surface.instance.model * vec4(surface.position.world, 1); vec4 cNDC = ubo.eyes[surface.pass].model * surface.object.model * vec4(surface.position.world, 1);
pNDC /= pNDC.w; pNDC /= pNDC.w;
cNDC /= cNDC.w; cNDC /= cNDC.w;

View File

@ -35,30 +35,33 @@ layout (std140, binding = 2) readonly buffer Instances {
layout (std140, binding = 3) readonly buffer InstanceAddresseses { layout (std140, binding = 3) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[]; InstanceAddresses instanceAddresses[];
}; };
layout (std140, binding = 4) readonly buffer Materials { layout (std140, binding = 4) readonly buffer Objects {
Object objects[];
};
layout (std140, binding = 5) readonly buffer Materials {
Material materials[]; Material materials[];
}; };
layout (std140, binding = 5) readonly buffer Textures { layout (std140, binding = 6) readonly buffer Textures {
Texture textures[]; Texture textures[];
}; };
layout (std140, binding = 6) readonly buffer Lights { layout (std140, binding = 7) readonly buffer Lights {
Light lights[]; Light lights[];
}; };
layout (binding = 7) uniform sampler2D samplerTextures[TEXTURES]; layout (binding = 8) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 8) uniform samplerCube samplerCubemaps[CUBEMAPS]; layout (binding = 9) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 9) uniform sampler3D samplerNoise; layout (binding = 10) uniform sampler3D samplerNoise;
layout (binding = 10, r32ui) uniform volatile coherent uimage3D voxelDrawId[CASCADES]; layout (binding = 11, r32ui) uniform volatile coherent uimage3D voxelDrawId[CASCADES];
layout (binding = 11, r32ui) uniform volatile coherent uimage3D voxelInstanceId[CASCADES]; layout (binding = 12, r32ui) uniform volatile coherent uimage3D voxelInstanceId[CASCADES];
layout (binding = 12, r32ui) uniform volatile coherent uimage3D voxelNormalX[CASCADES]; layout (binding = 13, r32ui) uniform volatile coherent uimage3D voxelNormalX[CASCADES];
layout (binding = 13, r32ui) uniform volatile coherent uimage3D voxelNormalY[CASCADES]; layout (binding = 14, r32ui) uniform volatile coherent uimage3D voxelNormalY[CASCADES];
layout (binding = 14, r32ui) uniform volatile coherent uimage3D voxelRadianceR[CASCADES]; layout (binding = 15, r32ui) uniform volatile coherent uimage3D voxelRadianceR[CASCADES];
layout (binding = 15, r32ui) uniform volatile coherent uimage3D voxelRadianceG[CASCADES]; layout (binding = 16, r32ui) uniform volatile coherent uimage3D voxelRadianceG[CASCADES];
layout (binding = 16, r32ui) uniform volatile coherent uimage3D voxelRadianceB[CASCADES]; layout (binding = 17, r32ui) uniform volatile coherent uimage3D voxelRadianceB[CASCADES];
layout (binding = 17, r32ui) uniform volatile coherent uimage3D voxelRadianceA[CASCADES]; layout (binding = 18, r32ui) uniform volatile coherent uimage3D voxelRadianceA[CASCADES];
layout (binding = 18, r32ui) uniform volatile coherent uimage3D voxelCount[CASCADES]; layout (binding = 19, r32ui) uniform volatile coherent uimage3D voxelCount[CASCADES];
layout (binding = 19, rgba8) uniform volatile coherent image3D voxelOutput[CASCADES]; layout (binding = 20, rgba8) uniform volatile coherent image3D voxelOutput[CASCADES];
#include "../../common/functions.h" #include "../../common/functions.h"
#include "../../common/light.h" #include "../../common/light.h"
@ -127,6 +130,7 @@ void main() {
const DrawCommand drawCommand = drawCommands[drawID]; const DrawCommand drawCommand = drawCommands[drawID];
surface.instance = instances[instanceID]; surface.instance = instances[instanceID];
surface.object = objects[surface.instance.objectID];
const Material material = materials[surface.instance.materialID]; const Material material = materials[surface.instance.materialID];
surface.material.albedo = material.colorBase; surface.material.albedo = material.colorBase;
surface.fragment = material.colorEmissive; surface.fragment = material.colorEmissive;

View File

@ -8,8 +8,8 @@ layout (constant_id = 0) const uint TEXTURES = 512;
layout (constant_id = 1) const uint CUBEMAPS = 128; layout (constant_id = 1) const uint CUBEMAPS = 128;
layout (constant_id = 2) const uint LAYERS = 32; layout (constant_id = 2) const uint LAYERS = 32;
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES]; layout (binding = 6) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 6) uniform samplerCube samplerCubemaps[CUBEMAPS]; layout (binding = 7) uniform samplerCube samplerCubemaps[CUBEMAPS];
#define SHADOW_SAMPLES 16 #define SHADOW_SAMPLES 16
#define FRAGMENT 1 #define FRAGMENT 1
@ -22,40 +22,40 @@ layout (binding = 6) uniform samplerCube samplerCubemaps[CUBEMAPS];
#include "../../common/macros.h" #include "../../common/macros.h"
#include "../../common/structs.h" #include "../../common/structs.h"
layout (binding = 7) uniform Camera { layout (binding = 8) uniform Camera {
Viewport viewport[6]; Viewport viewport[6];
} camera; } camera;
layout (binding = 8) uniform UBO { layout (binding = 9) uniform UBO {
uint lights; uint lights;
uint currentID; uint currentID;
uint padding1; uint padding1;
uint padding2; uint padding2;
} ubo; } ubo;
layout (std140, binding = 9) readonly buffer DrawCommands { layout (std140, binding = 10) readonly buffer DrawCommands {
DrawCommand drawCommands[]; DrawCommand drawCommands[];
}; };
layout (std140, binding = 10) readonly buffer Instances { layout (std140, binding = 11) readonly buffer Instances {
Instance instances[]; Instance instances[];
}; };
layout (std140, binding = 11) readonly buffer InstanceAddresseses { layout (std140, binding = 12) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[]; InstanceAddresses instanceAddresses[];
}; };
layout (std140, binding = 12) readonly buffer Materials { layout (std140, binding = 13) readonly buffer Materials {
Material materials[]; Material materials[];
}; };
layout (std140, binding = 13) readonly buffer Textures { layout (std140, binding = 14) readonly buffer Textures {
Texture textures[]; Texture textures[];
}; };
layout (std140, binding = 14) readonly buffer Lights { layout (std140, binding = 15) readonly buffer Lights {
Light lights[]; Light lights[];
}; };
layout (binding = 15, rgba8) uniform volatile coherent image3D outAlbedos; layout (binding = 16, rgba8) uniform volatile coherent image3D outAlbedos;
#if RT #if RT
layout (binding = 16) uniform accelerationStructureEXT tlas; layout (binding = 17) uniform accelerationStructureEXT tlas;
#endif #endif
#include "../../common/functions.h" #include "../../common/functions.h"

View File

@ -27,23 +27,23 @@ layout (constant_id = 0) const uint TEXTURES = 1;
#endif #endif
#endif #endif
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES]; layout (binding = 6) uniform sampler2D samplerTextures[TEXTURES];
layout (std140, binding = 6) readonly buffer DrawCommands { layout (std140, binding = 7) readonly buffer DrawCommands {
DrawCommand drawCommands[]; DrawCommand drawCommands[];
}; };
layout (std140, binding = 7) readonly buffer Instances { layout (std140, binding = 8) readonly buffer Instances {
Instance instances[]; Instance instances[];
}; };
layout (std140, binding = 8) readonly buffer InstanceAddresseses { layout (std140, binding = 9) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[]; InstanceAddresses instanceAddresses[];
}; };
layout (std140, binding = 9) readonly buffer Materials { layout (std140, binding = 10) readonly buffer Materials {
Material materials[]; Material materials[];
}; };
layout (std140, binding = 10) readonly buffer Textures { layout (std140, binding = 11) readonly buffer Textures {
Texture textures[]; Texture textures[];
}; };
layout (std140, binding = 11) readonly buffer Lights { layout (std140, binding = 12) readonly buffer Lights {
Light lights[]; Light lights[];
}; };

View File

@ -32,9 +32,12 @@ layout (std140, binding = 1) readonly buffer DrawCommands {
layout (std140, binding = 2) readonly buffer Instances { layout (std140, binding = 2) readonly buffer Instances {
Instance instances[]; Instance instances[];
}; };
layout (std140, binding = 3) readonly buffer Objects {
Object objects[];
};
#if SKINNED #if SKINNED
layout (std140, binding = 3) readonly buffer Joints { layout (std140, binding = 4) readonly buffer Joints {
mat4 joints[]; mat4 joints[];
}; };
#endif #endif
@ -63,6 +66,7 @@ void main() {
const DrawCommand drawCommand = drawCommands[drawID]; const DrawCommand drawCommand = drawCommands[drawID];
const uint instanceID = drawCommand.instanceID; // gl_InstanceIndex; const uint instanceID = drawCommand.instanceID; // gl_InstanceIndex;
const Instance instance = instances[instanceID]; const Instance instance = instances[instanceID];
const Object object = objects[instance.objectID];
const uint jointID = instance.jointID; const uint jointID = instance.jointID;
#if BAKING #if BAKING
@ -77,8 +81,8 @@ void main() {
#else #else
const mat4 skinned = mat4(1.0); const mat4 skinned = mat4(1.0);
#endif #endif
const mat4 model = instances.length() <= 0 ? skinned : (instance.model * skinned); const mat4 model = instances.length() <= 0 ? skinned : (object.model * skinned);
// const mat4 model = instance.model * skinned; // const mat4 model = object.model * skinned;
#if BAKING #if BAKING
@ -94,7 +98,7 @@ void main() {
outPosition = vec3(model * vec4(inPos.xyz, 1.0)); outPosition = vec3(model * vec4(inPos.xyz, 1.0));
outUv = inUv; outUv = inUv;
outSt = inSt; outSt = inSt;
outColor = inColor * instance.color; outColor = inColor * object.color;
outNormal = normalize(vec3(model * vec4(inNormal.xyz, 0.0))); outNormal = normalize(vec3(model * vec4(inNormal.xyz, 0.0)));
outTangent = normalize(vec3(view * model * vec4(inTangent.xyz, 0.0))); outTangent = normalize(vec3(view * model * vec4(inTangent.xyz, 0.0)));
} }

View File

@ -67,7 +67,11 @@ layout (std140, binding = 2) buffer Instances {
Instance instances[]; Instance instances[];
}; };
layout (binding = 3) uniform sampler2D samplerDepth; layout (std140, binding = 3) buffer Objects {
Object objects[];
};
layout (binding = 4) uniform sampler2D samplerDepth;
struct Frustum { struct Frustum {
vec4 planes[6]; vec4 planes[6];
@ -82,6 +86,7 @@ bool frustumCull( uint id ) {
const DrawCommand drawCommand = drawCommands[id]; const DrawCommand drawCommand = drawCommands[id];
const Instance instance = instances[drawCommand.instanceID]; const Instance instance = instances[drawCommand.instanceID];
const Object object = objects[instance.objectID];
if ( drawCommand.indices == 0 || drawCommand.vertices == 0 ) return false; if ( drawCommand.indices == 0 || drawCommand.vertices == 0 ) return false;
@ -89,9 +94,9 @@ bool frustumCull( uint id ) {
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) { for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
#if 0 #if 0
vec4 sphere = aabbToSphere( instance.bounds ); vec4 sphere = aabbToSphere( instance.bounds );
vec3 center = vec3( camera.viewport[pass].view * instance.model * vec4( ) ); vec3 center = vec3( camera.viewport[pass].view * object.model * vec4( ) );
#else #else
mat4 mat = camera.viewport[pass].projection * camera.viewport[pass].view * instance.model; mat4 mat = camera.viewport[pass].projection * camera.viewport[pass].view * object.model;
#if 1 #if 1
vec4 planes[6]; { vec4 planes[6]; {
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
@ -154,14 +159,15 @@ bool occlusionCull( uint id ) {
const DrawCommand drawCommand = drawCommands[id]; const DrawCommand drawCommand = drawCommands[id];
const Instance instance = instances[drawCommand.instanceID]; const Instance instance = instances[drawCommand.instanceID];
const Object object = objects[instance.objectID];
bool visible = true; bool visible = true;
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) { for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
#if 1 #if 1
vec4 aabb; vec4 aabb;
vec4 sphere = aabbToSphere( instance.bounds ); vec4 sphere = aabbToSphere( instance.bounds );
vec3 center = (camera.viewport[pass].view * instance.model * vec4(sphere.xyz, 1)).xyz; vec3 center = (camera.viewport[pass].view * object.model * vec4(sphere.xyz, 1)).xyz;
float radius = (instance.model * vec4(sphere.w, 0, 0, 0)).x; float radius = (object.model * vec4(sphere.w, 0, 0, 0)).x;
// center.y *= -1; // center.y *= -1;
mat4 proj = camera.viewport[pass].projection; mat4 proj = camera.viewport[pass].projection;
float znear = proj[3][2]; float znear = proj[3][2];
@ -193,7 +199,7 @@ bool occlusionCull( uint id ) {
} }
#else #else
mat4 mat = camera.viewport[pass].projection * camera.viewport[pass].view * instance.model; mat4 mat = camera.viewport[pass].projection * camera.viewport[pass].view * object.model;
vec3 boundsSize = instance.bounds.max - instance.bounds.min; vec3 boundsSize = instance.bounds.max - instance.bounds.min;
vec3 points[8] = { vec3 points[8] = {
instance.bounds.min.xyz, instance.bounds.min.xyz,

View File

@ -9,23 +9,23 @@ layout (constant_id = 0) const uint TEXTURES = 1;
#include "../../common/macros.h" #include "../../common/macros.h"
#include "../../common/structs.h" #include "../../common/structs.h"
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES]; layout (binding = 6) uniform sampler2D samplerTextures[TEXTURES];
layout (std140, binding = 6) readonly buffer DrawCommands { layout (std140, binding = 7) readonly buffer DrawCommands {
DrawCommand drawCommands[]; DrawCommand drawCommands[];
}; };
layout (std140, binding = 7) readonly buffer Instances { layout (std140, binding = 8) readonly buffer Instances {
Instance instances[]; Instance instances[];
}; };
layout (std140, binding = 8) readonly buffer InstanceAddresseses { layout (std140, binding = 9) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[]; InstanceAddresses instanceAddresses[];
}; };
layout (std140, binding = 9) readonly buffer Materials { layout (std140, binding = 10) readonly buffer Materials {
Material materials[]; Material materials[];
}; };
layout (std140, binding = 10) readonly buffer Textures { layout (std140, binding = 11) readonly buffer Textures {
Texture textures[]; Texture textures[];
}; };
layout (std140, binding = 11) readonly buffer Lights { layout (std140, binding = 12) readonly buffer Lights {
Light lights[]; Light lights[];
}; };

View File

@ -16,37 +16,37 @@ layout (constant_id = 1) const uint CASCADES = 16;
#include "../../common/macros.h" #include "../../common/macros.h"
#include "../../common/structs.h" #include "../../common/structs.h"
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES]; layout (binding = 6) uniform sampler2D samplerTextures[TEXTURES];
layout (std140, binding = 6) readonly buffer DrawCommands { layout (std140, binding = 7) readonly buffer DrawCommands {
DrawCommand drawCommands[]; DrawCommand drawCommands[];
}; };
layout (std140, binding = 7) readonly buffer Instances { layout (std140, binding = 8) readonly buffer Instances {
Instance instances[]; Instance instances[];
}; };
layout (std140, binding = 8) readonly buffer InstanceAddresseses { layout (std140, binding = 9) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[]; InstanceAddresses instanceAddresses[];
}; };
layout (std140, binding = 9) readonly buffer Materials { layout (std140, binding = 10) readonly buffer Materials {
Material materials[]; Material materials[];
}; };
layout (std140, binding = 10) readonly buffer Textures { layout (std140, binding = 11) readonly buffer Textures {
Texture textures[]; Texture textures[];
}; };
layout (std140, binding = 11) readonly buffer Lights { layout (std140, binding = 12) readonly buffer Lights {
Light lights[]; Light lights[];
}; };
layout (binding = 12, r32ui) uniform volatile coherent uimage3D voxelDrawId[CASCADES]; layout (binding = 13, r32ui) uniform volatile coherent uimage3D voxelDrawId[CASCADES];
layout (binding = 13, r32ui) uniform volatile coherent uimage3D voxelInstanceId[CASCADES]; layout (binding = 14, r32ui) uniform volatile coherent uimage3D voxelInstanceId[CASCADES];
layout (binding = 14, r32ui) uniform volatile coherent uimage3D voxelNormalX[CASCADES]; layout (binding = 15, r32ui) uniform volatile coherent uimage3D voxelNormalX[CASCADES];
layout (binding = 15, r32ui) uniform volatile coherent uimage3D voxelNormalY[CASCADES]; layout (binding = 16, r32ui) uniform volatile coherent uimage3D voxelNormalY[CASCADES];
layout (binding = 16, r32ui) uniform volatile coherent uimage3D voxelRadianceR[CASCADES]; layout (binding = 17, r32ui) uniform volatile coherent uimage3D voxelRadianceR[CASCADES];
layout (binding = 17, r32ui) uniform volatile coherent uimage3D voxelRadianceG[CASCADES]; layout (binding = 18, r32ui) uniform volatile coherent uimage3D voxelRadianceG[CASCADES];
layout (binding = 18, r32ui) uniform volatile coherent uimage3D voxelRadianceB[CASCADES]; layout (binding = 19, r32ui) uniform volatile coherent uimage3D voxelRadianceB[CASCADES];
layout (binding = 19, r32ui) uniform volatile coherent uimage3D voxelRadianceA[CASCADES]; layout (binding = 20, r32ui) uniform volatile coherent uimage3D voxelRadianceA[CASCADES];
layout (binding = 20, r32ui) uniform volatile coherent uimage3D voxelCount[CASCADES]; layout (binding = 21, r32ui) uniform volatile coherent uimage3D voxelCount[CASCADES];
layout (binding = 21, rgba8) uniform volatile coherent image3D voxelOutput[CASCADES]; layout (binding = 22, rgba8) uniform volatile coherent image3D voxelOutput[CASCADES];
layout (location = 0) flat in uvec4 inId; layout (location = 0) flat in uvec4 inId;
layout (location = 1) flat in vec4 inPOS0; layout (location = 1) flat in vec4 inPOS0;

View File

@ -24,7 +24,7 @@ layout (location = 6) out vec2 outSt;
layout (location = 7) out vec3 outNormal; layout (location = 7) out vec3 outNormal;
layout (location = 8) out vec3 outTangent; layout (location = 8) out vec3 outTangent;
layout (binding = 4) uniform UBO { layout (binding = 5) uniform UBO {
mat4 voxel; mat4 voxel;
float cascadePower; float cascadePower;

View File

@ -46,23 +46,26 @@ layout (std140, binding = 3) readonly buffer Instances {
layout (std140, binding = 4) readonly buffer InstanceAddresseses { layout (std140, binding = 4) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[]; InstanceAddresses instanceAddresses[];
}; };
layout (std140, binding = 5) readonly buffer Materials { layout (std140, binding = 5) readonly buffer Objects {
Object objects[];
};
layout (std140, binding = 6) readonly buffer Materials {
Material materials[]; Material materials[];
}; };
layout (std140, binding = 6) readonly buffer Textures { layout (std140, binding = 7) readonly buffer Textures {
Texture textures[]; Texture textures[];
}; };
layout (std140, binding = 7) readonly buffer Lights { layout (std140, binding = 8) readonly buffer Lights {
Light lights[]; Light lights[];
}; };
layout (binding = 8) uniform sampler2D samplerTextures[TEXTURES]; layout (binding = 9) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 9) uniform samplerCube samplerCubemaps[CUBEMAPS]; layout (binding = 10) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 10) uniform sampler3D samplerNoise; layout (binding = 11) uniform sampler3D samplerNoise;
#if VXGI #if VXGI
layout (binding = 11) uniform usampler3D voxelId[CASCADES]; layout (binding = 12) uniform usampler3D voxelId[CASCADES];
layout (binding = 12) uniform sampler3D voxelNormal[CASCADES]; layout (binding = 13) uniform sampler3D voxelNormal[CASCADES];
layout (binding = 13) uniform sampler3D voxelRadiance[CASCADES]; layout (binding = 14) uniform sampler3D voxelRadiance[CASCADES];
#endif #endif
layout (location = 0) rayPayloadEXT RayTracePayload payload; layout (location = 0) rayPayloadEXT RayTracePayload payload;

View File

@ -1 +1 @@
opengl vulkan

View File

@ -93,6 +93,7 @@ namespace pod {
// maps without direct analogues // maps without direct analogues
uf::stl::KeyMap<uf::Atlas> atlases; uf::stl::KeyMap<uf::Atlas> atlases;
uf::stl::KeyMap<pod::Instance::Object> objects;
uf::stl::KeyMap<uf::stl::vector<pod::Matrix4f>> joints; uf::stl::KeyMap<uf::stl::vector<pod::Matrix4f>> joints;
uf::stl::KeyMap<uf::renderer::Texture2D> texture2Ds; uf::stl::KeyMap<uf::renderer::Texture2D> texture2Ds;
uf::stl::KeyMap<uf::Entity*> entities; uf::stl::KeyMap<uf::Entity*> entities;
@ -106,6 +107,7 @@ namespace pod {
uf::renderer::Buffer instance; uf::renderer::Buffer instance;
uf::renderer::Buffer instanceAddresses; uf::renderer::Buffer instanceAddresses;
uf::renderer::Buffer joint; uf::renderer::Buffer joint;
uf::renderer::Buffer object;
uf::renderer::Buffer material; uf::renderer::Buffer material;
uf::renderer::Buffer texture; uf::renderer::Buffer texture;
uf::renderer::Buffer light; uf::renderer::Buffer light;

View File

@ -88,6 +88,7 @@ namespace pod {
int32_t parent = -1; int32_t parent = -1;
int32_t mesh = -1; int32_t mesh = -1;
int32_t skin = -1; int32_t skin = -1;
int32_t object = -1;
uf::stl::vector<int32_t> children; uf::stl::vector<int32_t> children;
uf::Object* entity = NULL; uf::Object* entity = NULL;

View File

@ -100,7 +100,7 @@ namespace ext {
bool updateMesh( uf::Mesh& mesh ); bool updateMesh( uf::Mesh& mesh );
// raytrace // raytrace
void generateBottomAccelerationStructures(); void generateBottomAccelerationStructures();
void generateTopAccelerationStructure( const uf::stl::vector<uf::renderer::Graphic*>&, const uf::stl::vector<pod::Instance>& ); void generateTopAccelerationStructure( const uf::stl::vector<uf::renderer::Graphic*>&, const uf::stl::vector<pod::Instance>&, const uf::stl::vector<pod::Matrix4f>& );
bool hasPipeline( const GraphicDescriptor& descriptor ) const; bool hasPipeline( const GraphicDescriptor& descriptor ) const;
void initializePipeline(); void initializePipeline();

View File

@ -77,16 +77,10 @@ namespace pod {
// stores information about how to transform a draw call // stores information about how to transform a draw call
// to-do: clean up this mess // to-do: clean up this mess
struct UF_API Instance { struct UF_API Instance {
// these could easily be tied to objectID
pod::Matrix4f model; // current model matrix
pod::Matrix4f previous; // previous model matrix, used for the "motion" output
pod::Vector4f color = {1,1,1,1}; // additional color information
alignas(4) uint32_t materialID = 0; // index for material information alignas(4) uint32_t materialID = 0; // index for material information
alignas(4) uint32_t primitiveID = 0; // index to reference the primitive(?) alignas(4) uint32_t primitiveID = 0; // index to reference the primitive(?)
alignas(4) uint32_t meshID = 0; // unused alignas(4) uint32_t meshID = 0; // unused
alignas(4) uint32_t objectID = 0; // unused alignas(4) uint32_t objectID = 0; // index for the object buffer
alignas(4) int32_t jointID = -1; // offset for skins(?) alignas(4) int32_t jointID = -1; // offset for skins(?)
alignas(4) int32_t lightmapID = -1; // index for lightmap to use alignas(4) int32_t lightmapID = -1; // index for lightmap to use
@ -126,6 +120,13 @@ namespace pod {
alignas(8) uint64_t id{}; alignas(8) uint64_t id{};
alignas(8) uint64_t padding1{}; alignas(8) uint64_t padding1{};
}; };
struct UF_API Object {
pod::Matrix4f model;
pod::Matrix4f previous;
pod::Vector4f color = { 1, 1, 1, 1 };
};
// Addresses addresses = {}; // Addresses addresses = {};
}; };

View File

@ -94,8 +94,9 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
} else return; } else return;
} }
static uf::stl::vector<pod::Instance> previousInstances;
uf::stl::vector<pod::Instance> instances; instances.reserve(storage.primitives.map.size()); uf::stl::vector<pod::Instance> instances; instances.reserve(storage.primitives.map.size());
uf::stl::vector<pod::Matrix4f> models; models.reserve(storage.objects.map.size());
for ( auto& key : storage.primitives.keys ) { for ( auto& key : storage.primitives.keys ) {
for ( auto& primitive : storage.primitives.map[key] ) { for ( auto& primitive : storage.primitives.map[key] ) {
instances.emplace_back( primitive.instance ); instances.emplace_back( primitive.instance );
@ -103,6 +104,12 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
} }
if ( instances.empty() ) return; if ( instances.empty() ) return;
for ( auto& key : storage.objects.keys ) {
models.emplace_back( storage.objects.map[key].model );
}
if ( models.empty() ) return;
static uf::stl::vector<pod::Matrix4f> previousModels;
static uf::stl::vector<uf::Graphic*> previousGraphics; static uf::stl::vector<uf::Graphic*> previousGraphics;
static uf::stl::vector<uf::renderer::AccelerationStructure> previousBlases; static uf::stl::vector<uf::renderer::AccelerationStructure> previousBlases;
@ -130,28 +137,30 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
} }
update = true; update = true;
} else if ( !update ) { } else if ( !update ) {
if ( previousInstances.size() != instances.size() ) update = true; if ( previousModels.size() != models.size() ) update = true;
else if ( previousGraphics.size() != graphics.size() ) update = true; else if ( previousGraphics.size() != graphics.size() ) update = true;
else if ( previousBlases.size() != blases.size() ) update = true; else if ( previousBlases.size() != blases.size() ) update = true;
// else if ( memcmp( previousInstances.data(), instances.data(), instances.size() * sizeof(decltype(instances)::value_type) ) != 0 ) update = true; else if ( memcmp( previousModels.data(), models.data(), models.size() * sizeof(pod::Instance::Object) ) != 0 ) update = true;
else if ( memcmp( previousGraphics.data(), graphics.data(), graphics.size() * sizeof(decltype(graphics)::value_type) ) != 0 ) update = true; else if ( memcmp( previousGraphics.data(), graphics.data(), graphics.size() * sizeof(decltype(graphics)::value_type) ) != 0 ) update = true;
else if ( memcmp( previousBlases.data(), blases.data(), blases.size() * sizeof(decltype(blases)::value_type) ) != 0 ) update = true; else if ( memcmp( previousBlases.data(), blases.data(), blases.size() * sizeof(decltype(blases)::value_type) ) != 0 ) update = true;
else for ( size_t i = 0; i < instances.size() && !update; ++i ) { /*
if ( !uf::matrix::equals( instances[i].model, previousInstances[i].model, 0.0001f ) ) else for ( size_t i = 0; i < models.size() && !update; ++i ) {
if ( !uf::matrix::equals( models[i], previousModels[i], 0.0001f ) )
update = true; update = true;
} }
*/
} }
if ( update ) { if ( update ) {
for ( auto* graphic : graphics ) { for ( auto* graphic : graphics ) {
if ( graphic->metadata.buffers.count("vertexSkinned") > 0 ) graphic->generateBottomAccelerationStructures(); if ( graphic->metadata.buffers.count("vertexSkinned") > 0 ) graphic->generateBottomAccelerationStructures();
} }
graphic.generateTopAccelerationStructure( graphics, instances ); graphic.generateTopAccelerationStructure( graphics, instances, models );
auto& sceneMetadata = this->getComponent<ext::ExtSceneBehavior::Metadata>(); auto& sceneMetadata = this->getComponent<ext::ExtSceneBehavior::Metadata>();
sceneMetadata.shader.frameAccumulateReset = true; sceneMetadata.shader.frameAccumulateReset = true;
uf::renderer::states::frameAccumulateReset = true; uf::renderer::states::frameAccumulateReset = true;
previousInstances = instances; previousModels = models;
previousGraphics = graphics; previousGraphics = graphics;
previousBlases = blases; previousBlases = blases;
} }
@ -201,11 +210,12 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
size_t maxTextures3D = uf::config["engine"]["scenes"]["textures"]["max"]["3D"].as<size_t>(1); size_t maxTextures3D = uf::config["engine"]["scenes"]["textures"]["max"]["3D"].as<size_t>(1);
size_t maxCascades = uf::config["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(16); size_t maxCascades = uf::config["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(16);
shader.buffers.emplace_back( storage.buffers.instance.alias() ); shader.aliasBuffer( storage.buffers.instance );
shader.buffers.emplace_back( storage.buffers.instanceAddresses.alias() ); shader.aliasBuffer( storage.buffers.instanceAddresses );
shader.buffers.emplace_back( storage.buffers.material.alias() ); shader.aliasBuffer( storage.buffers.object );
shader.buffers.emplace_back( storage.buffers.texture.alias() ); shader.aliasBuffer( storage.buffers.material );
shader.buffers.emplace_back( storage.buffers.light.alias() ); shader.aliasBuffer( storage.buffers.texture );
shader.aliasBuffer( storage.buffers.light );
shader.setSpecializationConstants({ shader.setSpecializationConstants({
{ "TEXTURES", maxTextures2D }, { "TEXTURES", maxTextures2D },

View File

@ -159,8 +159,8 @@ namespace {
pod::Instance decodeInstance( ext::json::Value& json, pod::Graph& graph ) { pod::Instance decodeInstance( ext::json::Value& json, pod::Graph& graph ) {
pod::Instance instance; pod::Instance instance;
instance.model = uf::matrix::decode( json["model"], instance.model ); //instance.model = uf::matrix::decode( json["model"], instance.model );
instance.color = uf::vector::decode( json["color"], instance.color ); //instance.color = uf::vector::decode( json["color"], instance.color );
instance.materialID = json["materialID"].as( instance.materialID ); instance.materialID = json["materialID"].as( instance.materialID );
instance.primitiveID = json["primitiveID"].as( instance.primitiveID ); instance.primitiveID = json["primitiveID"].as( instance.primitiveID );
instance.meshID = json["meshID"].as( instance.meshID ); instance.meshID = json["meshID"].as( instance.meshID );

View File

@ -110,8 +110,8 @@ namespace {
} }
uf::Serializer encode( const pod::Instance& instance, const EncodingSettings& settings, const pod::Graph& graph ) { uf::Serializer encode( const pod::Instance& instance, const EncodingSettings& settings, const pod::Graph& graph ) {
uf::Serializer json; uf::Serializer json;
json["model"] = uf::matrix::encode( instance.model, settings ); // json["model"] = uf::matrix::encode( instance.model, settings );
json["color"] = uf::vector::encode( instance.color, settings ); // json["color"] = uf::vector::encode( instance.color, settings );
json["materialID"] = instance.materialID; json["materialID"] = instance.materialID;
json["primitiveID"] = instance.primitiveID; json["primitiveID"] = instance.primitiveID;
json["meshID"] = instance.meshID; json["meshID"] = instance.meshID;

View File

@ -44,6 +44,13 @@ namespace {
return hash; return hash;
} }
uf::stl::string objectKey( pod::Node& node ){
return std::to_string(node.object);
}
uf::stl::string instanceKey( uint32_t instanceID ) {
return std::to_string( instanceID );
}
pod::Graph::Storage& getGraphStorage( uf::Object& object ) { pod::Graph::Storage& getGraphStorage( uf::Object& object ) {
return uf::graph::globalStorage ? uf::graph::storage : object.getComponent<pod::Graph::Storage>(); return uf::graph::globalStorage ? uf::graph::storage : object.getComponent<pod::Graph::Storage>();
} }
@ -283,113 +290,116 @@ namespace {
// rt pipeline // rt pipeline
// to-do: segregate out buffer updating code // to-do: segregate out buffer updating code
if ( uf::renderer::settings::pipelines::rt && mesh.vertex.count && graphMetadataJson["renderer"]["skinned"].as<bool>() ) { if ( uf::renderer::settings::pipelines::rt && mesh.vertex.count ) {
struct PushConstant { if ( graphMetadataJson["renderer"]["skinned"].as<bool>() ) {
uint32_t jointID; struct PushConstant {
}; uint32_t jointID;
};
if ( mesh.isInterleaved( mesh.vertex ) ) { if ( mesh.isInterleaved( mesh.vertex ) ) {
uf::stl::string compShaderFilename = graphMetadataJson["shaders"]["skinning"]["compute"].as<uf::stl::string>("/graph/skinning/skinning.interleaved.comp.spv"); { uf::stl::string compShaderFilename = graphMetadataJson["shaders"]["skinning"]["compute"].as<uf::stl::string>("/graph/skinning/skinning.interleaved.comp.spv"); {
compShaderFilename = entity.resolveURI( compShaderFilename, root ); compShaderFilename = entity.resolveURI( compShaderFilename, root );
} }
graphic.material.metadata.autoInitializeUniformBuffers = false; graphic.material.metadata.autoInitializeUniformBuffers = false;
graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, "skinning"); graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, "skinning");
graphic.material.metadata.autoInitializeUniformBuffers = true; graphic.material.metadata.autoInitializeUniformBuffers = true;
graphic.descriptor.bind.width = mesh.vertex.count;
graphic.descriptor.bind.height = 1;
graphic.descriptor.bind.depth = 1;
// compute shader
auto& shader = graphic.material.getShader("compute", "skinning");
// bind buffers
struct {
uint32_t jointID;
} uniforms = {
.jointID = 0
};
auto& vertexSourceData = mesh.buffers[mesh.vertex.interleaved];
size_t vertexSourceDataIndex = graphic.initializeBuffer( (const void*) vertexSourceData.data(), vertexSourceData.size(), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR );
auto& vertexIn = graphic.buffers.at(graphic.descriptor.inputs.vertex.interleaved);
auto& vertexOut = graphic.buffers.at(vertexSourceDataIndex);
graphic.metadata.buffers["vertexSkinned"] = vertexSourceDataIndex;
shader.updateBuffer( (const void*) &uniforms, sizeof(uniforms), shader.getUniformBuffer("UBO") );
::resetBuffers( shader );
shader.aliasBuffer( storage.buffers.joint );
shader.aliasBuffer( vertexIn );
shader.aliasBuffer( vertexOut );
} else {
uf::stl::string compShaderFilename = graphMetadataJson["shaders"]["skinning"]["compute"].as<uf::stl::string>("/graph/skinning/skinning.deinterleaved.comp.spv"); {
compShaderFilename = entity.resolveURI( compShaderFilename, root );
}
graphic.descriptor.bind.width = mesh.vertex.count; // graphic.material.metadata.autoInitializeUniformBuffers = false;
graphic.descriptor.bind.height = 1; graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, "skinning");
graphic.descriptor.bind.depth = 1; // graphic.material.metadata.autoInitializeUniformBuffers = true;
graphic.descriptor.bind.width = mesh.vertex.count;
graphic.descriptor.bind.height = 1;
graphic.descriptor.bind.depth = 1;
// compute shader uf::Mesh::Attribute vertexPos;
auto& shader = graphic.material.getShader("compute", "skinning"); uf::Mesh::Attribute vertexJoints;
uf::Mesh::Attribute vertexWeights;
// bind buffers size_t vertexPosIndex = 0;
struct { size_t vertexJointsIndex = 0;
uint32_t jointID; size_t vertexWeightsIndex = 0;
} uniforms = {
.jointID = 0
};
auto& vertexSourceData = mesh.buffers[mesh.vertex.interleaved]; for ( size_t i = 0; i < graphic.descriptor.inputs.vertex.attributes.size(); ++i ) {
size_t vertexSourceDataIndex = graphic.initializeBuffer( (const void*) vertexSourceData.data(), vertexSourceData.size(), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR ); auto& attribute = graphic.descriptor.inputs.vertex.attributes[i];
auto& vertexIn = graphic.buffers.at(graphic.descriptor.inputs.vertex.interleaved); if ( attribute.buffer < 0 ) continue;
auto& vertexOut = graphic.buffers.at(vertexSourceDataIndex); if ( attribute.descriptor.name == "position" ) {
graphic.metadata.buffers["vertexSkinned"] = vertexSourceDataIndex; vertexPos = attribute;
vertexPosIndex = graphic.metadata.buffers["vertex[position]"];
}
else if ( attribute.descriptor.name == "joints" ) {
vertexJoints = attribute;
vertexJointsIndex = graphic.metadata.buffers["vertex[joints]"];
}
else if ( attribute.descriptor.name == "weights" ) {
vertexWeights = attribute;
vertexWeightsIndex = graphic.metadata.buffers["vertex[weights]"];
}
}
shader.updateBuffer( (const void*) &uniforms, sizeof(uniforms), shader.getUniformBuffer("UBO") ); auto& vertexSourceData = mesh.buffers[vertexPos.buffer];
size_t vertexSourceDataIndex = graphic.initializeBuffer( (const void*) vertexSourceData.data(), vertexSourceData.size(), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR );
::resetBuffers( shader ); auto& vertexPositionBuffer = graphic.buffers.at(vertexPosIndex);
shader.aliasBuffer( storage.buffers.joint ); auto& vertexJointsBuffer = graphic.buffers.at(vertexJointsIndex);
shader.aliasBuffer( vertexIn ); auto& vertexWeightsBuffer = graphic.buffers.at(vertexWeightsIndex);
shader.aliasBuffer( vertexOut );
} else { auto& vertexOutPosition = graphic.buffers.at(vertexSourceDataIndex);
uf::stl::string compShaderFilename = graphMetadataJson["shaders"]["skinning"]["compute"].as<uf::stl::string>("/graph/skinning/skinning.deinterleaved.comp.spv"); { graphic.metadata.buffers["vertexSkinned"] = vertexSourceDataIndex;
compShaderFilename = entity.resolveURI( compShaderFilename, root );
auto& shader = graphic.material.getShader("compute", "skinning");
struct {
uint32_t jointID;
} uniforms = {
.jointID = 0
};
shader.updateBuffer( (const void*) &uniforms, sizeof(uniforms), shader.getUniformBuffer("UBO") );
// bind buffers
::resetBuffers( shader );
shader.aliasBuffer( storage.buffers.joint );
shader.aliasBuffer( vertexPositionBuffer );
shader.aliasBuffer( vertexJointsBuffer );
shader.aliasBuffer( vertexWeightsBuffer );
shader.aliasBuffer( vertexOutPosition );
} }
// graphic.material.metadata.autoInitializeUniformBuffers = false;
graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, "skinning");
// graphic.material.metadata.autoInitializeUniformBuffers = true;
graphic.descriptor.bind.width = mesh.vertex.count;
graphic.descriptor.bind.height = 1;
graphic.descriptor.bind.depth = 1;
uf::Mesh::Attribute vertexPos;
uf::Mesh::Attribute vertexJoints;
uf::Mesh::Attribute vertexWeights;
size_t vertexPosIndex = 0;
size_t vertexJointsIndex = 0;
size_t vertexWeightsIndex = 0;
for ( size_t i = 0; i < graphic.descriptor.inputs.vertex.attributes.size(); ++i ) {
auto& attribute = graphic.descriptor.inputs.vertex.attributes[i];
if ( attribute.buffer < 0 ) continue;
if ( attribute.descriptor.name == "position" ) {
vertexPos = attribute;
vertexPosIndex = graphic.metadata.buffers["vertex[position]"];
}
else if ( attribute.descriptor.name == "joints" ) {
vertexJoints = attribute;
vertexJointsIndex = graphic.metadata.buffers["vertex[joints]"];
}
else if ( attribute.descriptor.name == "weights" ) {
vertexWeights = attribute;
vertexWeightsIndex = graphic.metadata.buffers["vertex[weights]"];
}
}
auto& vertexSourceData = mesh.buffers[vertexPos.buffer];
size_t vertexSourceDataIndex = graphic.initializeBuffer( (const void*) vertexSourceData.data(), vertexSourceData.size(), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR );
auto& vertexPositionBuffer = graphic.buffers.at(vertexPosIndex);
auto& vertexJointsBuffer = graphic.buffers.at(vertexJointsIndex);
auto& vertexWeightsBuffer = graphic.buffers.at(vertexWeightsIndex);
auto& vertexOutPosition = graphic.buffers.at(vertexSourceDataIndex);
graphic.metadata.buffers["vertexSkinned"] = vertexSourceDataIndex;
auto& shader = graphic.material.getShader("compute", "skinning");
struct {
uint32_t jointID;
} uniforms = {
.jointID = 0
};
shader.updateBuffer( (const void*) &uniforms, sizeof(uniforms), shader.getUniformBuffer("UBO") );
// bind buffers
::resetBuffers( shader );
shader.aliasBuffer( storage.buffers.joint );
shader.aliasBuffer( vertexPositionBuffer );
shader.aliasBuffer( vertexJointsBuffer );
shader.aliasBuffer( vertexWeightsBuffer );
shader.aliasBuffer( vertexOutPosition );
} }
graphic.generateBottomAccelerationStructures(); graphic.generateBottomAccelerationStructures();
} }
#endif #endif
@ -419,6 +429,7 @@ namespace {
shader.aliasBuffer( "indirect", *indirect ); shader.aliasBuffer( "indirect", *indirect );
#endif #endif
shader.aliasBuffer( "instance", storage.buffers.instance ); shader.aliasBuffer( "instance", storage.buffers.instance );
shader.aliasBuffer( "object", storage.buffers.object );
shader.aliasBuffer( "joint", storage.buffers.joint ); shader.aliasBuffer( "joint", storage.buffers.joint );
} }
// fragment shader // fragment shader
@ -462,6 +473,7 @@ namespace {
shader.aliasBuffer( "camera", storage.buffers.camera ); shader.aliasBuffer( "camera", storage.buffers.camera );
shader.aliasBuffer( "indirect", *indirect ); shader.aliasBuffer( "indirect", *indirect );
shader.aliasBuffer( "instance", storage.buffers.instance ); shader.aliasBuffer( "instance", storage.buffers.instance );
shader.aliasBuffer( "object", storage.buffers.object );
} }
// vxgi pipeline // vxgi pipeline
@ -492,6 +504,7 @@ namespace {
shader.aliasBuffer( "indirect", *indirect ); shader.aliasBuffer( "indirect", *indirect );
#endif #endif
shader.aliasBuffer( "instance", storage.buffers.instance ); shader.aliasBuffer( "instance", storage.buffers.instance );
shader.aliasBuffer( "object", storage.buffers.object );
shader.aliasBuffer( "joint", storage.buffers.joint ); shader.aliasBuffer( "joint", storage.buffers.joint );
} }
@ -520,7 +533,7 @@ namespace {
for ( size_t drawID = 0; drawID < mesh.indirect.count; ++drawID ) { for ( size_t drawID = 0; drawID < mesh.indirect.count; ++drawID ) {
auto& drawCommand = drawCommands[drawID]; auto& drawCommand = drawCommands[drawID];
auto instanceID = drawCommand.instanceID; auto instanceID = drawCommand.instanceID;
auto instanceKeyName = std::to_string(instanceID); // it *should* be fine as the instance IDs are already objective to the scene graph auto instanceKeyName = ::instanceKey( instanceID ); // it *should* be fine as the instance IDs are already objective to the scene graph
auto& instanceAddresses = storage.instanceAddresses[instanceKeyName]; auto& instanceAddresses = storage.instanceAddresses[instanceKeyName];
if ( mesh.vertex.count ) { if ( mesh.vertex.count ) {
@ -1277,17 +1290,21 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
} }
} }
} }
size_t objectID = storage.entities.keys.size();
auto objectKeyName = std::to_string(objectID);
storage.entities[objectKeyName] = &entity;
// what a mess
// //
if ( 0 <= node.mesh && node.mesh < graph.meshes.size() ) { if ( 0 <= node.mesh && node.mesh < graph.meshes.size() ) {
auto model = uf::transform::model( transform );
auto& mesh = storage.meshes.map[graph.meshes[node.mesh]]; auto& mesh = storage.meshes.map[graph.meshes[node.mesh]];
auto& primitives = storage.primitives.map[graph.primitives[node.mesh]]; auto& primitives = storage.primitives.map[graph.primitives[node.mesh]];
node.object = storage.entities.keys.size();
auto objectKeyName = ::objectKey( node );
storage.entities[objectKeyName] = &entity;
auto& objectData = storage.objects[objectKeyName];
auto model = uf::transform::model( transform );
objectData.model = model;
objectData.previous = model;
pod::Instance::Bounds bounds; pod::Instance::Bounds bounds;
pod::DrawCommand* drawCommands = NULL; pod::DrawCommand* drawCommands = NULL;
if ( mesh.indirect.count && mesh.indirect.count <= primitives.size() ) { if ( mesh.indirect.count && mesh.indirect.count <= primitives.size() ) {
@ -1296,23 +1313,20 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
drawCommands = (pod::DrawCommand*) buffer.data(); drawCommands = (pod::DrawCommand*) buffer.data();
} }
// setup instances // setup instances
for ( auto i = 0; i < primitives.size(); ++i ) { for ( auto primitiveID = 0; primitiveID < primitives.size(); ++primitiveID ) {
auto& primitive = primitives[i]; auto& primitive = primitives[primitiveID];
auto& instance = primitive.instance; auto& instance = primitive.instance;
auto& drawCommand = primitive.drawCommand; auto& drawCommand = primitive.drawCommand;
auto instanceID = primitiveID;
auto instanceID = i; instance.objectID = node.object;
instance.model = model;
instance.previous = model;
instance.objectID = objectID;
instance.jointID = graphMetadataJson["renderer"]["skinned"].as<bool>() ? 0 : -1; instance.jointID = graphMetadataJson["renderer"]["skinned"].as<bool>() ? 0 : -1;
bounds.min = uf::vector::min( bounds.min, instance.bounds.min ); bounds.min = uf::vector::min( bounds.min, instance.bounds.min );
bounds.max = uf::vector::max( bounds.max, instance.bounds.max ); bounds.max = uf::vector::max( bounds.max, instance.bounds.max );
drawCommand.instanceID = instanceID; drawCommand.instanceID = instanceID;
if ( drawCommands ) drawCommands[i].instanceID = instanceID; if ( drawCommands ) drawCommands[primitiveID].instanceID = instanceID;
} }
#if !UF_GRAPH_EXTENDED #if !UF_GRAPH_EXTENDED
if ( graphMetadataJson["renderer"]["render"].as<bool>() ) { if ( graphMetadataJson["renderer"]["render"].as<bool>() ) {
@ -1373,6 +1387,7 @@ void uf::graph::initialize( pod::Graph::Storage& storage, size_t initialElements
storage.buffers.instance.initialize( (const void*) nullptr, sizeof(pod::Instance) * initialElements, uf::renderer::enums::Buffer::STORAGE ); storage.buffers.instance.initialize( (const void*) nullptr, sizeof(pod::Instance) * initialElements, uf::renderer::enums::Buffer::STORAGE );
storage.buffers.instanceAddresses.initialize( (const void*) nullptr, sizeof(pod::Instance::Addresses) * initialElements, uf::renderer::enums::Buffer::STORAGE ); storage.buffers.instanceAddresses.initialize( (const void*) nullptr, sizeof(pod::Instance::Addresses) * initialElements, uf::renderer::enums::Buffer::STORAGE );
storage.buffers.joint.initialize( (const void*) nullptr, sizeof(pod::Matrix4f) * initialElements, uf::renderer::enums::Buffer::STORAGE ); storage.buffers.joint.initialize( (const void*) nullptr, sizeof(pod::Matrix4f) * initialElements, uf::renderer::enums::Buffer::STORAGE );
storage.buffers.object.initialize( (const void*) nullptr, sizeof(pod::Instance::Object) * initialElements, uf::renderer::enums::Buffer::STORAGE );
storage.buffers.material.initialize( (const void*) nullptr, sizeof(pod::Material) * initialElements, uf::renderer::enums::Buffer::STORAGE ); storage.buffers.material.initialize( (const void*) nullptr, sizeof(pod::Material) * initialElements, uf::renderer::enums::Buffer::STORAGE );
storage.buffers.texture.initialize( (const void*) nullptr, sizeof(pod::Texture) * initialElements, uf::renderer::enums::Buffer::STORAGE ); storage.buffers.texture.initialize( (const void*) nullptr, sizeof(pod::Texture) * initialElements, uf::renderer::enums::Buffer::STORAGE );
storage.buffers.light.initialize( (const void*) nullptr, sizeof(pod::Light) * initialElements, uf::renderer::enums::Buffer::STORAGE ); storage.buffers.light.initialize( (const void*) nullptr, sizeof(pod::Light) * initialElements, uf::renderer::enums::Buffer::STORAGE );
@ -1407,6 +1422,7 @@ bool uf::graph::tick( pod::Graph::Storage& storage ) {
uf::stl::vector<pod::Instance> instances; instances.reserve(storage.primitives.map.size()); uf::stl::vector<pod::Instance> instances; instances.reserve(storage.primitives.map.size());
uf::stl::vector<pod::Instance::Addresses> instanceAddresses = storage.instanceAddresses.flatten(); uf::stl::vector<pod::Instance::Addresses> instanceAddresses = storage.instanceAddresses.flatten();
uf::stl::vector<pod::Matrix4f> joints; joints.reserve(storage.joints.map.size()); uf::stl::vector<pod::Matrix4f> joints; joints.reserve(storage.joints.map.size());
uf::stl::vector<pod::Instance::Object> objects = storage.objects.flatten();
for ( auto& key : storage.primitives.keys ) { for ( auto& key : storage.primitives.keys ) {
for ( auto& primitive : storage.primitives.map[key] ) { for ( auto& primitive : storage.primitives.map[key] ) {
@ -1423,6 +1439,7 @@ bool uf::graph::tick( pod::Graph::Storage& storage ) {
rebuild = storage.buffers.instance.update( (const void*) instances.data(), instances.size() * sizeof(pod::Instance) ) || rebuild; rebuild = storage.buffers.instance.update( (const void*) instances.data(), instances.size() * sizeof(pod::Instance) ) || rebuild;
rebuild = storage.buffers.instanceAddresses.update( (const void*) instanceAddresses.data(), instanceAddresses.size() * sizeof(pod::Instance::Addresses) ) || rebuild; rebuild = storage.buffers.instanceAddresses.update( (const void*) instanceAddresses.data(), instanceAddresses.size() * sizeof(pod::Instance::Addresses) ) || rebuild;
rebuild = storage.buffers.joint.update( (const void*) joints.data(), joints.size() * sizeof(pod::Matrix4f) ) || rebuild; rebuild = storage.buffers.joint.update( (const void*) joints.data(), joints.size() * sizeof(pod::Matrix4f) ) || rebuild;
rebuild = storage.buffers.object.update( (const void*) objects.data(), objects.size() * sizeof(pod::Instance::Object) ) || rebuild;
if ( ::newGraphAdded ) { if ( ::newGraphAdded ) {
uf::stl::vector<pod::Material> materials = storage.materials.flatten(); uf::stl::vector<pod::Material> materials = storage.materials.flatten();
@ -1548,6 +1565,7 @@ void uf::graph::destroy( pod::Graph::Storage& storage, bool soft ) {
storage.buffers.instance.destroy(true); storage.buffers.instance.destroy(true);
storage.buffers.instanceAddresses.destroy(true); storage.buffers.instanceAddresses.destroy(true);
storage.buffers.joint.destroy(true); storage.buffers.joint.destroy(true);
storage.buffers.object.destroy(true);
storage.buffers.material.destroy(true); storage.buffers.material.destroy(true);
storage.buffers.texture.destroy(true); storage.buffers.texture.destroy(true);
storage.buffers.light.destroy(true); storage.buffers.light.destroy(true);
@ -1968,7 +1986,25 @@ void uf::graph::update( pod::Graph& graph, float delta ) {
#if !UF_ENV_DREAMCAST #if !UF_ENV_DREAMCAST
// update instance model // update instance model
uf::stl::unordered_map<size_t, pod::Matrix4f> instanceCache; uf::stl::unordered_map<size_t, pod::Matrix4f> matrixCache;
for ( auto& node : graph.nodes ) {
if ( !( 0 <= node.object && node.object < storage.objects.keys.size() ) ) continue;
auto objectKeyName = ::objectKey( node );
auto& entity = *storage.entities[objectKeyName];
auto& object = storage.objects[objectKeyName];
if ( !entity.isValid() ) continue;
auto& metadata = entity.getComponent<uf::ObjectBehavior::Metadata>();
if ( metadata.system.ignoreGraph ) continue;
auto& transform = entity.getComponent<pod::Transform<>>();
object.previous = object.model;
object.model = uf::transform::model( transform );
}
/*
for ( auto& name : graph.primitives ) { for ( auto& name : graph.primitives ) {
auto& primitives = storage.primitives[name]; auto& primitives = storage.primitives[name];
for ( auto& primitive : primitives ) { for ( auto& primitive : primitives ) {
@ -1989,6 +2025,7 @@ void uf::graph::update( pod::Graph& graph, float delta ) {
instance.model = (instanceCache[instance.objectID] = uf::transform::model( transform )); instance.model = (instanceCache[instance.objectID] = uf::transform::model( transform ));
} }
} }
*/
#endif #endif
uf::graph::updateAnimation( graph, delta ); uf::graph::updateAnimation( graph, delta );

View File

@ -442,6 +442,7 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
auto storageBufferIt = storageBuffers.begin(); auto storageBufferIt = storageBuffers.begin();
auto _instanceBuffer = (*storageBufferIt++).buffer; auto _instanceBuffer = (*storageBufferIt++).buffer;
auto objectBuffer = (*storageBufferIt++).buffer;
auto jointBuffer = (*storageBufferIt++).buffer; auto jointBuffer = (*storageBufferIt++).buffer;
auto drawCommandsBuffer = (*storageBufferIt++).buffer; auto drawCommandsBuffer = (*storageBufferIt++).buffer;
@ -453,6 +454,7 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
/* /*
auto _instanceBuffer = bufferMap["instance"].buffer; auto _instanceBuffer = bufferMap["instance"].buffer;
auto jointBuffer = bufferMap["joint"].buffer; auto jointBuffer = bufferMap["joint"].buffer;
auto objectBuffer = bufferMap["object"].buffer;
auto drawCommandsBuffer = bufferMap["drawCommands"].buffer; auto drawCommandsBuffer = bufferMap["drawCommands"].buffer;
auto instanceBuffer = bufferMap["instance"].buffer; auto instanceBuffer = bufferMap["instance"].buffer;
@ -464,6 +466,7 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
pod::DrawCommand* drawCommands = (pod::DrawCommand*) indirectAttribute.pointer; pod::DrawCommand* drawCommands = (pod::DrawCommand*) indirectAttribute.pointer;
pod::Instance* instances = (pod::Instance*) device->getBuffer( instanceBuffer ); pod::Instance* instances = (pod::Instance*) device->getBuffer( instanceBuffer );
pod::Instance::Object* objects = (pod::Instance::Object*) device->getBuffer( objectBuffer );
pod::Material* materials = (pod::Material*) device->getBuffer( materialBuffer ); pod::Material* materials = (pod::Material*) device->getBuffer( materialBuffer );
pod::Texture* textures = (pod::Texture*) device->getBuffer( textureBuffer ); pod::Texture* textures = (pod::Texture*) device->getBuffer( textureBuffer );
@ -474,9 +477,13 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
auto instanceID = drawCommand.instanceID; auto instanceID = drawCommand.instanceID;
auto& instance = instances[instanceID]; auto& instance = instances[instanceID];
auto objectID = instance.objectID;
auto materialID = instance.materialID; auto materialID = instance.materialID;
auto lightmapID = instance.lightmapID; auto lightmapID = instance.lightmapID;
auto& object = objects[objectID];
auto& material = materials[materialID]; auto& material = materials[materialID];
auto textureID = material.indexAlbedo; auto textureID = material.indexAlbedo;
@ -496,12 +503,12 @@ void ext::opengl::Graphic::record( CommandBuffer& commandBuffer, const GraphicDe
drawCommandInfo.attributes.indirect.pointer = (uint8_t*) (void*) &drawCommand; drawCommandInfo.attributes.indirect.pointer = (uint8_t*) (void*) &drawCommand;
drawCommandInfo.attributes.indirect.length = sizeof(drawCommand); drawCommandInfo.attributes.indirect.length = sizeof(drawCommand);
drawCommandInfo.matrices.model = &instance.model; drawCommandInfo.matrices.model = &object.model;
drawCommandInfo.blend.modeAlpha = material.modeAlpha; drawCommandInfo.blend.modeAlpha = material.modeAlpha;
drawCommandInfo.blend.alphaCutoff = material.factorAlphaCutoff; drawCommandInfo.blend.alphaCutoff = material.factorAlphaCutoff;
drawCommandInfo.color.value = instance.color * material.colorBase; drawCommandInfo.color.value = object.color * material.colorBase;
drawCommandInfo.color.enabled = drawCommandInfo.color.value != pod::Vector4f{1.0f, 1.0f, 1.0f, 1.0f}; drawCommandInfo.color.enabled = drawCommandInfo.color.value != pod::Vector4f{1.0f, 1.0f, 1.0f, 1.0f};
if ( 0 <= textureID ) { if ( 0 <= textureID ) {

View File

@ -1550,7 +1550,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
VK_UNREGISTER_HANDLE( queryPool ); VK_UNREGISTER_HANDLE( queryPool );
} }
} }
void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vector<uf::renderer::Graphic*>& graphics, const uf::stl::vector<pod::Instance>& instances ) { void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vector<uf::renderer::Graphic*>& graphics, const uf::stl::vector<pod::Instance>& instances, const uf::stl::vector<pod::Matrix4f>& modelMatrices ) {
auto& device = *this->device; auto& device = *this->device;
bool rebuild = false; bool rebuild = false;
@ -1586,10 +1586,8 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
uf::stl::vector<VkAccelerationStructureInstanceKHR> instancesVK; instancesVK.reserve( instances.size() ); uf::stl::vector<VkAccelerationStructureInstanceKHR> instancesVK; instancesVK.reserve( instances.size() );
for ( auto& graphic : graphics ) { for ( auto& graphic : graphics ) {
for ( auto& blas : graphic->accelerationStructures.bottoms ) { for ( auto& blas : graphic->accelerationStructures.bottoms ) {
size_t instanceID = blas.instanceID; auto& instance = instances[blas.instanceID];
auto instanceKeyName = std::to_string(instanceID); auto mat = modelMatrices[instance.objectID];
auto mat = instances[instanceID].model;
mat = uf::matrix::transpose(mat); mat = uf::matrix::transpose(mat);
auto& instanceVK = instancesVK.emplace_back(); auto& instanceVK = instancesVK.emplace_back();

View File

@ -302,6 +302,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
shader.aliasBuffer( storage.buffers.drawCommands ); shader.aliasBuffer( storage.buffers.drawCommands );
shader.aliasBuffer( storage.buffers.instance ); shader.aliasBuffer( storage.buffers.instance );
shader.aliasBuffer( storage.buffers.instanceAddresses ); shader.aliasBuffer( storage.buffers.instanceAddresses );
shader.aliasBuffer( storage.buffers.object );
shader.aliasBuffer( storage.buffers.material ); shader.aliasBuffer( storage.buffers.material );
shader.aliasBuffer( storage.buffers.texture ); shader.aliasBuffer( storage.buffers.texture );
shader.aliasBuffer( storage.buffers.light ); shader.aliasBuffer( storage.buffers.light );
@ -527,6 +528,7 @@ void ext::vulkan::DeferredRenderMode::tick() {
shader.aliasBuffer( storage.buffers.drawCommands ); shader.aliasBuffer( storage.buffers.drawCommands );
shader.aliasBuffer( storage.buffers.instance ); shader.aliasBuffer( storage.buffers.instance );
shader.aliasBuffer( storage.buffers.instanceAddresses ); shader.aliasBuffer( storage.buffers.instanceAddresses );
shader.aliasBuffer( storage.buffers.object );
shader.aliasBuffer( storage.buffers.material ); shader.aliasBuffer( storage.buffers.material );
shader.aliasBuffer( storage.buffers.texture ); shader.aliasBuffer( storage.buffers.texture );
shader.aliasBuffer( storage.buffers.light ); shader.aliasBuffer( storage.buffers.light );

View File

@ -349,14 +349,15 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
{ "voxelOutput", maxCascades }, { "voxelOutput", maxCascades },
}); });
// shader.buffers.emplace_back( storage.buffers.camera.alias() ); // shader.aliasBuffer( storage.buffers.camera );
// shader.buffers.emplace_back( storage.buffers.joint.alias() ); // shader.aliasBuffer( storage.buffers.joint );
shader.buffers.emplace_back( storage.buffers.drawCommands.alias() ); shader.aliasBuffer( storage.buffers.drawCommands );
shader.buffers.emplace_back( storage.buffers.instance.alias() ); shader.aliasBuffer( storage.buffers.instance );
shader.buffers.emplace_back( storage.buffers.instanceAddresses.alias() ); shader.aliasBuffer( storage.buffers.instanceAddresses );
shader.buffers.emplace_back( storage.buffers.material.alias() ); shader.aliasBuffer( storage.buffers.object );
shader.buffers.emplace_back( storage.buffers.texture.alias() ); shader.aliasBuffer( storage.buffers.material );
shader.buffers.emplace_back( storage.buffers.light.alias() ); shader.aliasBuffer( storage.buffers.texture );
shader.aliasBuffer( storage.buffers.light );
} else if ( metadata.type == uf::renderer::settings::pipelines::names::rt ) { } else if ( metadata.type == uf::renderer::settings::pipelines::names::rt ) {
#if 0 #if 0
auto& shader = blitter.material.getShader("fragment"); auto& shader = blitter.material.getShader("fragment");