diff --git a/bin/data/config.json b/bin/data/config.json index 2e4a764b..825be3ff 100644 --- a/bin/data/config.json +++ b/bin/data/config.json @@ -1,15 +1,15 @@ { "engine": { "scenes": { - "start": "SS2", + "start": "McDonalds", "meshes": { "interleaved": false }, "matrix": { "reverseInfinite": true }, "lights": { "enabled": true, "useLightmaps": false, - "max": 32 + "max": 24 }, "shadows": { - "enabled": true, + "enabled": false, "update": 2, "max": 16, "samples": 1 @@ -48,7 +48,7 @@ "ext": { "vulkan": { "validation": { - "enabled": false, + "enabled": true, "filters": [ "MessageID = 0x4dae5635", // UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout (false positive for cubemaps) "MessageID = 0x609a13b", // UNASSIGNED-CoreValidation-Shader-OutputNotConsumed (from depth-only calls) @@ -243,6 +243,10 @@ "delete children on destroy": true, "delete components on destroy": true }, + "userdata": { + "auto destruct": true, + "auto validate": false + }, "loader": { "assert": true } diff --git a/bin/data/entities/playerModel.json b/bin/data/entities/playerModel.json index 78066453..ab58f2a8 100644 --- a/bin/data/entities/playerModel.json +++ b/bin/data/entities/playerModel.json @@ -2,10 +2,10 @@ "type": "Object", "name": "Player: Model", "ignore": true, + "import": "/model.json", "assets": [ "/player/bear.glb" - // { "filename": "/player/bear/graph.json", "delay": 0, "single threaded": false, "category": "models" } - // { "filename": "/player/bear/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" } + // { "filename": "/player/bear/graph.json" } ], "behaviors": [ "PlayerModelBehavior" @@ -29,30 +29,22 @@ "track": true, "hide": true, "model": { - "debug": { - "no cleanup": false, - "print tree": false, - "print stats": false + "lightmap": false, + "exporter": { + "enabled": false, + "unwrap": false, + "optimize": false }, - "export": { - "should": true, - "pretty": false, - "compress": true, - "quantize": false, - "precision": 4, - "combined": false, - "encode buffers": true, - "unwrap": false + "baking": { + "enabled": false }, "animation": "wank", "print animations": true, - // "filter": "NEAREST", - "cull mode": "none", "flags": { "ATLAS": false, "INVERT": true, "TRANSFORM": false, - "SKINNED": true, + "SKINNED": false, "RENDER": true, "SEPARATE": false, diff --git a/bin/data/scenes/cornell/cornell.json b/bin/data/scenes/cornell/cornell.json new file mode 100644 index 00000000..1e736638 --- /dev/null +++ b/bin/data/scenes/cornell/cornell.json @@ -0,0 +1,36 @@ +{ + "import": "/model.json", + "assets": [ + // { "filename": "./models/cornell.glb" } + // { "filename": "./models/cornell/graph.json" } + + // { "filename": "./models/sponza.glb" } + // { "filename": "./models/sponza/graph.json" } + + // { "filename": "./models/sponza-cornell.glb" } + { "filename": "./models/sponza-cornell/graph.json" } + ], + "metadata": { + "model": { + "baking": { + "enabled": false, + "resolution": 1024 + }, + "filter": "LINEAR", + "lightmap": false, + "tags": { + "/^Mesh_/": { + "physics": { "type": "mesh", "static": true }, + // "grid": { "size": [3,1,3], "epsilon": 0.0001, "cleanup": true, "print": true }, + // "optimize mesh": { "simplify": 0 }, + "unwrap mesh": true + }, + "Camera": { + "action": "attach", + "filename": "./player.json", + "preserve orientation": true + } + } + } + } +} \ No newline at end of file diff --git a/bin/data/scenes/cornell/loading.json b/bin/data/scenes/cornell/loading.json new file mode 100644 index 00000000..3a818433 --- /dev/null +++ b/bin/data/scenes/cornell/loading.json @@ -0,0 +1,32 @@ +{ + "name": "Gui: Loading", + "type": "Object", + "behaviors": [ + "GuiBehavior" + ], + "assets": [ + { "filename": "./cornell.json", "delay": 0 } + ], + "ignore": false, + "transform": { + "position": [ -0.830591, -0.699509, 0 ], + "rotation": { + "axis": [ 1, 0, 0 ], + "angle": 0 + }, + "scale": [ 0.258737, 0.115371, 1 ] + }, + "metadata": { + "uv": [ 0, 0, 1, 1 ], + "color": [ 1, 1, 1, 0.1 ], + "location": "", + "scaling": "relative", + "text settings": { + "stroke": [ 1, 0.749, 0.368, 1 ], + "color": [ 1, 0.749, 0.368, 1 ], + + "string": "Loading...", + "string1": "コマンド" + } + } +} \ No newline at end of file diff --git a/bin/data/scenes/cornell/player.json b/bin/data/scenes/cornell/player.json new file mode 100644 index 00000000..72aafad1 --- /dev/null +++ b/bin/data/scenes/cornell/player.json @@ -0,0 +1,27 @@ +{ + "import": "/player.json", + "assets": [ + // { "filename": "/gui/hud/hud.json", "delay": 0 } + ], + "system": { + "physics": { + "gravity": [ 0, 0, 0 ] + }, + "hot reload": { + "enabled": true + } + }, + "metadata": { + "overlay": { + "floating": true + }, + "collider": false, + "light": { + "should": false, + "color": [1, 1, 1], + "position": [ 0, 2.5, 0 ], + "power": 1, + "radius": [0.001, 32] + } + } +} \ No newline at end of file diff --git a/bin/data/scenes/cornell/scene.json b/bin/data/scenes/cornell/scene.json new file mode 100644 index 00000000..b14dd60d --- /dev/null +++ b/bin/data/scenes/cornell/scene.json @@ -0,0 +1,55 @@ +{ + "import": "/scene.json", + "assets": [ + "./loading.json" + ], + "system": { + "hot reload": { + "enabled": true + }, + "renderer": { + "clear values": [ + [ 0, 0, 0, 0 ] + ], + "shader": { + "mode": 1, + "scalar": 16, + "parameters": [ 0, 0, 0, "time" ] + } + } + }, + "metadata": { + "menus": { + "pause": "/gui/pause/menu.json" + }, + "bloom": { + "scale": 1.0, + "strength": 0.125, + "sigma": 0.8, + "samples": 5 + }, + "light": { + "exposure": 1.0, + "gamma": 1.0, + "brightnessThreshold": 1.2, + + // "ambient": [ 0.0, 0.0, 0.0 ], + "ambient": [ 0.5, 0.5, 0.5 ], + + "fog": { + "color": [ 0.025, 0.025, 0.1 ], + "step scale": 0.0, + "range": [ 1, 1 ], + "absorbtion": 0.85, + "density": { + "threshold": 0.5, + "multiplier": 5.0, + "scale": 50.0, + "offset": "time" + } + }, + "should": true, + "shadows": true + } + } +} \ No newline at end of file diff --git a/bin/data/scenes/mcdonalds/mcdonalds.json b/bin/data/scenes/mcdonalds/mcdonalds.json index 5929cc57..7273734b 100644 --- a/bin/data/scenes/mcdonalds/mcdonalds.json +++ b/bin/data/scenes/mcdonalds/mcdonalds.json @@ -22,8 +22,8 @@ "tags": { "/^worldspawn/": { "physics": { "type": "mesh", "static": true }, - "grid": { "size": [4,1,4], "epsilon": 1.0, "cleanup": true, "print": true }, - "optimize mesh": { "simplify": 0 }, + // "grid": { "size": [4,1,4], "epsilon": 1.0, "cleanup": true, "print": true }, + // "optimize mesh": { "simplify": 0 }, "unwrap mesh": true }, "info_player_spawn": { "action": "attach", "filename": "./player.json", "preserve orientation": true }, diff --git a/bin/data/scenes/mcdonalds/scene.json b/bin/data/scenes/mcdonalds/scene.json index b2b02dae..7e415b6a 100644 --- a/bin/data/scenes/mcdonalds/scene.json +++ b/bin/data/scenes/mcdonalds/scene.json @@ -35,7 +35,8 @@ "gamma": 1.0, "brightnessThreshold": 1.2, // "ambient": [ 0, 0, 0 ], - "ambient": [ 0.025, 0.025, 0.025 ], + // "ambient": [ 0.025, 0.025, 0.025 ], + "ambient": [ 0.075, 0.075, 0.075 ], // "ambient": [ 0.1, 0.1, 0.1 ], // "ambient": [ 0.4, 0.4, 0.4 ], diff --git a/bin/data/scenes/ss2/medsci.json b/bin/data/scenes/ss2/medsci.json index bab160cd..80b66296 100644 --- a/bin/data/scenes/ss2/medsci.json +++ b/bin/data/scenes/ss2/medsci.json @@ -5,7 +5,7 @@ // { "filename": "./test.json", "delay": 1 }, // { "filename": "./models/tiny_msci.glb" } - { "filename": "./models/tiny_msci/graph.json" } + // { "filename": "./models/tiny_msci/graph.json" } // { "filename": "./models/micro_sci.glb" } // { "filename": "./models/micro_sci/graph.json" } @@ -14,7 +14,7 @@ // { "filename": "./models/msci/graph.json" } // { "filename": "./models/medsci.glb" } - // { "filename": "./models/medsci/graph.json" } + { "filename": "./models/medsci/graph.json" } ], "metadata": { "model": { diff --git a/bin/data/shaders/common/macros.h b/bin/data/shaders/common/macros.h index 6abe4b8a..5dd85b17 100644 --- a/bin/data/shaders/common/macros.h +++ b/bin/data/shaders/common/macros.h @@ -54,6 +54,8 @@ #if ADDRESS_ENABLED #extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable +// #extension GL_EXT_shader_explicit_arithmetic_types_int16 : enable +// #extension GL_EXT_shader_explicit_arithmetic_types_int8 : enable #endif const float PI = 3.14159265359; diff --git a/bin/data/shaders/common/pbr.h b/bin/data/shaders/common/pbr.h index 4965e485..662787e0 100644 --- a/bin/data/shaders/common/pbr.h +++ b/bin/data/shaders/common/pbr.h @@ -13,7 +13,7 @@ float gaSchlickGGX(float cosLi, float cosLo, float roughness) { return gaSchlickG1(cosLi, k) * gaSchlickG1(cosLo, k); } vec3 fresnelSchlick(vec3 F0, float cosTheta) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); } -#if !BAKING && !COMPUTE +#if (!BAKING && !COMPUTE) || RAYTRACE void pbr() { if ( bool(ubo.useLightmaps) && validTextureIndex( surface.instance.lightmapID ) ) return; diff --git a/bin/data/shaders/common/structs.h b/bin/data/shaders/common/structs.h index 2e91443c..67299f9f 100644 --- a/bin/data/shaders/common/structs.h +++ b/bin/data/shaders/common/structs.h @@ -140,6 +140,10 @@ struct Instance { struct InstanceAddresses { uint64_t vertex; uint64_t index; + + uint64_t indirect; + uint drawID; + uint padding0; uint64_t position; uint64_t uv; @@ -154,7 +158,7 @@ struct InstanceAddresses { uint64_t weights; uint64_t id; - uint64_t padding; + uint64_t padding1; }; #endif @@ -221,4 +225,30 @@ struct VoxelInfo { float mipmapLevels; float radianceSize; float radianceSizeRecip; -} voxelInfo; \ No newline at end of file +} voxelInfo; + +// Raytrace stuff + +struct Vertex { + vec3 position; + vec2 uv; + uint color; + vec2 st; + vec3 normal; + vec3 tangent; + uvec2 joints; + vec4 weights; + uint id; +}; + +struct Triangle { + uvec3 indices; + Vertex points[3]; + Vertex point; +}; + +struct RayTracePayload { + bool hit; + uint instanceID; + Triangle triangle; +}; \ No newline at end of file diff --git a/bin/data/shaders/display/subpass.h b/bin/data/shaders/display/subpass.h index 6607891f..b0440288 100644 --- a/bin/data/shaders/display/subpass.h +++ b/bin/data/shaders/display/subpass.h @@ -62,7 +62,7 @@ layout (binding = 5) uniform UBO { uint msaa; uint shadowSamples; - uint indexSkybox; + int indexSkybox; uint useLightmaps; uint padding2; uint padding3; @@ -194,7 +194,9 @@ void populateSurface() { const uint drawID = ID.x - 1; const uint instanceID = ID.y - 1; if ( ID.x == 0 || ID.y == 0 ) { - surface.fragment.rgb = texture( samplerCubemaps[ubo.indexSkybox], surface.ray.direction ).rgb; + if ( 0 <= ubo.indexSkybox && ubo.indexSkybox < CUBEMAPS ) { + surface.fragment.rgb = texture( samplerCubemaps[ubo.indexSkybox], surface.ray.direction ).rgb; + } surface.fragment.a = 0.0; postProcess(); return; diff --git a/bin/data/shaders/graph/baking/bake.frag.glsl b/bin/data/shaders/graph/baking/bake.frag.glsl index f91458e3..52bae058 100644 --- a/bin/data/shaders/graph/baking/bake.frag.glsl +++ b/bin/data/shaders/graph/baking/bake.frag.glsl @@ -56,13 +56,13 @@ void main() { const uint instanceID = uint(inId.y); const uint materialID = uint(inId.z); - vec4 A = vec4(1, 1, 1, 1); surface.normal.world = normalize( inNormal ); surface.uv.xy = wrap(inUv.xy); surface.uv.z = mipLevel(dFdx(inUv), dFdy(inUv)); surface.position.world = inPosition; const Material material = materials[materialID]; + vec4 A = material.colorBase; surface.material.metallic = material.factorMetallic; surface.material.roughness = material.factorRoughness; surface.material.occlusion = 1.0f - material.factorOcclusion; diff --git a/bin/data/shaders/graph/base.frag.h b/bin/data/shaders/graph/base.frag.h index 12180284..54b28a54 100644 --- a/bin/data/shaders/graph/base.frag.h +++ b/bin/data/shaders/graph/base.frag.h @@ -59,12 +59,13 @@ void main() { const Instance instance = instances[instanceID]; const Material material = materials[materialID]; + A = material.colorBase; float M = material.factorMetallic; float R = material.factorRoughness; float AO = material.factorOcclusion; // sample albedo - if ( !validTextureIndex( material.indexAlbedo ) ) discard; { + if ( validTextureIndex( material.indexAlbedo ) ) { A = sampleTexture( material.indexAlbedo ); // alpha mode OPAQUE if ( material.modeAlpha == 0 ) { diff --git a/bin/data/shaders/graph/depth.frag.glsl b/bin/data/shaders/graph/depth.frag.glsl index 7ebdadd6..446a1756 100644 --- a/bin/data/shaders/graph/depth.frag.glsl +++ b/bin/data/shaders/graph/depth.frag.glsl @@ -36,13 +36,15 @@ void main() { const uint instanceID = uint(inId.y); const uint materialID = uint(inId.z); const vec2 uv = wrap(inUv.xy); - vec4 A = vec4(0, 0, 0, 0); + + const Material material = materials[materialID]; + vec4 A = material.colorBase; surface.uv.xy = uv; surface.uv.z = mipLevel(dFdx(inUv), dFdy(inUv)); - const Material material = materials[materialID]; // sample albedo - if ( !validTextureIndex( material.indexAlbedo ) ) discard; { +// if ( !validTextureIndex( material.indexAlbedo ) ) discard; { + if ( validTextureIndex( material.indexAlbedo ) ) { // const Texture t = textures[material.indexAlbedo]; // A = textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ), mip ); A = sampleTexture( material.indexAlbedo ); diff --git a/bin/data/shaders/graph/voxelize.frag.h b/bin/data/shaders/graph/voxelize.frag.h index 168e50f3..85da9275 100644 --- a/bin/data/shaders/graph/voxelize.frag.h +++ b/bin/data/shaders/graph/voxelize.frag.h @@ -69,18 +69,18 @@ void main() { surface.st.z = mipLevel(dFdx(inSt), dFdy(inSt)); vec3 N = inNormal; - vec4 A = vec4(0, 0, 0, 0); const Instance instance = instances[instanceID]; const Material material = materials[materialID]; surface.instance = instance; + vec4 A = material.colorBase; float M = material.factorMetallic; float R = material.factorRoughness; float AO = material.factorOcclusion; // sample albedo - if ( !validTextureIndex( material.indexAlbedo ) ) discard; { + if ( validTextureIndex( material.indexAlbedo ) ) { A = sampleTexture( material.indexAlbedo ); // alpha mode OPAQUE if ( material.modeAlpha == 0 ) { diff --git a/bin/data/shaders/raytrace/shader.gen.glsl b/bin/data/shaders/raytrace/shader.gen.glsl deleted file mode 100644 index dd0b6531..00000000 --- a/bin/data/shaders/raytrace/shader.gen.glsl +++ /dev/null @@ -1,47 +0,0 @@ -#version 460 -#extension GL_EXT_ray_tracing : enable -#pragma shader_stage(raygen) -layout (constant_id = 0) const uint PASSES = 2; - -#include "../common/macros.h" -#include "../common/structs.h" - -layout (binding = 0) uniform UBO { - EyeMatrices eyes[2]; -} ubo; -layout (binding = 1) uniform accelerationStructureEXT inTlas; -layout (binding = 2, rgba8) uniform volatile coherent image2D outImage; - -layout (location = 0) rayPayloadEXT vec4 hitValue; - -layout( push_constant ) uniform PushBlock { - uint pass; - uint draw; -} PushConstant; - -void main() { - { - surface.pass = PushConstant.pass; - - const vec2 inUv = (vec2(gl_LaunchIDEXT.xy) + vec2(0.5)) / vec2(gl_LaunchSizeEXT.xy); - - const mat4 iProjectionView = inverse( ubo.eyes[surface.pass].projection * mat4(mat3(ubo.eyes[surface.pass].view)) ); - const vec4 near4 = iProjectionView * (vec4(2.0 * inUv - 1.0, -1.0, 1.0)); - const vec4 far4 = iProjectionView * (vec4(2.0 * inUv - 1.0, 1.0, 1.0)); - const vec3 near3 = near4.xyz / near4.w; - const vec3 far3 = far4.xyz / far4.w; - - surface.ray.direction = normalize( far3 - near3 ); - surface.ray.origin = ubo.eyes[surface.pass].eyePos.xyz; - } - - uint rayFlags = gl_RayFlagsOpaqueEXT; - uint cullMask = 0xFF; - float tMin = 0.001; - float tMax = 10000.0; - - hitValue = vec4(0); - traceRayEXT(inTlas, rayFlags, cullMask, 0, 0, 0, surface.ray.origin.xyz, tMin, surface.ray.direction.xyz, tMax, 0); - - imageStore(outImage, ivec2(gl_LaunchIDEXT.xy), vec4(hitValue)); -} \ No newline at end of file diff --git a/bin/data/shaders/raytrace/shader.hit.glsl b/bin/data/shaders/raytrace/shader.hit.glsl deleted file mode 100644 index 6e4879cb..00000000 --- a/bin/data/shaders/raytrace/shader.hit.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#version 460 -#extension GL_EXT_ray_tracing : enable -#extension GL_EXT_nonuniform_qualifier : enable -#pragma shader_stage(closest) - -layout(location = 0) rayPayloadInEXT vec4 hitValue; -hitAttributeEXT vec2 attribs; - -void main() { - const vec3 barycentricCoords = vec3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y); - hitValue = vec4(barycentricCoords, 1.0); -} \ No newline at end of file diff --git a/bin/data/shaders/raytrace/shader.miss.glsl b/bin/data/shaders/raytrace/shader.miss.glsl deleted file mode 100644 index 73866f8d..00000000 --- a/bin/data/shaders/raytrace/shader.miss.glsl +++ /dev/null @@ -1,9 +0,0 @@ -#version 460 -#extension GL_EXT_ray_tracing : enable -#pragma shader_stage(miss) - -layout(location = 0) rayPayloadInEXT vec4 hitValue; - -void main() { - hitValue = vec4(0.2, 0.2, 0.2, 0.0); -} \ No newline at end of file diff --git a/bin/data/shaders/raytrace/shader.ray-gen.glsl b/bin/data/shaders/raytrace/shader.ray-gen.glsl new file mode 100644 index 00000000..71b2abb8 --- /dev/null +++ b/bin/data/shaders/raytrace/shader.ray-gen.glsl @@ -0,0 +1,280 @@ +#version 460 +#extension GL_EXT_ray_tracing : enable +#pragma shader_stage(raygen) +layout (constant_id = 0) const uint PASSES = 2; +layout (constant_id = 1) const uint TEXTURES = 512; +layout (constant_id = 2) const uint CUBEMAPS = 128; +layout (constant_id = 3) const uint CASCADES = 4; + +#define ADDRESS_ENABLED 1 +#define COMPUTE 1 +#define PBR 1 +#define VXGI 0 +#define RAYTRACE 1 +#define FOG 0 +#define WHITENOISE 0 +#define MAX_TEXTURES TEXTURES + +#include "../common/macros.h" +#include "../common/structs.h" + +layout( push_constant ) uniform PushBlock { + uint pass; + uint draw; +} PushConstant; + +layout (binding = 0) uniform accelerationStructureEXT tlas; + +layout (binding = 1, rgba8) uniform volatile coherent image2D outImage; + +layout (binding = 2) uniform UBO { + EyeMatrices eyes[2]; + + Mode mode; + Fog fog; + Vxgi vxgi; + + uint lights; + uint materials; + uint textures; + uint drawCommands; + + vec3 ambient; + float gamma; + + float exposure; + float brightnessThreshold; + uint msaa; + uint shadowSamples; + + int indexSkybox; + uint useLightmaps; + uint padding2; + uint padding3; +} ubo; + +layout (std140, binding = 3) readonly buffer Instances { + Instance instances[]; +}; +layout (std140, binding = 4) readonly buffer Materials { + Material materials[]; +}; +layout (std140, binding = 5) readonly buffer Textures { + Texture textures[]; +}; +layout (std140, binding = 6) readonly buffer Lights { + Light lights[]; +}; + +layout (binding = 7) uniform sampler2D samplerTextures[TEXTURES]; +layout (binding = 8) uniform samplerCube samplerCubemaps[CUBEMAPS]; + +#if VXGI + layout (binding = 14) uniform usampler3D voxelId[CASCADES]; + layout (binding = 15) uniform sampler3D voxelNormal[CASCADES]; + layout (binding = 16) uniform sampler3D voxelRadiance[CASCADES]; +#endif + +layout (location = 0) rayPayloadEXT RayTracePayload payload; + +#include "../common/functions.h" +#include "../common/light.h" +#if VXGI + #include "../common/vxgi.h" +#endif + +float shadowFactor( const Light light, float def ) { + + Ray ray; + ray.origin = surface.position.world; + ray.direction = light.position - ray.origin; + + uint rayFlags = gl_RayFlagsOpaqueEXT | gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsSkipClosestHitShaderEXT; + uint cullMask = 0xFF; + float tMin = 0.125; + float tMax = length(ray.direction) - 1; + + ray.direction = normalize(ray.direction); + + payload.hit = true; + traceRayEXT(tlas, rayFlags, cullMask, 0, 0, 0, ray.origin.xyz, tMin, ray.direction.xyz, tMax, 0); + + return payload.hit ? 0.0 : 1.0; +} + +void processHit( uint instanceID, Triangle triangle ) { + const Instance instance = instances[instanceID]; + surface.instance = instance; + + surface.pass = 0; + surface.fragment = vec4(0); + surface.light = vec4(0); + + // bind position + { + surface.position.world = vec3( instance.model * vec4(triangle.point.position, 1.0 ) ); + surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.position.world, 1.0) ); + } + // bind normals + { + surface.normal.world = vec3( instance.model * vec4(triangle.point.normal, 0.0 ) ); + surface.normal.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) ); + } + // bind UVs + { + surface.uv.xy = triangle.point.uv; + surface.st.xy = triangle.point.st; + } + + const Material material = materials[surface.instance.materialID]; + surface.material.albedo = material.colorBase; + surface.material.metallic = material.factorMetallic; + surface.material.roughness = material.factorRoughness; + surface.material.occlusion = material.factorOcclusion; + surface.fragment = material.colorEmissive; + + + if ( validTextureIndex( material.indexAlbedo ) ) { + surface.material.albedo = sampleTexture( material.indexAlbedo ); + } + // OPAQUE + if ( material.modeAlpha == 0 ) { + surface.material.albedo.a = 1; + // BLEND + } else if ( material.modeAlpha == 1 ) { + + // MASK + } else if ( material.modeAlpha == 2 ) { + + } + // Lightmap + if ( bool(ubo.useLightmaps) && validTextureIndex( surface.instance.lightmapID ) ) { + surface.light += surface.material.albedo * sampleTexture( surface.instance.lightmapID, surface.st ); + } + // Emissive textures + if ( validTextureIndex( material.indexEmissive ) ) { + surface.light += sampleTexture( material.indexEmissive ); + } + // Occlusion map + if ( validTextureIndex( material.indexOcclusion ) ) { + surface.material.occlusion = sampleTexture( material.indexOcclusion ).r; + } + // Metallic/Roughness map + if ( validTextureIndex( material.indexMetallicRoughness ) ) { + vec4 samp = sampleTexture( material.indexMetallicRoughness ); + surface.material.metallic = samp.r; + surface.material.roughness = samp.g; + } +#if VXGI + { + indirectLighting(); + } +#endif + + { + surface.light.rgb += surface.material.albedo.rgb * ubo.ambient.rgb * surface.material.occlusion; // add ambient lighting + surface.light.rgb += surface.material.indirect.rgb; // add indirect lighting + #if PBR + pbr(); + #endif + surface.fragment.rgb += surface.light.rgb; + surface.fragment.a = surface.material.albedo.a; + } +} + +void trace( float tMin, float tMax ) { + uint rayFlags = gl_RayFlagsOpaqueEXT; + uint cullMask = 0xFF; + + payload.hit = false; + traceRayEXT(tlas, rayFlags, cullMask, 0, 0, 0, surface.ray.origin.xyz, tMin, surface.ray.direction.xyz, tMax, 0); +} + +void main() { + { + surface.fragment = vec4(0); + surface.pass = PushConstant.pass; + + const vec2 inUv = (vec2(gl_LaunchIDEXT.xy) + vec2(0.5)) / vec2(gl_LaunchSizeEXT.xy); + + const mat4 iProjectionView = inverse( ubo.eyes[surface.pass].projection * mat4(mat3(ubo.eyes[surface.pass].view)) ); + const vec4 near4 = iProjectionView * (vec4(2.0 * inUv - 1.0, -1.0, 1.0)); + const vec4 far4 = iProjectionView * (vec4(2.0 * inUv - 1.0, 1.0, 1.0)); + const vec3 near3 = near4.xyz / near4.w; + const vec3 far3 = far4.xyz / far4.w; + + surface.ray.direction = normalize( far3 - near3 ); + surface.ray.origin = ubo.eyes[surface.pass].eyePos.xyz; + } + + trace( 0.001, 4096.0 ); + + if ( payload.hit ) { + processHit( payload.instanceID, payload.triangle ); + #if 1 + + uint tries = 8; + while ( 0 < surface.material.metallic && --tries > 0 ) { + vec4 back = surface.fragment; + surface.fragment = vec4(0); + + surface.ray.direction = reflect( normalize(surface.position.world - surface.ray.origin), surface.normal.world ); + surface.ray.origin = surface.position.world; + + trace( 0.01, 4096.0 ); + + if ( payload.hit ) { + processHit( payload.instanceID, payload.triangle ); + vec4 front = surface.fragment; + surface.fragment = mix( front, back, surface.material.metallic ); + // surface.fragment.rgb = front.rgb * front.a + back.rgb * back.a; + } else { + surface.fragment = back; + } + } + #endif + #if 0 + if ( surface.fragment.a < 1.0 ) { + vec4 back = surface.fragment; + surface.fragment = vec4(0); + + surface.ray.origin = surface.position.world; + + trace( 0.01, 4096.0 ); + + if ( payload.hit ) { + processHit( payload.instanceID, payload.triangle ); + vec4 front = surface.fragment; + + // surface.fragment = mix( front, back, back.a ); + surface.fragment.rgb = front.rgb * front.a + back.rgb * back.a; + } else { + surface.fragment = back; + } + } + #endif + } else if ( 0 <= ubo.indexSkybox && ubo.indexSkybox < CUBEMAPS ) { + surface.fragment.rgb = texture( samplerCubemaps[ubo.indexSkybox], surface.ray.direction ).rgb; + } + + { + surface.fragment.a = 1; + // float brightness = dot(surface.fragment.rgb, vec3(0.2126, 0.7152, 0.0722)); + // outFragBright = brightness > ubo.brightnessThreshold ? vec4(surface.fragment.rgb, 1.0) : vec4(0, 0, 0, 1); + + #if FOG + fog( surface.ray, surface.fragment.rgb, surface.fragment.a ); + #endif + #if TONE_MAP + surface.fragment.rgb = vec3(1.0) - exp(-surface.fragment.rgb * ubo.exposure); + #endif + #if GAMMA_CORRECT + surface.fragment.rgb = pow(surface.fragment.rgb, vec3(1.0 / ubo.gamma)); + #endif + #if WHITENOISE + if ( enabled(ubo.mode.type, 1) ) whitenoise(surface.fragment.rgb, ubo.mode.parameters); + #endif + + imageStore(outImage, ivec2(gl_LaunchIDEXT.xy), surface.fragment); + } +} \ No newline at end of file diff --git a/bin/data/shaders/raytrace/shader.ray-hit-any.glsl b/bin/data/shaders/raytrace/shader.ray-hit-any.glsl new file mode 100644 index 00000000..9dcd62c0 --- /dev/null +++ b/bin/data/shaders/raytrace/shader.ray-hit-any.glsl @@ -0,0 +1,91 @@ +#version 460 +#extension GL_EXT_ray_tracing : enable +#extension GL_EXT_nonuniform_qualifier : enable +#extension GL_EXT_buffer_reference : enable +#extension GL_EXT_buffer_reference2 : enable +#extension GL_EXT_scalar_block_layout : enable +#pragma shader_stage(anyhit) +layout (constant_id = 0) const uint PASSES = 2; +layout (constant_id = 1) const uint TEXTURES = 512; +layout (constant_id = 2) const uint CUBEMAPS = 128; + +#define ADDRESS_ENABLED 1 +#define COMPUTE 1 +#define PBR 1 +#define RAYTRACE 1 +#define MAX_TEXTURES TEXTURES + +#include "../common/macros.h" +#include "../common/structs.h" + +layout (std140, binding = 10) readonly buffer InstanceAddresseses { + InstanceAddresses instanceAddresses[]; +}; + +layout(buffer_reference, scalar) buffer Vertices { Vertex v[]; }; +layout(buffer_reference, scalar) buffer Indices { uvec3 i[]; }; +layout(buffer_reference, scalar) buffer Indirects { DrawCommand dc[]; }; + +layout(buffer_reference, scalar) buffer VPos { vec3 v[]; }; +layout(buffer_reference, scalar) buffer VUv { vec2 v[]; }; +layout(buffer_reference, scalar) buffer VColor { uint v[]; }; +layout(buffer_reference, scalar) buffer VSt { vec2 v[]; }; +layout(buffer_reference, scalar) buffer VNormal { vec3 v[]; }; +layout(buffer_reference, scalar) buffer VTangent { vec3 v[]; }; +layout(buffer_reference, scalar) buffer VID { uint v[]; }; + +layout(location = 0) rayPayloadInEXT RayTracePayload payload; + +hitAttributeEXT vec2 attribs; + +void main() { + const vec3 bary = vec3( + 1.0 - attribs.x - attribs.y, + attribs.x, + attribs.y + ); + + const uint instanceID = gl_InstanceCustomIndexEXT; + + const InstanceAddresses instanceAddresses = instanceAddresses[instanceID]; + + if ( !(0 < instanceAddresses.index) ) return; + + const DrawCommand drawCommand = Indirects(nonuniformEXT(instanceAddresses.indirect)).dc[instanceAddresses.drawID]; + const uint triangleID = gl_PrimitiveID + (drawCommand.indexID / 3); + + Triangle triangle; + triangle.indices = Indices(nonuniformEXT(instanceAddresses.index)).i[triangleID]; + for ( uint _ = 0; _ < 3; ++_ ) triangle.indices[_] += drawCommand.vertexID; + + if ( 0 < instanceAddresses.vertex ) { + Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex)); + for ( uint _ = 0; _ < 3; ++_ ) triangle.points[_] = vertices.v[triangle.indices[_]]; + } else { + if ( 0 < instanceAddresses.position ) { + VPos buf = VPos(nonuniformEXT(instanceAddresses.position)); + for ( uint _ = 0; _ < 3; ++_ ) triangle.points[_].position = buf.v[triangle.indices[_]]; + } + if ( 0 < instanceAddresses.uv ) { + VUv buf = VUv(nonuniformEXT(instanceAddresses.uv)); + for ( uint _ = 0; _ < 3; ++_ ) triangle.points[_].uv = buf.v[triangle.indices[_]]; + } + if ( 0 < instanceAddresses.st ) { + VSt buf = VSt(nonuniformEXT(instanceAddresses.st)); + for ( uint _ = 0; _ < 3; ++_ ) triangle.points[_].st = buf.v[triangle.indices[_]]; + } + if ( 0 < instanceAddresses.normal ) { + VNormal buf = VNormal(nonuniformEXT(instanceAddresses.normal)); + for ( uint _ = 0; _ < 3; ++_ ) triangle.points[_].normal = buf.v[triangle.indices[_]]; + } + } + + triangle.point.position = triangle.points[0].position * bary[0] + triangle.points[1].position * bary[1] + triangle.points[2].position * bary[2]; + triangle.point.uv = triangle.points[0].uv * bary[0] + triangle.points[1].uv * bary[1] + triangle.points[2].uv * bary[2]; + triangle.point.st = triangle.points[0].st * bary[0] + triangle.points[1].st * bary[1] + triangle.points[2].st * bary[2]; + triangle.point.normal = triangle.points[0].normal * bary[0] + triangle.points[1].normal * bary[1] + triangle.points[2].normal * bary[2]; + + payload.hit = true; + payload.instanceID = instanceID; + payload.triangle = triangle; +} \ No newline at end of file diff --git a/bin/data/shaders/raytrace/shader.ray-hit-closest.glsl b/bin/data/shaders/raytrace/shader.ray-hit-closest.glsl new file mode 100644 index 00000000..53edc6c9 --- /dev/null +++ b/bin/data/shaders/raytrace/shader.ray-hit-closest.glsl @@ -0,0 +1,91 @@ +#version 460 +#extension GL_EXT_ray_tracing : enable +#extension GL_EXT_nonuniform_qualifier : enable +#extension GL_EXT_buffer_reference : enable +#extension GL_EXT_buffer_reference2 : enable +#extension GL_EXT_scalar_block_layout : enable +#pragma shader_stage(closest) +layout (constant_id = 0) const uint PASSES = 2; +layout (constant_id = 1) const uint TEXTURES = 512; +layout (constant_id = 2) const uint CUBEMAPS = 128; + +#define ADDRESS_ENABLED 1 +#define COMPUTE 1 +#define PBR 1 +#define RAYTRACE 1 +#define MAX_TEXTURES TEXTURES + +#include "../common/macros.h" +#include "../common/structs.h" + +layout (std140, binding = 9) readonly buffer InstanceAddresseses { + InstanceAddresses instanceAddresses[]; +}; + +layout(buffer_reference, scalar) buffer Vertices { Vertex v[]; }; +layout(buffer_reference, scalar) buffer Indices { uvec3 i[]; }; +layout(buffer_reference, scalar) buffer Indirects { DrawCommand dc[]; }; + +layout(buffer_reference, scalar) buffer VPos { vec3 v[]; }; +layout(buffer_reference, scalar) buffer VUv { vec2 v[]; }; +layout(buffer_reference, scalar) buffer VColor { uint v[]; }; +layout(buffer_reference, scalar) buffer VSt { vec2 v[]; }; +layout(buffer_reference, scalar) buffer VNormal { vec3 v[]; }; +layout(buffer_reference, scalar) buffer VTangent { vec3 v[]; }; +layout(buffer_reference, scalar) buffer VID { uint v[]; }; + +layout(location = 0) rayPayloadInEXT RayTracePayload payload; + +hitAttributeEXT vec2 attribs; + +void main() { + const vec3 bary = vec3( + 1.0 - attribs.x - attribs.y, + attribs.x, + attribs.y + ); + + const uint instanceID = gl_InstanceCustomIndexEXT; + + const InstanceAddresses instanceAddresses = instanceAddresses[instanceID]; + + if ( !(0 < instanceAddresses.index) ) return; + + const DrawCommand drawCommand = Indirects(nonuniformEXT(instanceAddresses.indirect)).dc[instanceAddresses.drawID]; + const uint triangleID = gl_PrimitiveID + (drawCommand.indexID / 3); + + Triangle triangle; + triangle.indices = Indices(nonuniformEXT(instanceAddresses.index)).i[triangleID]; + for ( uint _ = 0; _ < 3; ++_ ) triangle.indices[_] += drawCommand.vertexID; + + if ( 0 < instanceAddresses.vertex ) { + Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex)); + for ( uint _ = 0; _ < 3; ++_ ) triangle.points[_] = vertices.v[triangle.indices[_]]; + } else { + if ( 0 < instanceAddresses.position ) { + VPos buf = VPos(nonuniformEXT(instanceAddresses.position)); + for ( uint _ = 0; _ < 3; ++_ ) triangle.points[_].position = buf.v[triangle.indices[_]]; + } + if ( 0 < instanceAddresses.uv ) { + VUv buf = VUv(nonuniformEXT(instanceAddresses.uv)); + for ( uint _ = 0; _ < 3; ++_ ) triangle.points[_].uv = buf.v[triangle.indices[_]]; + } + if ( 0 < instanceAddresses.st ) { + VSt buf = VSt(nonuniformEXT(instanceAddresses.st)); + for ( uint _ = 0; _ < 3; ++_ ) triangle.points[_].st = buf.v[triangle.indices[_]]; + } + if ( 0 < instanceAddresses.normal ) { + VNormal buf = VNormal(nonuniformEXT(instanceAddresses.normal)); + for ( uint _ = 0; _ < 3; ++_ ) triangle.points[_].normal = buf.v[triangle.indices[_]]; + } + } + + triangle.point.position = triangle.points[0].position * bary[0] + triangle.points[1].position * bary[1] + triangle.points[2].position * bary[2]; + triangle.point.uv = triangle.points[0].uv * bary[0] + triangle.points[1].uv * bary[1] + triangle.points[2].uv * bary[2]; + triangle.point.st = triangle.points[0].st * bary[0] + triangle.points[1].st * bary[1] + triangle.points[2].st * bary[2]; + triangle.point.normal = triangle.points[0].normal * bary[0] + triangle.points[1].normal * bary[1] + triangle.points[2].normal * bary[2]; + + payload.hit = true; + payload.instanceID = instanceID; + payload.triangle = triangle; +} \ No newline at end of file diff --git a/bin/data/shaders/raytrace/shader.ray-miss.glsl b/bin/data/shaders/raytrace/shader.ray-miss.glsl new file mode 100644 index 00000000..9aa2161d --- /dev/null +++ b/bin/data/shaders/raytrace/shader.ray-miss.glsl @@ -0,0 +1,18 @@ +#version 460 +#extension GL_EXT_ray_tracing : enable +#pragma shader_stage(miss) + +#define ADDRESS_ENABLED 1 +#define COMPUTE 1 +#define PBR 1 +#define RAYTRACE 1 +#define MAX_TEXTURES TEXTURES + +#include "../common/macros.h" +#include "../common/structs.h" + +layout(location = 0) rayPayloadInEXT RayTracePayload payload; + +void main() { + payload.hit = false; +} \ No newline at end of file diff --git a/engine/inc/uf/utils/component/component.h b/engine/inc/uf/utils/component/component.h index 0daaba5c..f7430dcd 100644 --- a/engine/inc/uf/utils/component/component.h +++ b/engine/inc/uf/utils/component/component.h @@ -7,7 +7,7 @@ #include #include -#define UF_COMPONENT_POINTERED_USERDATA 0 +#define UF_COMPONENT_POINTERED_USERDATA 1 // namespace pod { struct UF_API Component { diff --git a/engine/inc/uf/utils/mesh/mesh.h b/engine/inc/uf/utils/mesh/mesh.h index d541b636..965069fc 100644 --- a/engine/inc/uf/utils/mesh/mesh.h +++ b/engine/inc/uf/utils/mesh/mesh.h @@ -86,6 +86,10 @@ namespace pod { alignas(8) uint64_t vertex{}; alignas(8) uint64_t index{}; + alignas(8) uint64_t indirect{}; + alignas(4) uint32_t drawID{}; + alignas(4) uint32_t padding0{}; + alignas(8) uint64_t position{}; alignas(8) uint64_t uv{}; @@ -99,7 +103,7 @@ namespace pod { alignas(8) uint64_t weights{}; alignas(8) uint64_t id{}; - alignas(8) uint64_t padding{}; + alignas(8) uint64_t padding1{}; }; struct Primitive { diff --git a/engine/src/engine/asset/asset.cpp b/engine/src/engine/asset/asset.cpp index 0f502f11..cd830cb0 100644 --- a/engine/src/engine/asset/asset.cpp +++ b/engine/src/engine/asset/asset.cpp @@ -264,7 +264,7 @@ uf::stl::string uf::Asset::load(const uf::Asset::Payload& payload ) { asset = uf::graph::load( filename, metadata[payload.filename] ); uf::graph::process( asset ); #if !UF_ENV_DREAMCAST - if ( asset.metadata["debug"]["print stats"].as() ) UF_MSG_INFO(uf::graph::stats( asset ).dump(1,'\t')); + if ( asset.metadata["debug"]["print stats"].as() ) UF_MSG_INFO(uf::graph::stats( asset )); if ( asset.metadata["debug"]["print tree"].as() ) UF_MSG_INFO(uf::graph::print( asset )); #endif if ( !asset.metadata["debug"]["no cleanup"].as() ) uf::graph::cleanup( asset ); diff --git a/engine/src/engine/graph/encode.cpp b/engine/src/engine/graph/encode.cpp index 06b50096..c6714d2b 100644 --- a/engine/src/engine/graph/encode.cpp +++ b/engine/src/engine/graph/encode.cpp @@ -464,7 +464,7 @@ uf::stl::string uf::graph::save( const pod::Graph& graph, const uf::stl::string& uf::stl::string uf::graph::print( const pod::Graph& graph ) { uf::stl::stringstream ss; -#if 0 +#if 1 ss << "Graph Data:" "\n\tImages: " << graph.images.size() << "" "\n\tTextures: " << graph.textures.size() << "" @@ -487,8 +487,8 @@ uf::stl::string uf::graph::print( const pod::Graph& graph ) { uf::Serializer uf::graph::stats( const pod::Graph& graph ) { ext::json::Value json; #if 0 - size_t memoryTextures = sizeof(pod::Texture::Storage) * graph.textures.size(); - size_t memoryMaterials = sizeof(pod::Material::Storage) * graph.materials.size(); + size_t memoryTextures = sizeof(pod::Texture) * graph.textures.size(); + size_t memoryMaterials = sizeof(pod::Material) * graph.materials.size(); size_t memoryLights = sizeof(pod::Light) * graph.lights.size(); size_t memoryImages = 0; size_t memoryMeshes = 0; diff --git a/engine/src/engine/graph/graph.cpp b/engine/src/engine/graph/graph.cpp index fe61f5e2..856ba746 100644 --- a/engine/src/engine/graph/graph.cpp +++ b/engine/src/engine/graph/graph.cpp @@ -359,25 +359,31 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M // grab addresses { pod::DrawCommand* drawCommands = (pod::DrawCommand*) mesh.getBuffer( mesh.indirect ).data(); - for ( size_t i = 0; i < mesh.indirect.count; ++i ) { - auto instanceID = drawCommands[i].instanceID; + for ( size_t drawID = 0; drawID < mesh.indirect.count; ++drawID ) { + auto& drawCommand = drawCommands[drawID]; + auto instanceID = drawCommand.instanceID; auto instanceKeyName = std::to_string(instanceID); + + if ( uf::graph::storage.instanceAddresses.map.count(instanceKeyName) > 0 ) { + UF_MSG_DEBUG("DUPLICATE INSTANCE ID"); + } + auto& instanceAddresses = uf::graph::storage.instanceAddresses.map[instanceKeyName]; if ( mesh.vertex.count ) { if ( mesh.isInterleaved( mesh.vertex ) ) { - instanceAddresses.vertex = graphic.buffers.at(graphic.descriptor.inputs.vertex.interleaved).getAddress(); + instanceAddresses.vertex = graphic.buffers.at(graphic.descriptor.inputs.vertex.interleaved).getAddress()/* + (drawCommand.vertexID * mesh.vertex.size)*/; } else { for ( auto& attribute : graphic.descriptor.inputs.vertex.attributes ) { if ( attribute.buffer < 0 ) continue; - if ( attribute.descriptor.name == "position" ) instanceAddresses.position = graphic.buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "uv" ) instanceAddresses.uv = graphic.buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "color" ) instanceAddresses.color = graphic.buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "st" ) instanceAddresses.st = graphic.buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "normal" ) instanceAddresses.normal = graphic.buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "tangent" ) instanceAddresses.tangent = graphic.buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "joints" ) instanceAddresses.joints = graphic.buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "weights" ) instanceAddresses.weights = graphic.buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "id" ) instanceAddresses.id = graphic.buffers.at(attribute.buffer).getAddress(); + if ( attribute.descriptor.name == "position" ) instanceAddresses.position = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/; + else if ( attribute.descriptor.name == "uv" ) instanceAddresses.uv = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/; + else if ( attribute.descriptor.name == "color" ) instanceAddresses.color = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/; + else if ( attribute.descriptor.name == "st" ) instanceAddresses.st = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/; + else if ( attribute.descriptor.name == "normal" ) instanceAddresses.normal = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/; + else if ( attribute.descriptor.name == "tangent" ) instanceAddresses.tangent = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/; + else if ( attribute.descriptor.name == "joints" ) instanceAddresses.joints = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/; + else if ( attribute.descriptor.name == "weights" ) instanceAddresses.weights = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/; + else if ( attribute.descriptor.name == "id" ) instanceAddresses.id = graphic.buffers.at(attribute.buffer).getAddress()/* + (drawCommand.vertexID * attribute.stride)*/; } } } @@ -385,6 +391,13 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M if ( mesh.isInterleaved( mesh.index ) ) instanceAddresses.index = graphic.buffers.at(graphic.descriptor.inputs.index.interleaved).getAddress(); else instanceAddresses.index = graphic.buffers.at(graphic.descriptor.inputs.index.attributes.front().buffer).getAddress(); } + + if ( mesh.indirect.count ) { + if ( mesh.isInterleaved( mesh.indirect ) ) instanceAddresses.indirect = graphic.buffers.at(graphic.descriptor.inputs.indirect.interleaved).getAddress(); + else instanceAddresses.indirect = graphic.buffers.at(graphic.descriptor.inputs.indirect.attributes.front().buffer).getAddress(); + + instanceAddresses.drawID = drawID; + } } } #endif @@ -717,6 +730,8 @@ void uf::graph::process( pod::Graph& graph ) { */ } + uf::graph::storage.instanceAddresses.keys = uf::graph::storage.instances.keys; + } void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent ) { auto& node = graph.nodes[index]; @@ -919,9 +934,6 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent ) pod::Vector3f center = (max + min) * 0.5f; pod::Vector3f corner = uf::vector::abs(max - min) * 0.5f; - // corner.x = abs(corner.x); - // corner.y = abs(corner.y); - // corner.z = abs(corner.z); metadataJson["system"]["physics"]["center"] = uf::vector::encode( center ); metadataJson["system"]["physics"]["corner"] = uf::vector::encode( corner ); diff --git a/engine/src/ext/gltf/gltf.cpp b/engine/src/ext/gltf/gltf.cpp index 3cc78302..9ab68fc4 100644 --- a/engine/src/ext/gltf/gltf.cpp +++ b/engine/src/ext/gltf/gltf.cpp @@ -482,7 +482,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize #endif #if UF_USE_MESHOPT // cleanup if blender's exporter is poopy - if ( graph.metadata["exporter"]["optimize"].as(true) || graph.metadata["exporter"]["optimize"].as("") == "tagged" ) { + if ( graph.metadata["exporter"]["optimize"].as(false) || graph.metadata["exporter"]["optimize"].as("") == "tagged" ) { UF_MSG_DEBUG( "Optimizing meshes..." ); for ( auto& keyName : graph.meshes ) { size_t level = SIZE_MAX; diff --git a/engine/src/ext/reactphysics/reactphysics.cpp b/engine/src/ext/reactphysics/reactphysics.cpp index c2919610..e5386c76 100644 --- a/engine/src/ext/reactphysics/reactphysics.cpp +++ b/engine/src/ext/reactphysics/reactphysics.cpp @@ -291,6 +291,10 @@ void ext::reactphysics::attach( pod::PhysicsState& state ) { state.body->setType(rp3d::BodyType::STATIC); } + if ( state.stats.gravity == pod::Vector3f{0,0,0} ) { + state.body->enableGravity(false); + } + auto& material = collider->getMaterial(); material.setBounciness(0); @@ -406,7 +410,13 @@ void ext::reactphysics::syncFrom( float interp ) { auto* body = ::world->getRigidBody(i); if ( !body ) continue; uf::Object* object = (uf::Object*) body->getUserData(); if ( !object ) continue; - auto& state = object->getComponent();; + auto& state = object->getComponent(); + + if ( !state.object ) { + state.object = object; + //continue; + } + auto& transform = state.object->getComponent>(); auto& physics = state.object->getComponent(); diff --git a/engine/src/ext/vulkan/buffer.cpp b/engine/src/ext/vulkan/buffer.cpp index 14449a10..ec104e25 100644 --- a/engine/src/ext/vulkan/buffer.cpp +++ b/engine/src/ext/vulkan/buffer.cpp @@ -123,8 +123,8 @@ void ext::vulkan::Buffer::initialize( const void* data, VkDeviceSize length, VkB if ( data && length ) update( data, length, stage ); } bool ext::vulkan::Buffer::update( const void* data, VkDeviceSize length, bool stage ) const { - if ( !data || !length ) return false; - +// if ( !data || !length ) return false; + if ( !length ) return false; if ( length > allocationInfo.size ) { UF_MSG_DEBUG("LENGTH OF " << length << " EXCEEDS BUFFER SIZE " << allocationInfo.size ); Buffer& b = *const_cast(this); @@ -132,6 +132,7 @@ bool ext::vulkan::Buffer::update( const void* data, VkDeviceSize length, bool st b.initialize( data, length, usage, memoryProperties, stage ); return true; } + if ( !data ) return false; if ( !stage ) { void* map = this->map(); memcpy(map, data, length); diff --git a/engine/src/ext/vulkan/graphic.cpp b/engine/src/ext/vulkan/graphic.cpp index d2ebf2bf..06acd9ee 100644 --- a/engine/src/ext/vulkan/graphic.cpp +++ b/engine/src/ext/vulkan/graphic.cpp @@ -425,7 +425,6 @@ void ext::vulkan::Pipeline::record( const Graphic& graphic, const GraphicDescrip vkCmdBindPipeline(commandBuffer, bindPoint, pipeline); if ( bindPoint == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR ) { - UF_MSG_DEBUG("vkCmdTraceRaysKHR"); uf::renderer::vkCmdTraceRaysKHR( commandBuffer, &sbtEntries[0], @@ -512,8 +511,7 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip } } - auto& textures = !shader->textures.empty() ? shader->textures : graphic.material.textures; - for ( auto& texture : textures ) { + for ( auto& texture : shader->textures ) { infos.image.emplace_back(texture.descriptor); switch ( texture.viewType ) { case VK_IMAGE_VIEW_TYPE_2D: infos.image2D.emplace_back(texture.descriptor); break; @@ -523,6 +521,17 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip default: infos.imageUnknown.emplace_back(texture.descriptor); break; } } + for ( auto& texture : graphic.material.textures ) { + infos.image.emplace_back(texture.descriptor); + switch ( texture.viewType ) { + case VK_IMAGE_VIEW_TYPE_2D: infos.image2D.emplace_back(texture.descriptor); break; + case VK_IMAGE_VIEW_TYPE_2D_ARRAY: infos.image2DA.emplace_back(texture.descriptor); break; + case VK_IMAGE_VIEW_TYPE_CUBE: infos.imageCube.emplace_back(texture.descriptor); break; + case VK_IMAGE_VIEW_TYPE_3D: infos.image3D.emplace_back(texture.descriptor); break; + default: infos.imageUnknown.emplace_back(texture.descriptor); break; + } + } + for ( auto& sampler : graphic.material.samplers ) { infos.sampler.emplace_back(sampler.descriptor.info); } @@ -1169,12 +1178,13 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() { indexInput.count = drawCommand.indices; auto& blasData = blasDatas.emplace_back(); + // blasData.as.drawID = i; blasData.as.instanceID = drawCommand.instanceID; VkAccelerationStructureGeometryKHR& asGeom = blasData.asGeom.emplace_back(); asGeom.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; asGeom.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; - asGeom.flags = VK_GEOMETRY_OPAQUE_BIT_KHR; + asGeom.flags = VK_GEOMETRY_OPAQUE_BIT_KHR | VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR; VkAccelerationStructureGeometryTrianglesDataKHR& triangles = asGeom.geometry.triangles; triangles.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR; @@ -1287,7 +1297,6 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() { blasBufferOffset += blasData.sizeInfo.accelerationStructureSize; - // UF_MSG_DEBUG("vkCreateAccelerationStructureKHR"); VK_CHECK_RESULT(uf::renderer::vkCreateAccelerationStructureKHR(device, &createInfo, nullptr, &blasData.as.handle)); VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{}; @@ -1301,7 +1310,6 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() { blasData.buildInfo.scratchData.deviceAddress = scratchBuffer.getAddress(); VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE); - // UF_MSG_DEBUG("vkCmdBuildAccelerationStructuresKHR"); uf::renderer::vkCmdBuildAccelerationStructuresKHR( commandBuffer, 1, @@ -1318,7 +1326,9 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() { } void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vector& graphics, const uf::stl::vector& instances ) { auto& device = *this->device; - // graphic.process = false; + + bool rebuild = false; + bool update = this->accelerationStructures.top.handle != VK_NULL_HANDLE; VkPhysicalDeviceAccelerationStructurePropertiesKHR acclerationStructureProperties{}; VkPhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingPipelineProperties{}; @@ -1334,84 +1344,45 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect vkGetPhysicalDeviceProperties2(device.physicalDevice, &deviceProperties2); } - uf::renderer::Buffer instanceBuffer; - uf::renderer::Buffer scratchBuffer; - uf::renderer::Buffer tlasBuffer; uf::stl::vector instancesVK; instancesVK.reserve( instances.size() ); - uf::stl::vector instanceAddresseses( instances.size() ); - for ( auto& graphic : graphics ) { for ( auto& blas : graphic->accelerationStructures.bottoms ) { size_t instanceID = blas.instanceID; + auto instanceKeyName = std::to_string(instanceID); - auto& instanceAddresses = instanceAddresseses[instanceID]; - if ( graphic->descriptor.inputs.vertex.count ) { - if ( 0 <= graphic->descriptor.inputs.vertex.interleaved ) { - instanceAddresses.vertex = graphic->buffers.at(graphic->descriptor.inputs.vertex.interleaved).getAddress(); - } else { - for ( auto& attribute : graphic->descriptor.inputs.vertex.attributes ) { - if ( attribute.buffer < 0 ) continue; - if ( attribute.descriptor.name == "position" ) instanceAddresses.position = graphic->buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "uv" ) instanceAddresses.uv = graphic->buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "color" ) instanceAddresses.color = graphic->buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "st" ) instanceAddresses.st = graphic->buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "normal" ) instanceAddresses.normal = graphic->buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "tangent" ) instanceAddresses.tangent = graphic->buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "joints" ) instanceAddresses.joints = graphic->buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "weights" ) instanceAddresses.weights = graphic->buffers.at(attribute.buffer).getAddress(); - else if ( attribute.descriptor.name == "id" ) instanceAddresses.id = graphic->buffers.at(attribute.buffer).getAddress(); - } - } - } - if ( graphic->descriptor.inputs.index.count ) { - if ( 0 <= graphic->descriptor.inputs.index.interleaved ) { - instanceAddresses.index = graphic->buffers.at(graphic->descriptor.inputs.index.interleaved).getAddress(); - } else { - instanceAddresses.index = graphic->buffers.at(graphic->descriptor.inputs.index.attributes.front().buffer).getAddress(); - } - } - - auto& instanceVK = instancesVK.emplace_back(); - instanceVK.transform = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f - }; - auto mat = instances[instanceID].model; mat = uf::matrix::transpose(mat); + auto& instanceVK = instancesVK.emplace_back(); memcpy(&instanceVK.transform, &mat, sizeof(instanceVK.transform)); instanceVK.instanceCustomIndex = blas.instanceID; instanceVK.accelerationStructureReference = blas.deviceAddress; - instanceVK.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; + instanceVK.flags = 0; // VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; instanceVK.mask = 0xFF; instanceVK.instanceShaderBindingTableRecordOffset = 0; } } // do not stage, because apparently vkQueueWaitIdle doesn't actually wait for the transfer to complete - size_t instanceIndex = this->initializeBuffer( - (const void*) instancesVK.data(), instancesVK.size() * sizeof(VkAccelerationStructureInstanceKHR), - uf::renderer::enums::Buffer::ADDRESS | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, false - ); - size_t instanceBufferAddress = this->buffers[instanceIndex].getAddress(); - - // build SBT - if ( !this->material.hasShader("ray:gen", uf::renderer::settings::pipelines::names::rt) ) { - uf::stl::string rayGenShaderFilename = uf::io::root+"/shaders/raytrace/shader.gen.spv"; - uf::stl::string rayMissShaderFilename = uf::io::root+"/shaders/raytrace/shader.miss.spv"; - uf::stl::string rayHitShaderFilename = uf::io::root+"/shaders/raytrace/shader.hit.spv"; - - this->material.attachShader(rayGenShaderFilename, VK_SHADER_STAGE_RAYGEN_BIT_KHR, uf::renderer::settings::pipelines::names::rt); - this->material.attachShader(rayMissShaderFilename, VK_SHADER_STAGE_MISS_BIT_KHR, uf::renderer::settings::pipelines::names::rt); - this->material.attachShader(rayHitShaderFilename, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, uf::renderer::settings::pipelines::names::rt); + size_t instanceIndex{}; + size_t tlasBufferIndex{}; + if ( !update ) { + instanceIndex = this->initializeBuffer( + (const void*) instancesVK.data(), instancesVK.size() * sizeof(VkAccelerationStructureInstanceKHR), + uf::renderer::enums::Buffer::ADDRESS | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, false + ); + } else { + for ( size_t i = 0; i < buffers.size(); ++i ) { + if ( !(this->buffers[i].usage & (uf::renderer::enums::Buffer::ADDRESS | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR)) ) continue; + instanceIndex = i; + break; + } + rebuild = rebuild || this->updateBuffer( (const void*) instancesVK.data(), instancesVK.size() * sizeof(VkAccelerationStructureInstanceKHR), instanceIndex, false ); } - + size_t instanceBufferAddress = this->buffers[instanceIndex].getAddress(); { - VkBuildAccelerationStructureFlagsKHR flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR; - bool update = false; + VkBuildAccelerationStructureFlagsKHR flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR | VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR; uint32_t countInstance = instancesVK.size(); auto& tlas = this->accelerationStructures.top; @@ -1431,7 +1402,6 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect buildInfo.srcAccelerationStructure = VK_NULL_HANDLE; VkAccelerationStructureBuildSizesInfoKHR sizeInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR}; - UF_MSG_DEBUG("vkGetAccelerationStructureBuildSizesKHR"); uf::renderer::vkGetAccelerationStructureBuildSizesKHR( device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, @@ -1441,31 +1411,38 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect ); // create BLAS buffer and handle - size_t tlasBufferIndex = this->initializeBuffer( NULL, sizeInfo.accelerationStructureSize, uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS ); - auto& tlasBuffer = this->buffers[tlasBufferIndex]; { - auto& shader = this->material.getShader("ray:gen", uf::renderer::settings::pipelines::names::rt); - shader.buffers.emplace_back( this->buffers[tlasBufferIndex].alias() ); + auto tlasBufferUsageFlags = uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS; + if ( !update ) { + tlasBufferIndex = this->initializeBuffer( NULL, sizeInfo.accelerationStructureSize, tlasBufferUsageFlags); + } else { + for ( int i = buffers.size() - 1; i >= 0; --i ) { + if ( !(this->buffers[i].usage & tlasBufferUsageFlags) ) continue; + tlasBufferIndex = i; + break; + } + rebuild = rebuild || this->updateBuffer( NULL, sizeInfo.accelerationStructureSize, tlasBufferIndex ); } - VkAccelerationStructureCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR}; - createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; - createInfo.size = sizeInfo.accelerationStructureSize; - createInfo.buffer = tlasBuffer.buffer; + if ( !update ) { + VkAccelerationStructureCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR}; + createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; + createInfo.size = sizeInfo.accelerationStructureSize; + createInfo.buffer = this->buffers[tlasBufferIndex].buffer; - UF_MSG_DEBUG("vkCreateAccelerationStructureKHR"); - VK_CHECK_RESULT(uf::renderer::vkCreateAccelerationStructureKHR(device, &createInfo, nullptr, &tlas.handle)); + VK_CHECK_RESULT(uf::renderer::vkCreateAccelerationStructureKHR(device, &createInfo, nullptr, &tlas.handle)); - VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{}; - accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR; - accelerationDeviceAddressInfo.accelerationStructure = tlas.handle; - tlas.deviceAddress = uf::renderer::vkGetAccelerationStructureDeviceAddressKHR(device, &accelerationDeviceAddressInfo); + VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{}; + accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR; + accelerationDeviceAddressInfo.accelerationStructure = tlas.handle; + tlas.deviceAddress = uf::renderer::vkGetAccelerationStructureDeviceAddressKHR(device, &accelerationDeviceAddressInfo); + } // write to BLAS + uf::renderer::Buffer scratchBuffer; scratchBuffer.alignment = acclerationStructureProperties.minAccelerationStructureScratchOffsetAlignment; scratchBuffer.initialize( NULL, sizeInfo.buildScratchSize, uf::renderer::enums::Buffer::STORAGE | uf::renderer::enums::Buffer::ADDRESS ); - UF_MSG_DEBUG("Scratch buffer size: " << sizeInfo.buildScratchSize); - buildInfo.srcAccelerationStructure = VK_NULL_HANDLE; + buildInfo.srcAccelerationStructure = update ? tlas.handle : VK_NULL_HANDLE; buildInfo.dstAccelerationStructure = tlas.handle; buildInfo.scratchData.deviceAddress = scratchBuffer.getAddress(); @@ -1473,7 +1450,6 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect const VkAccelerationStructureBuildRangeInfoKHR* rangeInfo = &buildOffsetInfo; VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE); - UF_MSG_DEBUG("vkCmdBuildAccelerationStructuresKHR"); uf::renderer::vkCmdBuildAccelerationStructuresKHR( commandBuffer, 1, @@ -1485,98 +1461,41 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect scratchBuffer.destroy(); } - // should be placed outside, in the responsible scene/rendermode -#if 1 - { - auto& shader = this->material.getShader("ray:gen", uf::renderer::settings::pipelines::names::rt); - auto& image = shader.textures.emplace_back(); - image.fromBuffers( NULL, 0, uf::renderer::enums::Format::R8G8B8A8_UNORM, uf::renderer::settings::width, uf::renderer::settings::height, 1, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL ); - - this->descriptor.pipeline = uf::renderer::settings::pipelines::names::rt; - this->descriptor.inputs.width = image.width; - this->descriptor.inputs.height = image.height; - - // - struct UniformDescriptor { - struct Matrices { - alignas(16) pod::Matrix4f view; - alignas(16) pod::Matrix4f projection; - alignas(16) pod::Matrix4f iView; - alignas(16) pod::Matrix4f iProjection; - alignas(16) pod::Matrix4f iProjectionView; - alignas(16) pod::Vector4f eyePos; - } matrices[2]; - } uniforms; - - auto& scene = uf::scene::getCurrentScene(); - auto& controller = scene.getController(); - auto& camera = controller.getComponent(); - - for ( auto i = 0; i < 2; ++i ) { - uniforms.matrices[i] = UniformDescriptor::Matrices{ - .view = camera.getView(i), - .projection = camera.getProjection(i), - .iView = uf::matrix::inverse( camera.getView(i) ), - .iProjection = uf::matrix::inverse( camera.getProjection(i) ), - .iProjectionView = uf::matrix::inverse( camera.getProjection(i) * camera.getView(i) ), - .eyePos = camera.getEye( i ), - }; - } - bool found = false; - for ( auto& buffer : shader.buffers ) { - if ( !(buffer.usage & uf::renderer::enums::Buffer::UNIFORM) ) continue; - if ( buffer.allocationInfo.size != sizeof(UniformDescriptor) ) continue; - found = true; - break; - } - if ( !found ) shader.initializeBuffer( (const void*) &uniforms, sizeof(UniformDescriptor), uf::renderer::enums::Buffer::UNIFORM ); - - // - auto& sceneMetadataJson = scene.getComponent(); - size_t maxLights = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as(512); - size_t maxTextures2D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["2D"].as(512); - size_t maxTexturesCube = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["cube"].as(128); - size_t maxTextures3D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["3D"].as(1); - size_t maxCascades = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as(16); - - // shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() ); - // shader.buffers.emplace_back( uf::graph::storage.buffers.joint.alias() ); - shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() ); - shader.buffers.emplace_back( uf::graph::storage.buffers.material.alias() ); - shader.buffers.emplace_back( uf::graph::storage.buffers.texture.alias() ); - shader.buffers.emplace_back( uf::graph::storage.buffers.light.alias() ); - shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.alias() ); - - uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants; - for ( auto pair : shader.metadata.definitions.specializationConstants ) { - auto& sc = pair.second; - if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures2D); - else if ( sc.name == "CUBEMAPS" ) sc.value.ui = (specializationConstants[sc.index] = maxTexturesCube); - else if ( sc.name == "CASCADES" ) sc.value.ui = (specializationConstants[sc.index] = maxCascades); - } - for ( auto pair : shader.metadata.definitions.textures ) { - auto& tx = pair.second; - for ( auto& layout : shader.descriptorSetLayoutBindings ) { - if ( layout.binding != tx.binding ) continue; - if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures2D; - else if ( tx.name == "samplerCubemaps" ) layout.descriptorCount = maxTexturesCube; - else if ( tx.name == "voxelId" ) layout.descriptorCount = maxCascades; - else if ( tx.name == "voxelUv" ) layout.descriptorCount = maxCascades; - else if ( tx.name == "voxelNormal" ) layout.descriptorCount = maxCascades; - else if ( tx.name == "voxelRadiance" ) layout.descriptorCount = maxCascades; - } - } + if ( rebuild ) { + auto& renderMode = ext::vulkan::getRenderMode( descriptor.renderMode, true ); + renderMode.rebuild = true; } - // UF_MSG_DEBUG("Building pipeline..."); - this->initializePipeline(); - this->initialized = true; - this->process = true; + // build SBT + if ( !this->material.hasShader("ray:gen", uf::renderer::settings::pipelines::names::rt) ) { + { + uf::stl::string rayGenShaderFilename = uf::io::root+"/shaders/raytrace/shader.ray-gen.spv"; + uf::stl::string rayMissShaderFilename = uf::io::root+"/shaders/raytrace/shader.ray-miss.spv"; + uf::stl::string rayHitClosestShaderFilename = uf::io::root+"/shaders/raytrace/shader.ray-hit-closest.spv"; + uf::stl::string rayHitAnyShaderFilename = uf::io::root+"/shaders/raytrace/shader.ray-hit-any.spv"; -#endif + this->material.attachShader(rayGenShaderFilename, VK_SHADER_STAGE_RAYGEN_BIT_KHR, uf::renderer::settings::pipelines::names::rt); + this->material.attachShader(rayMissShaderFilename, VK_SHADER_STAGE_MISS_BIT_KHR, uf::renderer::settings::pipelines::names::rt); + this->material.attachShader(rayHitClosestShaderFilename, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, uf::renderer::settings::pipelines::names::rt); + // this->material.attachShader(rayHitAnyShaderFilename, VK_SHADER_STAGE_ANY_HIT_BIT_KHR, uf::renderer::settings::pipelines::names::rt); + } + { + auto& shader = this->material.getShader("ray:gen", uf::renderer::settings::pipelines::names::rt); - UF_MSG_DEBUG("Generated acceleration structures for " << this << " (" << this->descriptor.renderMode << ")"); + auto& image = shader.textures.emplace_back(); + image.fromBuffers( NULL, 0, uf::renderer::enums::Format::R8G8B8A8_UNORM, uf::renderer::settings::width, uf::renderer::settings::height, 1, 1, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL ); + + this->descriptor.pipeline = uf::renderer::settings::pipelines::names::rt; + this->descriptor.inputs.width = image.width; + this->descriptor.inputs.height = image.height; + + // + shader.buffers.emplace_back( this->buffers[tlasBufferIndex].alias() ); + } + } + + if ( !update ) UF_MSG_DEBUG("Generated acceleration structures for " << this << " (" << this->descriptor.renderMode << ")"); } bool ext::vulkan::Graphic::hasPipeline( const GraphicDescriptor& descriptor ) const { return pipelines.count( descriptor ) > 0; diff --git a/engine/src/ext/vulkan/rendermodes/deferred.cpp b/engine/src/ext/vulkan/rendermodes/deferred.cpp index 5dd2eac6..7a865e1f 100644 --- a/engine/src/ext/vulkan/rendermodes/deferred.cpp +++ b/engine/src/ext/vulkan/rendermodes/deferred.cpp @@ -555,7 +555,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto for ( size_t eye = 0; eye < metadata.eyes; ++eye ) { size_t currentPass = 0; size_t currentDraw = 0; - for ( auto graphic : graphics ) { + if ( !settings::pipelines::rt ) for ( auto graphic : graphics ) { // only draw graphics that are assigned to this type of render mode if ( graphic->descriptor.renderMode != this->getName() ) continue; ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentSubpass); @@ -573,7 +573,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto } vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); ++currentPass; ++currentSubpass; // deferred post-processing lighting pass - { + if ( !settings::pipelines::rt ) { ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(blitter.descriptor, currentSubpass); blitter.record(commands[i], descriptor, eye, currentDraw++); } diff --git a/ext/behaviors/player/behavior.cpp b/ext/behaviors/player/behavior.cpp index 11f9567f..715177c9 100644 --- a/ext/behaviors/player/behavior.cpp +++ b/ext/behaviors/player/behavior.cpp @@ -258,6 +258,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { } } + if ( collider.stats.gravity == pod::Vector3f{0,0,0} ) stats.noclipped = true; + struct { float move = 4; float walk = 1; @@ -274,8 +276,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { speed.air = metadata.movement.air; if ( stats.noclipped ) { - speed.move *= 4.0; - speed.run *= 2.0; + speed.move *= 1.5; + speed.run *= 1.5; } if ( !stats.floored || stats.noclipped ) speed.friction = 1; if ( stats.noclipped ) physics.linear.velocity = {}; @@ -318,7 +320,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { } else #endif // un-flatted if noclipped - if ( stats.noclipped ){ + + if ( stats.noclipped || collider.stats.gravity == pod::Vector3f{0,0,0} ){ translator.forward.y += cameraTransform.forward.y; translator.forward = uf::vector::normalize( translator.forward ); } @@ -328,6 +331,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) { TIMER(0.25, keys.vee && ) { bool state = !stats.noclipped; metadata.system.noclipped = state; + if ( collider.body ) collider.body->enableGravity(!state); UF_MSG_DEBUG( (state ? "En" : "Dis") << "abled noclip: " << uf::vector::toString(transform.position)); #if 0 diff --git a/ext/behaviors/raytrace/behavior.cpp b/ext/behaviors/raytrace/behavior.cpp index cdff6252..1a80ba24 100644 --- a/ext/behaviors/raytrace/behavior.cpp +++ b/ext/behaviors/raytrace/behavior.cpp @@ -16,92 +16,10 @@ #include "../light/behavior.h" #include "../scene/behavior.h" -#define TEST 0 - UF_BEHAVIOR_REGISTER_CPP(ext::RayTraceSceneBehavior) UF_BEHAVIOR_TRAITS_CPP(ext::RayTraceSceneBehavior, ticks = true, renders = false, multithread = false) #define this (&self) void ext::RayTraceSceneBehavior::initialize( uf::Object& self ) { -#if TEST - auto& metadata = this->getComponent(); - auto& graphic = this->getComponent(); //metadata.renderer.graphic; - auto& mesh = this->getComponent(); - - - mesh.bind(); - mesh.insertVertices({ - {-1.0f,-1.0f,-1.0f,}, - {-1.0f,-1.0f, 1.0f,}, - {-1.0f, 1.0f, 1.0f,}, - {1.0f, 1.0f,-1.0f,}, - {-1.0f,-1.0f,-1.0f,}, - {-1.0f, 1.0f,-1.0f,}, - {1.0f,-1.0f, 1.0f,}, - {-1.0f,-1.0f,-1.0f,}, - {1.0f,-1.0f,-1.0f,}, - {1.0f, 1.0f,-1.0f,}, - {1.0f,-1.0f,-1.0f,}, - {-1.0f,-1.0f,-1.0f,}, - {-1.0f,-1.0f,-1.0f,}, - {-1.0f, 1.0f, 1.0f,}, - {-1.0f, 1.0f,-1.0f,}, - {1.0f,-1.0f, 1.0f,}, - {-1.0f,-1.0f, 1.0f,}, - {-1.0f,-1.0f,-1.0f,}, - {-1.0f, 1.0f, 1.0f,}, - {-1.0f,-1.0f, 1.0f,}, - {1.0f,-1.0f, 1.0f,}, - {1.0f, 1.0f, 1.0f,}, - {1.0f,-1.0f,-1.0f,}, - {1.0f, 1.0f,-1.0f,}, - {1.0f,-1.0f,-1.0f,}, - {1.0f, 1.0f, 1.0f,}, - {1.0f,-1.0f, 1.0f,}, - {1.0f, 1.0f, 1.0f,}, - {1.0f, 1.0f,-1.0f,}, - {-1.0f, 1.0f,-1.0f,}, - {1.0f, 1.0f, 1.0f,}, - {-1.0f, 1.0f,-1.0f,}, - {-1.0f, 1.0f, 1.0f,}, - {1.0f, 1.0f, 1.0f,}, - {-1.0f, 1.0f, 1.0f,}, - {1.0f,-1.0f, 1.0f,}, - }); - mesh.updateDescriptor(); - - graphic.initialize("Compute"); - graphic.initializeMesh( mesh ); - - uf::stl::vector instances; - auto& instance = instances.emplace_back(); - instance.model = uf::matrix::identity(); - - graphic.generateBottomAccelerationStructures(); - graphic.generateTopAccelerationStructure( { &graphic }, instances ); - - auto& shader = graphic.material.getShader("ray:gen", uf::renderer::settings::pipelines::names::rt); - auto& image = shader.textures.front(); - - if ( !uf::renderer::hasRenderMode("Compute", true) ) { - auto* renderMode = new uf::renderer::RenderTargetRenderMode; - renderMode->setTarget("Compute"); - renderMode->metadata.json["shaders"]["vertex"] = "/shaders/display/renderTargetSimple.vert.spv"; - renderMode->metadata.json["shaders"]["fragment"] = "/shaders/display/renderTargetSimple.frag.spv"; - renderMode->blitter.descriptor.subpass = 1; - renderMode->metadata.type = uf::renderer::settings::pipelines::names::rt; - renderMode->metadata.pipelines.emplace_back(uf::renderer::settings::pipelines::names::rt); - renderMode->execute = false; - uf::renderer::addRenderMode( renderMode, "Compute" ); - } else { - auto& renderMode = uf::renderer::getRenderMode("Compute", true); - auto& blitter = *renderMode.getBlitter(); - - if ( blitter.material.hasShader("fragment") ) { - auto& shader = blitter.material.getShader("fragment"); - shader.textures.emplace_back().aliasTexture( image ); - } - } -#else if ( !uf::renderer::hasRenderMode("Compute", true) ) { auto* renderMode = new uf::renderer::RenderTargetRenderMode; renderMode->setTarget("Compute"); @@ -113,72 +31,82 @@ void ext::RayTraceSceneBehavior::initialize( uf::Object& self ) { renderMode->execute = false; uf::renderer::addRenderMode( renderMode, "Compute" ); } -#endif } void ext::RayTraceSceneBehavior::tick( uf::Object& self ) { auto& metadata = this->getComponent(); -#if !TEST - if ( !metadata.renderer.bound ) { - auto instances = uf::graph::storage.instances.flatten(); - if ( instances.empty() ) return; + auto instances = uf::graph::storage.instances.flatten(); + if ( instances.empty() ) return; - uf::stl::vector graphics; - this->process([&]( uf::Entity* entity ) { - if ( !entity->hasComponent() ) return; - graphics.emplace_back(entity->getComponentPointer()); - }); - if ( graphics.empty() ) return; + uf::stl::vector graphics; + this->process([&]( uf::Entity* entity ) { + if ( !entity->hasComponent() ) return; + graphics.emplace_back(entity->getComponentPointer()); + }); - auto& graphic = this->getComponent(); - graphic.initialize("Compute"); - graphic.generateTopAccelerationStructure( graphics, instances ); + if ( graphics.empty() ) return; + auto& graphic = this->getComponent(); + + if ( !metadata.renderer.bound ) graphic.initialize("Compute"); + graphic.generateTopAccelerationStructure( graphics, instances ); - UF_MSG_DEBUG( graphics.size() << " " << instances.size() ); + if ( !metadata.renderer.bound ) { + if ( graphic.material.hasShader("ray:gen", uf::renderer::settings::pipelines::names::rt) ) { + auto& shader = graphic.material.getShader("ray:gen", uf::renderer::settings::pipelines::names::rt); + + auto& scene = uf::scene::getCurrentScene(); + auto& sceneMetadataJson = scene.getComponent(); + size_t maxLights = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as(512); + size_t maxTextures2D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["2D"].as(512); + size_t maxTexturesCube = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["cube"].as(128); + size_t maxTextures3D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["3D"].as(1); + size_t maxCascades = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as(16); - metadata.renderer.bound = true; - return; + shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() ); + shader.buffers.emplace_back( uf::graph::storage.buffers.material.alias() ); + shader.buffers.emplace_back( uf::graph::storage.buffers.texture.alias() ); + shader.buffers.emplace_back( uf::graph::storage.buffers.light.alias() ); + + uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants; + for ( auto pair : shader.metadata.definitions.specializationConstants ) { + auto& sc = pair.second; + if ( sc.name == "TEXTURES" ) sc.value.ui = (specializationConstants[sc.index] = maxTextures2D); + else if ( sc.name == "CUBEMAPS" ) sc.value.ui = (specializationConstants[sc.index] = maxTexturesCube); + else if ( sc.name == "CASCADES" ) sc.value.ui = (specializationConstants[sc.index] = maxCascades); + } + for ( auto pair : shader.metadata.definitions.textures ) { + auto& tx = pair.second; + for ( auto& layout : shader.descriptorSetLayoutBindings ) { + if ( layout.binding != tx.binding ) continue; + if ( tx.name == "samplerTextures" ) layout.descriptorCount = maxTextures2D; + else if ( tx.name == "samplerCubemaps" ) layout.descriptorCount = maxTexturesCube; + else if ( tx.name == "voxelId" ) layout.descriptorCount = maxCascades; + else if ( tx.name == "voxelUv" ) layout.descriptorCount = maxCascades; + else if ( tx.name == "voxelNormal" ) layout.descriptorCount = maxCascades; + else if ( tx.name == "voxelRadiance" ) layout.descriptorCount = maxCascades; + } + } + + metadata.renderer.bound = true; + } + if ( graphic.material.hasShader("ray:hit:closest", uf::renderer::settings::pipelines::names::rt) ) { + auto& shader = graphic.material.getShader("ray:hit:closest", uf::renderer::settings::pipelines::names::rt); + shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.alias() ); + } + if ( graphic.material.hasShader("ray:hit:any", uf::renderer::settings::pipelines::names::rt) ) { + auto& shader = graphic.material.getShader("ray:hit:any", uf::renderer::settings::pipelines::names::rt); + shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.alias() ); + } + + graphic.process = false; + } + /* Update lights */ { + ext::ExtSceneBehavior::bindBuffers( *this, graphic, "ray:gen", uf::renderer::settings::pipelines::names::rt ); } if ( !metadata.renderer.bound ) return; -#endif - auto& graphic = this->getComponent(); auto& shader = graphic.material.getShader("ray:gen", uf::renderer::settings::pipelines::names::rt); auto& image = shader.textures.front(); - struct UniformDescriptor { - struct Matrices { - alignas(16) pod::Matrix4f view; - alignas(16) pod::Matrix4f projection; - alignas(16) pod::Matrix4f iView; - alignas(16) pod::Matrix4f iProjection; - alignas(16) pod::Matrix4f iProjectionView; - alignas(16) pod::Vector4f eyePos; - } matrices[2]; - } uniforms; - - auto& scene = uf::scene::getCurrentScene(); - auto& controller = scene.getController(); - auto& camera = controller.getComponent(); - - for ( auto i = 0; i < 2; ++i ) { - uniforms.matrices[i] = UniformDescriptor::Matrices{ - .view = camera.getView(i), - .projection = camera.getProjection(i), - .iView = uf::matrix::inverse( camera.getView(i) ), - .iProjection = uf::matrix::inverse( camera.getProjection(i) ), - .iProjectionView = uf::matrix::inverse( camera.getProjection(i) * camera.getView(i) ), - .eyePos = camera.getEye( i ), - }; - } - - for ( auto& buffer : shader.buffers ) { - if ( !(buffer.usage & uf::renderer::enums::Buffer::UNIFORM) ) continue; - if ( buffer.allocationInfo.size != sizeof(UniformDescriptor) ) continue; - - buffer.update( (const void*) &uniforms, sizeof(UniformDescriptor) ); - break; - } - auto& renderMode = uf::renderer::getRenderMode("Compute", true); auto& blitter = *renderMode.getBlitter(); if ( blitter.material.hasShader("fragment") ) { @@ -186,6 +114,7 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) { if ( shader.textures.empty() ) { shader.textures.emplace_back().aliasTexture( image ); renderMode.execute = true; + graphic.process = true; } } @@ -212,7 +141,7 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) { void ext::RayTraceSceneBehavior::render( uf::Object& self ){} void ext::RayTraceSceneBehavior::destroy( uf::Object& self ){ auto& metadata = this->getComponent(); - auto& graphic = this->getComponent(); // metadata.renderer.graphic; + auto& graphic = this->getComponent(); graphic.destroy(); } diff --git a/ext/behaviors/scene/behavior.cpp b/ext/behaviors/scene/behavior.cpp index 78833d51..63cbd11e 100644 --- a/ext/behaviors/scene/behavior.cpp +++ b/ext/behaviors/scene/behavior.cpp @@ -687,7 +687,7 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali } } -void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string& renderModeName, bool isCompute ) { +void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string& renderModeName, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) { auto& graph = this->getGraph(); auto& controller = this->getController(); auto& camera = controller.getComponent(); @@ -700,6 +700,20 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string auto& renderMode = uf::renderer::getRenderMode(renderModeName, true); auto blitters = renderMode.getBlitters(); + bindBuffers( self, *blitters.front(), shaderType, shaderPipeline ); +} +void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic& graphic, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) { + auto& graph = this->getGraph(); + auto& controller = this->getController(); + auto& camera = controller.getComponent(); + auto& controllerMetadata = controller.getComponent(); + auto& controllerTransform = controller.getComponent>(); + auto& metadata = this->getComponent(); + auto& metadataVxgi = this->getComponent(); + auto& metadataJson = this->getComponent(); + + if ( !graphic.initialized ) return; + #if UF_USE_VULKAN struct UniformDescriptor { struct Matrices { @@ -871,29 +885,25 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string uniforms.useLightmaps = metadata.light.useLightmaps; } - for ( auto* blitter : blitters ) { - auto& graphic = *blitter; - if ( !graphic.initialized ) continue; - uf::stl::vector previousTextures; - for ( auto& texture : graphic.material.textures ) previousTextures.emplace_back(texture.image); - graphic.material.textures.clear(); + uf::stl::vector previousTextures; + for ( auto& texture : graphic.material.textures ) previousTextures.emplace_back(texture.image); + graphic.material.textures.clear(); - // attach our textures to the graphic - for ( auto& t : textures2D ) graphic.material.textures.emplace_back().aliasTexture(t); - for ( auto& t : texturesCube ) graphic.material.textures.emplace_back().aliasTexture(t); - for ( auto& t : textures3D ) graphic.material.textures.emplace_back().aliasTexture(t); + // attach our textures to the graphic + for ( auto& t : textures2D ) graphic.material.textures.emplace_back().aliasTexture(t); + for ( auto& t : texturesCube ) graphic.material.textures.emplace_back().aliasTexture(t); + for ( auto& t : textures3D ) graphic.material.textures.emplace_back().aliasTexture(t); - // trigger an update when we have differing bound texture sizes - bool shouldUpdate = metadata.shader.invalidated || graphic.material.textures.size() != previousTextures.size(); - for ( uint32_t i = 0; !shouldUpdate && i < previousTextures.size() && i < graphic.material.textures.size(); ++i ) { - if ( previousTextures[i] != graphic.material.textures[i].image ) shouldUpdate = true; - } - if ( shouldUpdate ) graphic.updatePipelines(); - - auto& shader = graphic.material.getShader(isCompute ? "compute" : "fragment"); - shader.updateBuffer( (const void*) &uniforms, sizeof(uniforms), shader.getUniformBuffer("UBO") ); + // trigger an update when we have differing bound texture sizes + bool shouldUpdate = metadata.shader.invalidated || graphic.material.textures.size() != previousTextures.size(); + for ( uint32_t i = 0; !shouldUpdate && i < previousTextures.size() && i < graphic.material.textures.size(); ++i ) { + if ( previousTextures[i] != graphic.material.textures[i].image ) shouldUpdate = true; } + if ( shouldUpdate ) graphic.updatePipelines(); + + auto& shader = graphic.material.getShader(shaderType, shaderPipeline); + shader.updateBuffer( (const void*) &uniforms, sizeof(uniforms), shader.getUniformBuffer("UBO") ); #endif } #undef this \ No newline at end of file diff --git a/ext/behaviors/scene/behavior.h b/ext/behaviors/scene/behavior.h index 3057edec..c4107da7 100644 --- a/ext/behaviors/scene/behavior.h +++ b/ext/behaviors/scene/behavior.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace ext { namespace ExtSceneBehavior { @@ -67,6 +68,7 @@ namespace ext { } sky; ); - void bindBuffers( uf::Object&, const uf::stl::string& = "", bool = false ); + void bindBuffers( uf::Object&, const uf::stl::string& = "", const uf::stl::string& = "fragment", const uf::stl::string& = "" ); + void bindBuffers( uf::Object&, uf::renderer::Graphic&, const uf::stl::string& = "fragment", const uf::stl::string& = "" ); } } \ No newline at end of file diff --git a/ext/behaviors/voxelizer/behavior.cpp b/ext/behaviors/voxelizer/behavior.cpp index 1005244c..abe4ff40 100644 --- a/ext/behaviors/voxelizer/behavior.cpp +++ b/ext/behaviors/voxelizer/behavior.cpp @@ -174,7 +174,6 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) { if ( renderMode.blitter.initialized ) { auto& pipeline = renderMode.blitter.getPipeline(); pipeline.record(renderMode.blitter, commandBuffer); - // vkCmdDispatch(commandBuffer, metadata.voxelSize.x / metadata.dispatchSize.x, metadata.voxelSize.y / metadata.dispatchSize.y, metadata.voxelSize.z / metadata.dispatchSize.z); } // generate mipmaps @@ -437,7 +436,7 @@ void ext::VoxelizerSceneBehavior::tick( uf::Object& self ) { } #endif } - ext::ExtSceneBehavior::bindBuffers( scene, metadata.renderModeName, true ); + ext::ExtSceneBehavior::bindBuffers( scene, metadata.renderModeName, "compute" ); ext::ExtSceneBehavior::bindBuffers( scene ); #endif } diff --git a/ext/main.cpp b/ext/main.cpp index 8f7c9f47..ee98cc18 100644 --- a/ext/main.cpp +++ b/ext/main.cpp @@ -230,6 +230,9 @@ void EXT_API ext::initialize() { uf::Object::assertionLoad = ::json["engine"]["debug"]["loader"]["assert"].as( uf::Object::assertionLoad ); uf::Asset::assertionLoad = ::json["engine"]["debug"]["loader"]["assert"].as( uf::Asset::assertionLoad ); + + uf::userdata::autoDestruct = ::json["engine"]["debug"]["userdata"]["auto destruct"].as( uf::userdata::autoDestruct ); + uf::userdata::autoValidate = ::json["engine"]["debug"]["userdata"]["auto validate"].as( uf::userdata::autoValidate ); } { @@ -417,6 +420,11 @@ void EXT_API ext::initialize() { uf::renderer::settings::pipelines::culling = configRenderPipelinesJson["culling"].as( uf::renderer::settings::pipelines::culling ); uf::renderer::settings::pipelines::bloom = configRenderPipelinesJson["bloom"].as( uf::renderer::settings::pipelines::bloom ); uf::renderer::settings::pipelines::rt = configRenderPipelinesJson["rt"].as( uf::renderer::settings::pipelines::rt ); + + if ( uf::renderer::settings::pipelines::rt ) { + // uf::renderer::settings::pipelines::vxgi = false; + uf::renderer::settings::pipelines::culling = false; + } #define JSON_TO_VKFORMAT( key ) if ( configRenderJson["formats"][#key].is() ) {\ uf::stl::string format = configRenderJson["formats"][#key].as();\ diff --git a/makefiles/win64.gcc.make b/makefiles/win64.gcc.make index 3757331a..88166693 100644 --- a/makefiles/win64.gcc.make +++ b/makefiles/win64.gcc.make @@ -2,6 +2,6 @@ ARCH = win64 CDIR = CC = gcc CXX = g++ -OPTIMIZATIONS = -O3 -g -fstrict-aliasing -DUF_NO_EXCEPTIONS #-flto +OPTIMIZATIONS = -O3 -g -fstrict-aliasing -DUF_NO_EXCEPTIONS # -flto WARNINGS = -Wall -Wno-unknown-pragmas -Wno-unused-function -Wno-unused-variable -Wno-switch -Wno-reorder -Wno-sign-compare -Wno-unused-but-set-variable -Wno-ignored-attributes -Wno-narrowing -Wno-misleading-indentation FLAGS += -std=c++20 $(OPTIMIZATIONS) $(WARNINGS) -fdiagnostics-color=always \ No newline at end of file