diff --git a/bin/data/shaders/common/functions.h b/bin/data/shaders/common/functions.h index 1e61ca79..95ce4718 100644 --- a/bin/data/shaders/common/functions.h +++ b/bin/data/shaders/common/functions.h @@ -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); diff --git a/bin/data/shaders/common/structs.h b/bin/data/shaders/common/structs.h index 811c353b..f575c105 100644 --- a/bin/data/shaders/common/structs.h +++ b/bin/data/shaders/common/structs.h @@ -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; diff --git a/bin/data/shaders/display/deferred/comp/comp.h b/bin/data/shaders/display/deferred/comp/comp.h index 47a7ceee..4a608c1a 100644 --- a/bin/data/shaders/display/deferred/comp/comp.h +++ b/bin/data/shaders/display/deferred/comp/comp.h @@ -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; diff --git a/bin/data/shaders/display/vxgi/comp.glsl b/bin/data/shaders/display/vxgi/comp.glsl index a2d71e60..e9078a0e 100644 --- a/bin/data/shaders/display/vxgi/comp.glsl +++ b/bin/data/shaders/display/vxgi/comp.glsl @@ -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; diff --git a/bin/data/shaders/graph/baking/frag.h b/bin/data/shaders/graph/baking/frag.h index 585d4b52..a4c8443b 100644 --- a/bin/data/shaders/graph/baking/frag.h +++ b/bin/data/shaders/graph/baking/frag.h @@ -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" diff --git a/bin/data/shaders/graph/base/frag.glsl b/bin/data/shaders/graph/base/frag.glsl index 49d60e02..a106158f 100644 --- a/bin/data/shaders/graph/base/frag.glsl +++ b/bin/data/shaders/graph/base/frag.glsl @@ -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[]; }; diff --git a/bin/data/shaders/graph/base/vert.h b/bin/data/shaders/graph/base/vert.h index 99437451..15ef1442 100644 --- a/bin/data/shaders/graph/base/vert.h +++ b/bin/data/shaders/graph/base/vert.h @@ -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))); } \ No newline at end of file diff --git a/bin/data/shaders/graph/cull/comp.glsl b/bin/data/shaders/graph/cull/comp.glsl index e312b560..345d6d13 100644 --- a/bin/data/shaders/graph/cull/comp.glsl +++ b/bin/data/shaders/graph/cull/comp.glsl @@ -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, diff --git a/bin/data/shaders/graph/depth/frag.glsl b/bin/data/shaders/graph/depth/frag.glsl index 79ed3c71..e6116b13 100644 --- a/bin/data/shaders/graph/depth/frag.glsl +++ b/bin/data/shaders/graph/depth/frag.glsl @@ -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[]; }; diff --git a/bin/data/shaders/graph/voxelize/frag.glsl b/bin/data/shaders/graph/voxelize/frag.glsl index 1744c9c5..e6a33b98 100644 --- a/bin/data/shaders/graph/voxelize/frag.glsl +++ b/bin/data/shaders/graph/voxelize/frag.glsl @@ -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; diff --git a/bin/data/shaders/graph/voxelize/geom.glsl b/bin/data/shaders/graph/voxelize/geom.glsl index 65259479..286a482e 100644 --- a/bin/data/shaders/graph/voxelize/geom.glsl +++ b/bin/data/shaders/graph/voxelize/geom.glsl @@ -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; diff --git a/bin/data/shaders/raytrace/shader.ray-gen.glsl b/bin/data/shaders/raytrace/shader.ray-gen.glsl index a5f3491f..988398a0 100644 --- a/bin/data/shaders/raytrace/shader.ray-gen.glsl +++ b/bin/data/shaders/raytrace/shader.ray-gen.glsl @@ -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; diff --git a/bin/exe/default/renderer b/bin/exe/default/renderer index 91caa7c1..53395cff 100644 --- a/bin/exe/default/renderer +++ b/bin/exe/default/renderer @@ -1 +1 @@ -opengl \ No newline at end of file +vulkan \ No newline at end of file diff --git a/engine/inc/uf/engine/graph/graph.h b/engine/inc/uf/engine/graph/graph.h index 8bcdfc7d..e99d3bcf 100644 --- a/engine/inc/uf/engine/graph/graph.h +++ b/engine/inc/uf/engine/graph/graph.h @@ -93,6 +93,7 @@ namespace pod { // maps without direct analogues uf::stl::KeyMap atlases; + uf::stl::KeyMap objects; uf::stl::KeyMap> joints; uf::stl::KeyMap texture2Ds; uf::stl::KeyMap 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; diff --git a/engine/inc/uf/engine/graph/pod.inl b/engine/inc/uf/engine/graph/pod.inl index 330de89e..ad016571 100644 --- a/engine/inc/uf/engine/graph/pod.inl +++ b/engine/inc/uf/engine/graph/pod.inl @@ -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 children; uf::Object* entity = NULL; diff --git a/engine/inc/uf/ext/vulkan/graphic.h b/engine/inc/uf/ext/vulkan/graphic.h index f1472876..ebc09cb0 100644 --- a/engine/inc/uf/ext/vulkan/graphic.h +++ b/engine/inc/uf/ext/vulkan/graphic.h @@ -100,7 +100,7 @@ namespace ext { bool updateMesh( uf::Mesh& mesh ); // raytrace void generateBottomAccelerationStructures(); - void generateTopAccelerationStructure( const uf::stl::vector&, const uf::stl::vector& ); + void generateTopAccelerationStructure( const uf::stl::vector&, const uf::stl::vector&, const uf::stl::vector& ); bool hasPipeline( const GraphicDescriptor& descriptor ) const; void initializePipeline(); diff --git a/engine/inc/uf/utils/mesh/mesh.h b/engine/inc/uf/utils/mesh/mesh.h index 0dc177cb..31e18c60 100644 --- a/engine/inc/uf/utils/mesh/mesh.h +++ b/engine/inc/uf/utils/mesh/mesh.h @@ -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 = {}; }; diff --git a/engine/src/engine/ext/raytrace/behavior.cpp b/engine/src/engine/ext/raytrace/behavior.cpp index 29c9d841..eaffc0af 100644 --- a/engine/src/engine/ext/raytrace/behavior.cpp +++ b/engine/src/engine/ext/raytrace/behavior.cpp @@ -94,8 +94,9 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) { } else return; } - static uf::stl::vector previousInstances; uf::stl::vector instances; instances.reserve(storage.primitives.map.size()); + uf::stl::vector 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 previousModels; static uf::stl::vector previousGraphics; static uf::stl::vector 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(); 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(1); size_t maxCascades = uf::config["engine"]["scenes"]["vxgi"]["cascades"].as(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 }, diff --git a/engine/src/engine/graph/decode.cpp b/engine/src/engine/graph/decode.cpp index f94832e4..6cf422de 100644 --- a/engine/src/engine/graph/decode.cpp +++ b/engine/src/engine/graph/decode.cpp @@ -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 ); diff --git a/engine/src/engine/graph/encode.cpp b/engine/src/engine/graph/encode.cpp index c199ac62..1122d563 100644 --- a/engine/src/engine/graph/encode.cpp +++ b/engine/src/engine/graph/encode.cpp @@ -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; diff --git a/engine/src/engine/graph/graph.cpp b/engine/src/engine/graph/graph.cpp index 68fdd073..47ecb4ea 100644 --- a/engine/src/engine/graph/graph.cpp +++ b/engine/src/engine/graph/graph.cpp @@ -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(); } @@ -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() ) { - struct PushConstant { - uint32_t jointID; - }; + if ( uf::renderer::settings::pipelines::rt && mesh.vertex.count ) { + if ( graphMetadataJson["renderer"]["skinned"].as() ) { + struct PushConstant { + uint32_t jointID; + }; - if ( mesh.isInterleaved( mesh.vertex ) ) { - uf::stl::string compShaderFilename = graphMetadataJson["shaders"]["skinning"]["compute"].as("/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("/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("/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("/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() ? 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() ) { @@ -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 instances; instances.reserve(storage.primitives.map.size()); uf::stl::vector instanceAddresses = storage.instanceAddresses.flatten(); uf::stl::vector joints; joints.reserve(storage.joints.map.size()); + uf::stl::vector 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 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 instanceCache; + uf::stl::unordered_map 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(); + if ( metadata.system.ignoreGraph ) continue; + + auto& transform = entity.getComponent>(); + + 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 ); diff --git a/engine/src/ext/opengl/graphic.cpp b/engine/src/ext/opengl/graphic.cpp index cd7e6fd8..24d2f09d 100644 --- a/engine/src/ext/opengl/graphic.cpp +++ b/engine/src/ext/opengl/graphic.cpp @@ -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 ) { diff --git a/engine/src/ext/vulkan/graphic.cpp b/engine/src/ext/vulkan/graphic.cpp index 90406aac..7fb2e0f6 100644 --- a/engine/src/ext/vulkan/graphic.cpp +++ b/engine/src/ext/vulkan/graphic.cpp @@ -1550,7 +1550,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() { VK_UNREGISTER_HANDLE( queryPool ); } } -void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vector& graphics, const uf::stl::vector& instances ) { +void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vector& graphics, const uf::stl::vector& instances, const uf::stl::vector& modelMatrices ) { auto& device = *this->device; bool rebuild = false; @@ -1586,10 +1586,8 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect uf::stl::vector 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(); diff --git a/engine/src/ext/vulkan/rendermodes/deferred.cpp b/engine/src/ext/vulkan/rendermodes/deferred.cpp index 52674a69..7dd58143 100644 --- a/engine/src/ext/vulkan/rendermodes/deferred.cpp +++ b/engine/src/ext/vulkan/rendermodes/deferred.cpp @@ -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 ); diff --git a/engine/src/ext/vulkan/rendermodes/rendertarget.cpp b/engine/src/ext/vulkan/rendermodes/rendertarget.cpp index cc9e7f5b..9200e19c 100644 --- a/engine/src/ext/vulkan/rendermodes/rendertarget.cpp +++ b/engine/src/ext/vulkan/rendermodes/rendertarget.cpp @@ -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");