Commit for 2022.06.25 23-41-15.7z
This commit is contained in:
parent
ddb43b26ea
commit
813907f0a3
@ -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
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
36
bin/data/scenes/cornell/cornell.json
Normal file
36
bin/data/scenes/cornell/cornell.json
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
bin/data/scenes/cornell/loading.json
Normal file
32
bin/data/scenes/cornell/loading.json
Normal file
@ -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": "コマンド"
|
||||
}
|
||||
}
|
||||
}
|
||||
27
bin/data/scenes/cornell/player.json
Normal file
27
bin/data/scenes/cornell/player.json
Normal file
@ -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]
|
||||
}
|
||||
}
|
||||
}
|
||||
55
bin/data/scenes/cornell/scene.json
Normal file
55
bin/data/scenes/cornell/scene.json
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 },
|
||||
|
||||
@ -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 ],
|
||||
|
||||
|
||||
@ -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": {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
} 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;
|
||||
};
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 ) {
|
||||
|
||||
@ -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 );
|
||||
|
||||
@ -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 ) {
|
||||
|
||||
@ -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));
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
280
bin/data/shaders/raytrace/shader.ray-gen.glsl
Normal file
280
bin/data/shaders/raytrace/shader.ray-gen.glsl
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
91
bin/data/shaders/raytrace/shader.ray-hit-any.glsl
Normal file
91
bin/data/shaders/raytrace/shader.ray-hit-any.glsl
Normal file
@ -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;
|
||||
}
|
||||
91
bin/data/shaders/raytrace/shader.ray-hit-closest.glsl
Normal file
91
bin/data/shaders/raytrace/shader.ray-hit-closest.glsl
Normal file
@ -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;
|
||||
}
|
||||
18
bin/data/shaders/raytrace/shader.ray-miss.glsl
Normal file
18
bin/data/shaders/raytrace/shader.ray-miss.glsl
Normal file
@ -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;
|
||||
}
|
||||
@ -7,7 +7,7 @@
|
||||
#include <uf/utils/memory/unordered_map.h>
|
||||
#include <typeinfo>
|
||||
|
||||
#define UF_COMPONENT_POINTERED_USERDATA 0
|
||||
#define UF_COMPONENT_POINTERED_USERDATA 1 //
|
||||
|
||||
namespace pod {
|
||||
struct UF_API Component {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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<bool>() ) UF_MSG_INFO(uf::graph::stats( asset ).dump(1,'\t'));
|
||||
if ( asset.metadata["debug"]["print stats"].as<bool>() ) UF_MSG_INFO(uf::graph::stats( asset ));
|
||||
if ( asset.metadata["debug"]["print tree"].as<bool>() ) UF_MSG_INFO(uf::graph::print( asset ));
|
||||
#endif
|
||||
if ( !asset.metadata["debug"]["no cleanup"].as<bool>() ) uf::graph::cleanup( asset );
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 );
|
||||
|
||||
@ -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<bool>(true) || graph.metadata["exporter"]["optimize"].as<uf::stl::string>("") == "tagged" ) {
|
||||
if ( graph.metadata["exporter"]["optimize"].as<bool>(false) || graph.metadata["exporter"]["optimize"].as<uf::stl::string>("") == "tagged" ) {
|
||||
UF_MSG_DEBUG( "Optimizing meshes..." );
|
||||
for ( auto& keyName : graph.meshes ) {
|
||||
size_t level = SIZE_MAX;
|
||||
|
||||
@ -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<pod::PhysicsState>();;
|
||||
auto& state = object->getComponent<pod::PhysicsState>();
|
||||
|
||||
if ( !state.object ) {
|
||||
state.object = object;
|
||||
//continue;
|
||||
}
|
||||
|
||||
auto& transform = state.object->getComponent<pod::Transform<>>();
|
||||
auto& physics = state.object->getComponent<pod::Physics>();
|
||||
|
||||
|
||||
@ -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<Buffer*>(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);
|
||||
|
||||
@ -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<uf::renderer::Graphic*>& graphics, const uf::stl::vector<pod::Instance>& 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<VkAccelerationStructureInstanceKHR> instancesVK; instancesVK.reserve( instances.size() );
|
||||
uf::stl::vector<pod::InstanceAddresses> 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<uf::Camera>();
|
||||
|
||||
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<uf::Serializer>();
|
||||
size_t maxLights = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>(512);
|
||||
size_t maxTextures2D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["2D"].as<size_t>(512);
|
||||
size_t maxTexturesCube = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["cube"].as<size_t>(128);
|
||||
size_t maxTextures3D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["3D"].as<size_t>(1);
|
||||
size_t maxCascades = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(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;
|
||||
|
||||
@ -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++);
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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<ext::RayTraceSceneBehavior::Metadata>();
|
||||
auto& graphic = this->getComponent<uf::renderer::Graphic>(); //metadata.renderer.graphic;
|
||||
auto& mesh = this->getComponent<uf::Mesh>();
|
||||
|
||||
|
||||
mesh.bind<pod::Vertex_3F>();
|
||||
mesh.insertVertices<pod::Vertex_3F>({
|
||||
{-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<pod::Instance> 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<ext::RayTraceSceneBehavior::Metadata>();
|
||||
#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<uf::Graphic*> graphics;
|
||||
this->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
graphics.emplace_back(entity->getComponentPointer<uf::Graphic>());
|
||||
});
|
||||
if ( graphics.empty() ) return;
|
||||
uf::stl::vector<uf::Graphic*> graphics;
|
||||
this->process([&]( uf::Entity* entity ) {
|
||||
if ( !entity->hasComponent<uf::Graphic>() ) return;
|
||||
graphics.emplace_back(entity->getComponentPointer<uf::Graphic>());
|
||||
});
|
||||
|
||||
auto& graphic = this->getComponent<uf::renderer::Graphic>();
|
||||
graphic.initialize("Compute");
|
||||
graphic.generateTopAccelerationStructure( graphics, instances );
|
||||
if ( graphics.empty() ) return;
|
||||
auto& graphic = this->getComponent<uf::renderer::Graphic>();
|
||||
|
||||
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<uf::Serializer>();
|
||||
size_t maxLights = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["max"].as<size_t>(512);
|
||||
size_t maxTextures2D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["2D"].as<size_t>(512);
|
||||
size_t maxTexturesCube = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["cube"].as<size_t>(128);
|
||||
size_t maxTextures3D = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["textures"]["max"]["3D"].as<size_t>(1);
|
||||
size_t maxCascades = sceneMetadataJson["system"]["config"]["engine"]["scenes"]["vxgi"]["cascades"].as<size_t>(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<uf::renderer::Graphic>();
|
||||
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<uf::Camera>();
|
||||
|
||||
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<ext::RayTraceSceneBehavior::Metadata>();
|
||||
auto& graphic = this->getComponent<uf::renderer::Graphic>(); // metadata.renderer.graphic;
|
||||
auto& graphic = this->getComponent<uf::renderer::Graphic>();
|
||||
|
||||
graphic.destroy();
|
||||
}
|
||||
|
||||
@ -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<uf::Camera>();
|
||||
@ -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<uf::Camera>();
|
||||
auto& controllerMetadata = controller.getComponent<uf::Serializer>();
|
||||
auto& controllerTransform = controller.getComponent<pod::Transform<>>();
|
||||
auto& metadata = this->getComponent<ext::ExtSceneBehavior::Metadata>();
|
||||
auto& metadataVxgi = this->getComponent<ext::VoxelizerSceneBehavior::Metadata>();
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
|
||||
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<VkImage> previousTextures;
|
||||
for ( auto& texture : graphic.material.textures ) previousTextures.emplace_back(texture.image);
|
||||
graphic.material.textures.clear();
|
||||
uf::stl::vector<VkImage> 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
|
||||
@ -5,6 +5,7 @@
|
||||
#include <uf/engine/entity/entity.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
#include <uf/utils/math/vector.h>
|
||||
#include <uf/utils/graphic/graphic.h>
|
||||
|
||||
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& = "" );
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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>() ) {\
|
||||
uf::stl::string format = configRenderJson["formats"][#key].as<uf::stl::string>();\
|
||||
|
||||
@ -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
|
||||
Loading…
Reference in New Issue
Block a user