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
{
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 b = points[1].position;
@ -410,21 +410,21 @@ void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
// 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) ));
vec3 bitangent = normalize(vec3( surface.instance.model * vec4(cross( triangle.point.normal, triangle.point.tangent ), 0.0) ));
surface.tangent.world = normalize(vec3( surface.object.model * vec4(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);
}
// 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.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) );
}
#endif
// 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) );
}
// bind UVs
@ -441,6 +441,7 @@ void populateSurface( uint instanceID, uint primitiveID ) {
surface.fragment = vec4(0);
surface.light = vec4(0);
surface.instance = instances[instanceID];
surface.object = objects[surface.instance.objectID];
const InstanceAddresses instanceAddresses = instanceAddresses[instanceID];
if ( !isValidAddress(instanceAddresses.index) ) return;
@ -464,6 +465,7 @@ void populateSurface( RayTracePayload payload ) {
surface.fragment = vec4(0);
surface.light = vec4(0);
surface.instance = instances[payload.instanceID];
surface.object = objects[surface.instance.objectID];
if ( !payload.hit ) return;
surface.barycentric = decodeBarycentrics(payload.attributes);

View File

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

View File

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

View File

@ -35,30 +35,33 @@ layout (std140, binding = 2) readonly buffer Instances {
layout (std140, binding = 3) readonly buffer InstanceAddresseses {
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[];
};
layout (std140, binding = 5) readonly buffer Textures {
layout (std140, binding = 6) readonly buffer Textures {
Texture textures[];
};
layout (std140, binding = 6) readonly buffer Lights {
layout (std140, binding = 7) readonly buffer Lights {
Light lights[];
};
layout (binding = 7) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 8) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 9) uniform sampler3D samplerNoise;
layout (binding = 8) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 9) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 10) uniform sampler3D samplerNoise;
layout (binding = 10, 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 voxelNormalX[CASCADES];
layout (binding = 13, 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 voxelRadianceG[CASCADES];
layout (binding = 16, 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 voxelCount[CASCADES];
layout (binding = 19, rgba8) uniform volatile coherent image3D voxelOutput[CASCADES];
layout (binding = 11, r32ui) uniform volatile coherent uimage3D voxelDrawId[CASCADES];
layout (binding = 12, r32ui) uniform volatile coherent uimage3D voxelInstanceId[CASCADES];
layout (binding = 13, r32ui) uniform volatile coherent uimage3D voxelNormalX[CASCADES];
layout (binding = 14, r32ui) uniform volatile coherent uimage3D voxelNormalY[CASCADES];
layout (binding = 15, r32ui) uniform volatile coherent uimage3D voxelRadianceR[CASCADES];
layout (binding = 16, r32ui) uniform volatile coherent uimage3D voxelRadianceG[CASCADES];
layout (binding = 17, r32ui) uniform volatile coherent uimage3D voxelRadianceB[CASCADES];
layout (binding = 18, r32ui) uniform volatile coherent uimage3D voxelRadianceA[CASCADES];
layout (binding = 19, r32ui) uniform volatile coherent uimage3D voxelCount[CASCADES];
layout (binding = 20, rgba8) uniform volatile coherent image3D voxelOutput[CASCADES];
#include "../../common/functions.h"
#include "../../common/light.h"
@ -127,6 +130,7 @@ void main() {
const DrawCommand drawCommand = drawCommands[drawID];
surface.instance = instances[instanceID];
surface.object = objects[surface.instance.objectID];
const Material material = materials[surface.instance.materialID];
surface.material.albedo = material.colorBase;
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 = 2) const uint LAYERS = 32;
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 6) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 6) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 7) uniform samplerCube samplerCubemaps[CUBEMAPS];
#define SHADOW_SAMPLES 16
#define FRAGMENT 1
@ -22,40 +22,40 @@ layout (binding = 6) uniform samplerCube samplerCubemaps[CUBEMAPS];
#include "../../common/macros.h"
#include "../../common/structs.h"
layout (binding = 7) uniform Camera {
layout (binding = 8) uniform Camera {
Viewport viewport[6];
} camera;
layout (binding = 8) uniform UBO {
layout (binding = 9) uniform UBO {
uint lights;
uint currentID;
uint padding1;
uint padding2;
} ubo;
layout (std140, binding = 9) readonly buffer DrawCommands {
layout (std140, binding = 10) readonly buffer DrawCommands {
DrawCommand drawCommands[];
};
layout (std140, binding = 10) readonly buffer Instances {
layout (std140, binding = 11) readonly buffer Instances {
Instance instances[];
};
layout (std140, binding = 11) readonly buffer InstanceAddresseses {
layout (std140, binding = 12) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[];
};
layout (std140, binding = 12) readonly buffer Materials {
layout (std140, binding = 13) readonly buffer Materials {
Material materials[];
};
layout (std140, binding = 13) readonly buffer Textures {
layout (std140, binding = 14) readonly buffer Textures {
Texture textures[];
};
layout (std140, binding = 14) readonly buffer Lights {
layout (std140, binding = 15) readonly buffer Lights {
Light lights[];
};
layout (binding = 15, rgba8) uniform volatile coherent image3D outAlbedos;
layout (binding = 16, rgba8) uniform volatile coherent image3D outAlbedos;
#if RT
layout (binding = 16) uniform accelerationStructureEXT tlas;
layout (binding = 17) uniform accelerationStructureEXT tlas;
#endif
#include "../../common/functions.h"

View File

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

View File

@ -32,9 +32,12 @@ layout (std140, binding = 1) readonly buffer DrawCommands {
layout (std140, binding = 2) readonly buffer Instances {
Instance instances[];
};
layout (std140, binding = 3) readonly buffer Objects {
Object objects[];
};
#if SKINNED
layout (std140, binding = 3) readonly buffer Joints {
layout (std140, binding = 4) readonly buffer Joints {
mat4 joints[];
};
#endif
@ -63,6 +66,7 @@ void main() {
const DrawCommand drawCommand = drawCommands[drawID];
const uint instanceID = drawCommand.instanceID; // gl_InstanceIndex;
const Instance instance = instances[instanceID];
const Object object = objects[instance.objectID];
const uint jointID = instance.jointID;
#if BAKING
@ -77,8 +81,8 @@ void main() {
#else
const mat4 skinned = mat4(1.0);
#endif
const mat4 model = instances.length() <= 0 ? skinned : (instance.model * skinned);
// const mat4 model = instance.model * skinned;
const mat4 model = instances.length() <= 0 ? skinned : (object.model * skinned);
// const mat4 model = object.model * skinned;
#if BAKING
@ -94,7 +98,7 @@ void main() {
outPosition = vec3(model * vec4(inPos.xyz, 1.0));
outUv = inUv;
outSt = inSt;
outColor = inColor * instance.color;
outColor = inColor * object.color;
outNormal = normalize(vec3(model * vec4(inNormal.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[];
};
layout (binding = 3) uniform sampler2D samplerDepth;
layout (std140, binding = 3) buffer Objects {
Object objects[];
};
layout (binding = 4) uniform sampler2D samplerDepth;
struct Frustum {
vec4 planes[6];
@ -82,6 +86,7 @@ bool frustumCull( uint id ) {
const DrawCommand drawCommand = drawCommands[id];
const Instance instance = instances[drawCommand.instanceID];
const Object object = objects[instance.objectID];
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 ) {
#if 0
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
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
vec4 planes[6]; {
for (int i = 0; i < 3; ++i)
@ -154,14 +159,15 @@ bool occlusionCull( uint id ) {
const DrawCommand drawCommand = drawCommands[id];
const Instance instance = instances[drawCommand.instanceID];
const Object object = objects[instance.objectID];
bool visible = true;
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
#if 1
vec4 aabb;
vec4 sphere = aabbToSphere( instance.bounds );
vec3 center = (camera.viewport[pass].view * instance.model * vec4(sphere.xyz, 1)).xyz;
float radius = (instance.model * vec4(sphere.w, 0, 0, 0)).x;
vec3 center = (camera.viewport[pass].view * object.model * vec4(sphere.xyz, 1)).xyz;
float radius = (object.model * vec4(sphere.w, 0, 0, 0)).x;
// center.y *= -1;
mat4 proj = camera.viewport[pass].projection;
float znear = proj[3][2];
@ -193,7 +199,7 @@ bool occlusionCull( uint id ) {
}
#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 points[8] = {
instance.bounds.min.xyz,

View File

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

View File

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

View File

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

View File

@ -1 +1 @@
opengl
vulkan

View File

@ -93,6 +93,7 @@ namespace pod {
// maps without direct analogues
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::renderer::Texture2D> texture2Ds;
uf::stl::KeyMap<uf::Entity*> entities;
@ -106,6 +107,7 @@ namespace pod {
uf::renderer::Buffer instance;
uf::renderer::Buffer instanceAddresses;
uf::renderer::Buffer joint;
uf::renderer::Buffer object;
uf::renderer::Buffer material;
uf::renderer::Buffer texture;
uf::renderer::Buffer light;

View File

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

View File

@ -100,7 +100,7 @@ namespace ext {
bool updateMesh( uf::Mesh& mesh );
// raytrace
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;
void initializePipeline();

View File

@ -77,16 +77,10 @@ namespace pod {
// stores information about how to transform a draw call
// to-do: clean up this mess
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 primitiveID = 0; // index to reference the primitive(?)
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 lightmapID = -1; // index for lightmap to use
@ -126,6 +120,13 @@ namespace pod {
alignas(8) uint64_t id{};
alignas(8) uint64_t padding1{};
};
struct UF_API Object {
pod::Matrix4f model;
pod::Matrix4f previous;
pod::Vector4f color = { 1, 1, 1, 1 };
};
// Addresses addresses = {};
};

View File

@ -94,8 +94,9 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
} 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::Matrix4f> models; models.reserve(storage.objects.map.size());
for ( auto& key : storage.primitives.keys ) {
for ( auto& primitive : storage.primitives.map[key] ) {
instances.emplace_back( primitive.instance );
@ -103,6 +104,12 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
}
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::renderer::AccelerationStructure> previousBlases;
@ -130,28 +137,30 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
}
update = true;
} 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 ( 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( 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;
}
*/
}
if ( update ) {
for ( auto* graphic : graphics ) {
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>();
sceneMetadata.shader.frameAccumulateReset = true;
uf::renderer::states::frameAccumulateReset = true;
previousInstances = instances;
previousModels = models;
previousGraphics = graphics;
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 maxCascades = uf::config["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(16);
shader.buffers.emplace_back( storage.buffers.instance.alias() );
shader.buffers.emplace_back( storage.buffers.instanceAddresses.alias() );
shader.buffers.emplace_back( storage.buffers.material.alias() );
shader.buffers.emplace_back( storage.buffers.texture.alias() );
shader.buffers.emplace_back( storage.buffers.light.alias() );
shader.aliasBuffer( storage.buffers.instance );
shader.aliasBuffer( storage.buffers.instanceAddresses );
shader.aliasBuffer( storage.buffers.object );
shader.aliasBuffer( storage.buffers.material );
shader.aliasBuffer( storage.buffers.texture );
shader.aliasBuffer( storage.buffers.light );
shader.setSpecializationConstants({
{ "TEXTURES", maxTextures2D },

View File

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

View File

@ -44,6 +44,13 @@ namespace {
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 ) {
return uf::graph::globalStorage ? uf::graph::storage : object.getComponent<pod::Graph::Storage>();
}
@ -283,113 +290,116 @@ namespace {
// rt pipeline
// to-do: segregate out buffer updating code
if ( uf::renderer::settings::pipelines::rt && mesh.vertex.count && graphMetadataJson["renderer"]["skinned"].as<bool>() ) {
struct PushConstant {
uint32_t jointID;
};
if ( uf::renderer::settings::pipelines::rt && mesh.vertex.count ) {
if ( graphMetadataJson["renderer"]["skinned"].as<bool>() ) {
struct PushConstant {
uint32_t jointID;
};
if ( mesh.isInterleaved( mesh.vertex ) ) {
uf::stl::string compShaderFilename = graphMetadataJson["shaders"]["skinning"]["compute"].as<uf::stl::string>("/graph/skinning/skinning.interleaved.comp.spv"); {
compShaderFilename = entity.resolveURI( compShaderFilename, root );
}
graphic.material.metadata.autoInitializeUniformBuffers = false;
graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, "skinning");
graphic.material.metadata.autoInitializeUniformBuffers = true;
if ( mesh.isInterleaved( mesh.vertex ) ) {
uf::stl::string compShaderFilename = graphMetadataJson["shaders"]["skinning"]["compute"].as<uf::stl::string>("/graph/skinning/skinning.interleaved.comp.spv"); {
compShaderFilename = entity.resolveURI( compShaderFilename, root );
}
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;
// 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.descriptor.bind.height = 1;
graphic.descriptor.bind.depth = 1;
// 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;
// compute shader
auto& shader = graphic.material.getShader("compute", "skinning");
uf::Mesh::Attribute vertexPos;
uf::Mesh::Attribute vertexJoints;
uf::Mesh::Attribute vertexWeights;
// bind buffers
struct {
uint32_t jointID;
} uniforms = {
.jointID = 0
};
size_t vertexPosIndex = 0;
size_t vertexJointsIndex = 0;
size_t vertexWeightsIndex = 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 );
for ( size_t i = 0; i < graphic.descriptor.inputs.vertex.attributes.size(); ++i ) {
auto& attribute = graphic.descriptor.inputs.vertex.attributes[i];
auto& vertexIn = graphic.buffers.at(graphic.descriptor.inputs.vertex.interleaved);
auto& vertexOut = graphic.buffers.at(vertexSourceDataIndex);
graphic.metadata.buffers["vertexSkinned"] = vertexSourceDataIndex;
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]"];
}
}
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 );
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 );
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.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();
}
#endif
@ -419,6 +429,7 @@ namespace {
shader.aliasBuffer( "indirect", *indirect );
#endif
shader.aliasBuffer( "instance", storage.buffers.instance );
shader.aliasBuffer( "object", storage.buffers.object );
shader.aliasBuffer( "joint", storage.buffers.joint );
}
// fragment shader
@ -462,6 +473,7 @@ namespace {
shader.aliasBuffer( "camera", storage.buffers.camera );
shader.aliasBuffer( "indirect", *indirect );
shader.aliasBuffer( "instance", storage.buffers.instance );
shader.aliasBuffer( "object", storage.buffers.object );
}
// vxgi pipeline
@ -492,6 +504,7 @@ namespace {
shader.aliasBuffer( "indirect", *indirect );
#endif
shader.aliasBuffer( "instance", storage.buffers.instance );
shader.aliasBuffer( "object", storage.buffers.object );
shader.aliasBuffer( "joint", storage.buffers.joint );
}
@ -520,7 +533,7 @@ namespace {
for ( size_t drawID = 0; drawID < mesh.indirect.count; ++drawID ) {
auto& drawCommand = drawCommands[drawID];
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];
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() ) {
auto model = uf::transform::model( transform );
auto& mesh = storage.meshes.map[graph.meshes[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::DrawCommand* drawCommands = NULL;
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();
}
// setup instances
for ( auto i = 0; i < primitives.size(); ++i ) {
auto& primitive = primitives[i];
for ( auto primitiveID = 0; primitiveID < primitives.size(); ++primitiveID ) {
auto& primitive = primitives[primitiveID];
auto& instance = primitive.instance;
auto& drawCommand = primitive.drawCommand;
auto instanceID = primitiveID;
auto instanceID = i;
instance.model = model;
instance.previous = model;
instance.objectID = objectID;
instance.objectID = node.object;
instance.jointID = graphMetadataJson["renderer"]["skinned"].as<bool>() ? 0 : -1;
bounds.min = uf::vector::min( bounds.min, instance.bounds.min );
bounds.max = uf::vector::max( bounds.max, instance.bounds.max );
drawCommand.instanceID = instanceID;
if ( drawCommands ) drawCommands[i].instanceID = instanceID;
if ( drawCommands ) drawCommands[primitiveID].instanceID = instanceID;
}
#if !UF_GRAPH_EXTENDED
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.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.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.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 );
@ -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::Addresses> instanceAddresses = storage.instanceAddresses.flatten();
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& 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.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.object.update( (const void*) objects.data(), objects.size() * sizeof(pod::Instance::Object) ) || rebuild;
if ( ::newGraphAdded ) {
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.instanceAddresses.destroy(true);
storage.buffers.joint.destroy(true);
storage.buffers.object.destroy(true);
storage.buffers.material.destroy(true);
storage.buffers.texture.destroy(true);
storage.buffers.light.destroy(true);
@ -1968,7 +1986,25 @@ void uf::graph::update( pod::Graph& graph, float delta ) {
#if !UF_ENV_DREAMCAST
// 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 ) {
auto& primitives = storage.primitives[name];
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 ));
}
}
*/
#endif
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 _instanceBuffer = (*storageBufferIt++).buffer;
auto objectBuffer = (*storageBufferIt++).buffer;
auto jointBuffer = (*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 jointBuffer = bufferMap["joint"].buffer;
auto objectBuffer = bufferMap["object"].buffer;
auto drawCommandsBuffer = bufferMap["drawCommands"].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::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::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& instance = instances[instanceID];
auto objectID = instance.objectID;
auto materialID = instance.materialID;
auto lightmapID = instance.lightmapID;
auto& object = objects[objectID];
auto& material = materials[materialID];
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.length = sizeof(drawCommand);
drawCommandInfo.matrices.model = &instance.model;
drawCommandInfo.matrices.model = &object.model;
drawCommandInfo.blend.modeAlpha = material.modeAlpha;
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};
if ( 0 <= textureID ) {

View File

@ -1550,7 +1550,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
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;
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() );
for ( auto& graphic : graphics ) {
for ( auto& blas : graphic->accelerationStructures.bottoms ) {
size_t instanceID = blas.instanceID;
auto instanceKeyName = std::to_string(instanceID);
auto mat = instances[instanceID].model;
auto& instance = instances[blas.instanceID];
auto mat = modelMatrices[instance.objectID];
mat = uf::matrix::transpose(mat);
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.instance );
shader.aliasBuffer( storage.buffers.instanceAddresses );
shader.aliasBuffer( storage.buffers.object );
shader.aliasBuffer( storage.buffers.material );
shader.aliasBuffer( storage.buffers.texture );
shader.aliasBuffer( storage.buffers.light );
@ -527,6 +528,7 @@ void ext::vulkan::DeferredRenderMode::tick() {
shader.aliasBuffer( storage.buffers.drawCommands );
shader.aliasBuffer( storage.buffers.instance );
shader.aliasBuffer( storage.buffers.instanceAddresses );
shader.aliasBuffer( storage.buffers.object );
shader.aliasBuffer( storage.buffers.material );
shader.aliasBuffer( storage.buffers.texture );
shader.aliasBuffer( storage.buffers.light );

View File

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