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:
parent
a099c562a2
commit
0fb2e3b750
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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[];
|
||||
};
|
||||
|
||||
|
@ -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)));
|
||||
}
|
@ -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,
|
||||
|
@ -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[];
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1 +1 @@
|
||||
opengl
|
||||
vulkan
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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 = {};
|
||||
};
|
||||
|
||||
|
@ -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 },
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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 ) {
|
||||
|
@ -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();
|
||||
|
@ -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 );
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user