Commit for 2022.06.28 23-53-39.7z

This commit is contained in:
mrq 2022-06-28 23:53:00 -05:00
parent 813907f0a3
commit c536d24e63
73 changed files with 1001 additions and 358 deletions

View File

@ -56,7 +56,7 @@ LINKS += $(UF_LIBS) $(EXT_LIBS) $(DEPS)
DEPS +=
ifneq (,$(findstring win64,$(ARCH)))
REQ_DEPS += $(RENDERER) json:nlohmann png zlib openal ogg freetype curl luajit reactphysics meshoptimizer xatlas simd ctti gltf # ncurses openvr draco discord bullet ultralight-ux
REQ_DEPS += $(RENDERER) json:nlohmann png zlib openal ogg freetype curl luajit reactphysics meshoptimizer xatlas simd ctti gltf imgui # ncurses openvr draco discord bullet ultralight-ux
FLAGS +=
DEPS += -lgdi32
LINKS += #-Wl,-subsystem,windows
@ -90,6 +90,11 @@ ifneq (,$(findstring opengl,$(REQ_DEPS)))
endif
endif
ifneq (,$(findstring imgui,$(REQ_DEPS)))
FLAGS += -DUF_USE_IMGUI
INCS += -I./dep/imgui/
INCS += -I./dep/imgui/backends
endif
ifneq (,$(findstring json,$(REQ_DEPS)))
FLAGS += -DUF_USE_JSON
DEPS +=

View File

@ -5,11 +5,11 @@
"meshes": { "interleaved": false },
"matrix": { "reverseInfinite": true },
"lights": { "enabled": true,
"useLightmaps": false,
"max": 24
"useLightmaps": true,
"max": 32
},
"shadows": {
"enabled": false,
"enabled": true,
"update": 2,
"max": 16,
"samples": 1
@ -17,8 +17,8 @@
"textures": {
"max": {
"2D": 1024,
"cube": 256,
"3D": 1
"cube": 1024,
"3D": 64
}
},
"vxgi": {
@ -48,7 +48,7 @@
"ext": {
"vulkan": {
"validation": {
"enabled": true,
"enabled": false,
"filters": [
"MessageID = 0x4dae5635", // UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout (false positive for cubemaps)
"MessageID = 0x609a13b", // UNASSIGNED-CoreValidation-Shader-OutputNotConsumed (from depth-only calls)
@ -68,6 +68,8 @@
},
"framebuffer": {
"msaa": 1,
// "size": 0.5
// "size": 0.75
"size": 1
// "size": [ 640, 480, "NEAREST" ]
// "size": [ 1280, 720 ]
@ -76,7 +78,7 @@
},
"gpu": 1,
"experimental": {
"batch queue submissions": true,
"batch queue submissions": false,
"rebuild on tick begin": false,
"dedicated thread": false
},
@ -113,6 +115,8 @@
"multiViewport",
"shaderOutputLayer",
"shaderInt64",
"shaderFloat64",
"shaderSubgroupClock",
"shaderSampledImageArrayDynamicIndexing",
"shaderStorageImageArrayDynamicIndexing"
],
@ -130,7 +134,9 @@
"VK_KHR_deferred_host_operations",
"VK_EXT_descriptor_indexing",
"VK_KHR_spirv_1_4",
"VK_KHR_shader_float_controls"
"VK_KHR_shader_float_controls",
"VK_KHR_shader_clock",
"VK_KHR_ray_query"
]
}
},

View File

@ -0,0 +1,39 @@
{
"type": "Object",
"name": "Cornell Box",
"ignore": false,
"import": "/model.json",
"assets": [
// "/cornell/cornell.glb"
{ "filename": "/cornell/cornell/graph.json" }
],
"behaviors": [],
"transform": {
"position": [ -0.23807, -0.984829, -30.4967 ],
"rotation": {
"axis": [ 0, 1, 0 ],
"angle": 0
},
"scale": [ 1, 1, 1 ]
},
"system": {
"hot reload": {
"enabled": true
}
},
"metadata": {
"track": true,
"hide": true,
"model": {
"lightmap": false,
"exporter": {
"enabled": false,
"unwrap": false,
"optimize": false
},
"baking": {
"enabled": false
}
}
}
}

View File

@ -2,7 +2,7 @@
"name": "Graph",
"type": "Object",
"ignore": false,
"behaviors": [ "LoadingBehavior" ],
// "behaviors": [ "LoadingBehavior" ],
"transform": {
"position": [ 0, 0, 0 ],
"rotation": { "axis": [ 0, 1, 0 ], "angle": 0 },

View File

@ -4,29 +4,35 @@
// { "filename": "./static.json", "delay": 8 },
// { "filename": "./models/mcdonalds.glb" }
{ "filename": "./models/mcdonalds/graph.json" }
{ "filename": "./models/mcdonalds/graph.json" },
// { "filename": "./models/mini_mcd.glb" }
// { "filename": "./models/mini_mcd/graph.json" }
// { "filename": "/cornell/cornell.glb" }
{ "filename": "/cornell/cornell/graph.json" }
],
"metadata": {
"model": {
"baking": {
"enabled": true,
"enabled": false,
"resolution": 2048,
"settings": {
"useInputMeshUvs": false
}
},
"cull mode": "none",
// "cull mode": "none",
"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 },
"cornellBox.000": {
"transform": { "position": [ 0, -2, -75 ], "scale": [ 3, 3, 3 ] }
},
"func_door_rotating_5409": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5487": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },

View File

@ -2,7 +2,8 @@
"import": "/scene.json",
"assets": [
"./audio/soundscape/ambience.ogg",
"./loading.json",
// "./loading.json",
"./mcdonalds.json",
"./static.json"
],
"system": {
@ -13,7 +14,8 @@
"shader": {
"mode": 1,
"scalar": 16,
"parameters": [ 0, 0, 0, "time" ]
"parameters": [ 0, 0, 0, "time" ],
"frame accumulate limit": 0
},
"clear values": [
[ 1, 1, 1, 0 ]
@ -34,13 +36,13 @@
"exposure": 1.0,
"gamma": 1.0,
"brightnessThreshold": 1.2,
// "ambient": [ 0, 0, 0 ],
"ambient": [ 0, 0, 0 ],
// "ambient": [ 0.025, 0.025, 0.025 ],
"ambient": [ 0.075, 0.075, 0.075 ],
// "ambient": [ 0.075, 0.075, 0.075 ],
// "ambient": [ 0.1, 0.1, 0.1 ],
// "ambient": [ 0.4, 0.4, 0.4 ],
"fog": {
"fog-": {
"color": [ 0.5, 0.5, 0.5 ],
"range": [ 16, 32 ],
"step scale": 2,

View File

@ -11,7 +11,7 @@
"cull mode": "none",
"alpha mode": "BLEND",
"baking": {
"enabled": true,
"enabled": false,
"resolution": 1024,
"settings": {
"useInputMeshUvs": false
@ -23,7 +23,7 @@
"grid": { "size": [3,1,3], "epsilon": 1.0, "cleanup": true, "print": true }
},
"/^cb$/": {
"grid": { "size": [12,1,12], "epsilon": 1.0, "cleanup": true, "print": true }
"grid": { "size": [6,1,6], "epsilon": 1.0, "cleanup": true, "print": true }
},
// "worldspawn_sh2": { "physics": { "type": "mesh", "static": true } },
"info_player_spawn": { "action": "attach", "filename": "./player.json", "preserve orientation": true },

View File

@ -8,13 +8,13 @@
// { "filename": "./models/tiny_msci/graph.json" }
// { "filename": "./models/micro_sci.glb" }
// { "filename": "./models/micro_sci/graph.json" }
{ "filename": "./models/micro_sci/graph.json" }
// { "filename": "./models/msci.glb" }
// { "filename": "./models/msci/graph.json" }
// { "filename": "./models/medsci.glb" }
{ "filename": "./models/medsci/graph.json" }
// { "filename": "./models/medsci/graph.json" }
],
"metadata": {
"model": {
@ -39,13 +39,13 @@
"light_30145": { "light": { "power": 120 } },
"prop_camera_103001_light": { "light": { "shadows": false, "static": false, "dynamic": true, "power": 30 } },
"prop_camera_103118_light": { "light": { "shadows": false, "static": false, "dynamic": true, "power": 30 } },
"prop_camera_103001": { "action": "load", "payload": { "import": "./camera.json" } },
"prop_camera_103118": { "action": "load", "payload": { "import": "./camera.json" } },
"func_movelinear_57637": { "action": "load", "payload": { "import": "./lift.json", "metadata": { "delta": [ 0,8.6,0 ] } } },
"func_movelinear_82820": { "action": "load", "payload": { "import": "./lift.json", "metadata": { "delta": [ 0,9.2,0 ] } } },
"func_movelinear_103114": { "action": "load", "payload": { "import": "./lift.json", "metadata": { "delta": [ 0,-3.0,0 ] } } }
"prop_camera_103001_light": { /*"bake": false,*/ "light": { "shadows": false, "static": false, "dynamic": true, "power": 30 } },
"prop_camera_103118_light": { /*"bake": false,*/ "light": { "shadows": false, "static": false, "dynamic": true, "power": 30 } },
"prop_camera_103001": { /*"bake": false,*/ "action": "load", "payload": { "import": "./camera.json" } },
"prop_camera_103118": { /*"bake": false,*/ "action": "load", "payload": { "import": "./camera.json" } },
"func_movelinear_57637": { /*"bake": false,*/ "action": "load", "payload": { "import": "./lift.json", "metadata": { "delta": [ 0,8.6,0 ] } } },
"func_movelinear_82820": { /*"bake": false,*/ "action": "load", "payload": { "import": "./lift.json", "metadata": { "delta": [ 0,9.2,0 ] } } },
"func_movelinear_103114": { /*"bake": false,*/ "action": "load", "payload": { "import": "./lift.json", "metadata": { "delta": [ 0,-3.0,0 ] } } }
}
}
}

View File

@ -2,7 +2,8 @@
"import": "/scene.json",
"assets": [
{ "filename": "./audio/music/medsci1.ogg", "category": "audio-stream", "override": true, "streamed": true },
"./loading.json"
// "./loading.json"
"./medsci.json"
],
"system": {
"hot reload": {

View File

@ -1,6 +1,7 @@
#version 450
#pragma shader_stage(vertex)
#include "../common/macros.h"
#include "../common/structs.h"
layout (constant_id = 0) const uint PASSES = 6;

View File

@ -1,6 +1,7 @@
#version 450
#pragma shader_stage(vertex)
#include "../common/macros.h"
#include "../common/structs.h"
layout (constant_id = 0) const uint PASSES = 6;

View File

@ -1,6 +1,7 @@
#version 450
#pragma shader_stage(vertex)
#include "../common/macros.h"
#include "../common/structs.h"
layout (constant_id = 0) const uint PASSES = 6;

View File

@ -2,6 +2,66 @@
float random(vec3 seed, int i){ return fract(sin(dot(vec4(seed,i), vec4(12.9898,78.233,45.164,94.673))) * 43758.5453); }
float rand2(vec2 co){ return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 143758.5453); }
float rand3(vec3 co){ return fract(sin(dot(co.xyz ,vec3(12.9898,78.233, 37.719))) * 143758.5453); }
//
uint tea(uint val0, uint val1) {
uint v0 = val0;
uint v1 = val1;
uint s0 = 0;
for(uint n = 0; n < 16; n++) {
s0 += 0x9e3779b9;
v0 += ((v1 << 4) + 0xa341316c) ^ (v1 + s0) ^ ((v1 >> 5) + 0xc8013ea4);
v1 += ((v0 << 4) + 0xad90777d) ^ (v0 + s0) ^ ((v0 >> 5) + 0x7e95761e);
}
return v0;
}
uint lcg(inout uint prev) {
uint LCG_A = 1664525u;
uint LCG_C = 1013904223u;
prev = (LCG_A * prev + LCG_C);
return prev & 0x00FFFFFF;
}
float rnd(inout uint prev) { return (float(lcg(prev)) / float(0x01000000)); }
uint prngSeed;
float rnd() { return rnd(prngSeed); }
//
void tangentBitangent(in vec3 N, out vec3 Nt, out vec3 Nb) {
if(abs(N.x) > abs(N.y)) Nt = vec3(N.z, 0, -N.x) / sqrt(N.x * N.x + N.z * N.z);
else Nt = vec3(0, -N.z, N.y) / sqrt(N.y * N.y + N.z * N.z);
Nb = cross(N, Nt);
}
vec3 samplingHemisphere(inout uint seed, in vec3 x, in vec3 y, in vec3 z) {
float r1 = rnd(seed);
float r2 = rnd(seed);
float sq = sqrt(1.0 - r2);
vec3 direction = vec3(cos(2 * PI * r1) * sq, sin(2 * PI * r1) * sq, sqrt(r2));
direction = direction.x * x + direction.y * y + direction.z * z;
return direction;
}
vec3 samplingHemisphere(inout uint seed, in vec3 z) {
vec3 x;
vec3 y;
tangentBitangent( z, x, y );
float r1 = rnd(seed);
float r2 = rnd(seed);
float sq = sqrt(1.0 - r2);
vec3 direction = vec3(cos(2 * PI * r1) * sq, sin(2 * PI * r1) * sq, sqrt(r2));
direction = direction.x * x + direction.y * y + direction.z * z;
return direction;
}
//
#if BUFFER_REFERENCE
uint64_t uvec2uint64( uvec2 src ) {
uint64_t dst;
dst = (src.x << 32) | src.y;
return dst;
}
#endif
//
float max3( vec3 v ) { return max(max(v.x, v.y), v.z); }
float min3( vec3 v ) { return min(min(v.x, v.y), v.z); }
uint biasedRound( float x, float bias ) { return uint( ( x < bias ) ? floor(x) : ceil(x)); }
@ -13,7 +73,7 @@ vec3 orthogonal(vec3 u){
return abs(dot(u, v)) > 0.99999f ? cross(u, vec3(0, 1, 0)) : cross(u, v);
}
vec4 blend( vec4 source, vec4 dest, float a ) {
return source * a + dest * (1.0 - a);
return source * a + dest * (1.0 - a);
}
float gauss( float x, float sigma ) {
return (1.0 / (2.0 * 3.14157 * sigma) * exp(-(x*x) / (2.0 * sigma)));
@ -33,17 +93,17 @@ vec2 encodeNormals( vec3 n ) {
return (vec2(atan(n.y,n.x)/PI, n.z)+1.0)*0.5;
}
vec3 encodeSrgb(vec3 rgb) {
const vec3 a = 12.92 * rgb;
const vec3 b = 1.055 * pow(rgb, vec3(1.0 / 2.4)) - 0.055;
const vec3 c = step(vec3(0.0031308), rgb);
return mix(a, b, c);
const vec3 a = 12.92 * rgb;
const vec3 b = 1.055 * pow(rgb, vec3(1.0 / 2.4)) - 0.055;
const vec3 c = step(vec3(0.0031308), rgb);
return mix(a, b, c);
}
vec3 decodeSrgb(vec3 rgb) {
const vec3 a = rgb / 12.92;
const vec3 b = pow((rgb + 0.055) / 1.055, vec3(2.4));
const vec3 c = step(vec3(0.04045), rgb);
return mix(a, b, c);
const vec3 a = rgb / 12.92;
const vec3 b = pow((rgb + 0.055) / 1.055, vec3(2.4));
const vec3 c = step(vec3(0.04045), rgb);
return mix(a, b, c);
}
bool validTextureIndex( int textureIndex ) {
return 0 <= textureIndex && textureIndex < MAX_TEXTURES;

View File

@ -52,10 +52,17 @@
#define nonuniformEXT(X) X
#endif
#if ADDRESS_ENABLED
#ifndef BUFFER_REFERENCE
#define BUFFER_REFERENCE 1
#else
#define UINT64_ENABLED 1
#endif
#if BUFFER_REFERENCE
#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
#extension GL_EXT_buffer_reference : enable
#extension GL_EXT_buffer_reference2 : enable
#extension GL_EXT_scalar_block_layout : enable
#endif
const float PI = 3.14159265359;

View File

@ -15,7 +15,7 @@ float gaSchlickGGX(float cosLi, float cosLo, float roughness) {
vec3 fresnelSchlick(vec3 F0, float cosTheta) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); }
#if (!BAKING && !COMPUTE) || RAYTRACE
void pbr() {
if ( bool(ubo.useLightmaps) && validTextureIndex( surface.instance.lightmapID ) ) return;
if ( surface.material.lightmapped && validTextureIndex( surface.instance.lightmapID ) ) return;
const float Rs = 4.0; // specular lighting looks gross without this
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);

View File

@ -134,9 +134,10 @@ struct Instance {
uint auxID;
Bounds bounds;
// InstanceAddresses addresses;
};
#if ADDRESS_ENABLED
#if UINT64_ENABLED
struct InstanceAddresses {
uint64_t vertex;
uint64_t index;
@ -160,6 +161,30 @@ struct InstanceAddresses {
uint64_t id;
uint64_t padding1;
};
#else
struct InstanceAddresses {
uvec2 vertex;
uvec2 index;
uvec2 indirect;
uint drawID;
uint padding0;
uvec2 position;
uvec2 uv;
uvec2 color;
uvec2 st;
uvec2 normal;
uvec2 tangent;
uvec2 joints;
uvec2 weights;
uvec2 id;
uvec2 padding1;
};
#endif
struct SurfaceMaterial {
@ -169,7 +194,7 @@ struct SurfaceMaterial {
float metallic;
float roughness;
float occlusion;
uint padding;
bool lightmapped;
};
struct Surface {
@ -178,6 +203,7 @@ struct Surface {
vec3 st;
Space position;
Space normal;
mat3 tbn;
Ray ray;
@ -242,13 +268,14 @@ struct Vertex {
};
struct Triangle {
uvec3 indices;
Vertex points[3];
Vertex point;
vec3 geomNormal;
uint instanceID;
};
struct RayTracePayload {
bool hit;
uint instanceID;
Triangle triangle;
};

View File

@ -174,7 +174,7 @@ void indirectLighting() {
if ( surface.material.albedo.a < 1.0 ) {
Ray ray;
ray.direction = surface.ray.direction;
ray.origin = surface.position.world; // + ray.direction;
ray.origin = surface.position.world + ray.direction;
vec4 radiance = voxelConeTrace( ray, surface.material.albedo.a * 0.5 );
surface.fragment.rgb += (1.0 - surface.material.albedo.a) * radiance.rgb;
}

View File

@ -1,7 +1,10 @@
#extension GL_EXT_samplerless_texture_functions : require
#extension GL_EXT_nonuniform_qualifier : enable
#define ADDRESS_ENABLED 1
#if RAYTRACE
#extension GL_EXT_ray_query : require
#endif
#define DEFERRED 1
#define MAX_TEXTURES TEXTURES
//#define TEXTURE_WORKAROUND 0
@ -64,39 +67,40 @@ layout (binding = 5) uniform UBO {
int indexSkybox;
uint useLightmaps;
uint padding2;
uint frameNumber;
uint padding3;
} ubo;
/*
*/
layout (std140, binding = 6) readonly buffer DrawCommands {
DrawCommand drawCommands[];
};
*/
layout (std140, binding = 6) readonly buffer Instances {
layout (std140, binding = 7) readonly buffer Instances {
Instance instances[];
};
layout (std140, binding = 7) readonly buffer Materials {
Material materials[];
};
layout (std140, binding = 8) readonly buffer Textures {
Texture textures[];
};
layout (std140, binding = 9) readonly buffer Lights {
Light lights[];
};
/*
layout (std140, binding = 10) readonly buffer InstanceAddresseses {
layout (std140, binding = 8) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[];
};
*/
layout (std140, binding = 9) readonly buffer Materials {
Material materials[];
};
layout (std140, binding = 10) readonly buffer Textures {
Texture textures[];
};
layout (std140, binding = 11) readonly buffer Lights {
Light lights[];
};
layout (binding = 11) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 12) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 13) uniform sampler3D samplerNoise;
layout (binding = 12) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 13) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 14) uniform sampler3D samplerNoise;
#if VXGI
layout (binding = 14) uniform usampler3D voxelId[CASCADES];
layout (binding = 15) uniform sampler3D voxelNormal[CASCADES];
layout (binding = 16) uniform sampler3D voxelRadiance[CASCADES];
layout (binding = 15) uniform usampler3D voxelId[CASCADES];
layout (binding = 16) uniform sampler3D voxelNormal[CASCADES];
layout (binding = 17) uniform sampler3D voxelRadiance[CASCADES];
#endif
#if RAYTRACE
layout (binding = 18) uniform accelerationStructureEXT tlas;
#endif
layout (location = 0) in vec2 inUv;
@ -105,6 +109,18 @@ layout (location = 1) in flat uvec2 inPushConstantPass;
layout (location = 0) out vec4 outFragColor;
layout (location = 1) out vec4 outFragBright;
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[]; };
#include "../common/functions.h"
#include "../common/fog.h"
#include "../common/light.h"
@ -201,11 +217,9 @@ void populateSurface() {
postProcess();
return;
}
// const DrawCommand drawCommand = drawCommands[drawID];
const DrawCommand drawCommand = drawCommands[drawID];
const Instance instance = instances[instanceID];
surface.instance = instance;
// surface.instance.materialID = instance.materialID;
// surface.instance.lightmapID = instance.lightmapID;
const Material material = materials[surface.instance.materialID];
surface.material.albedo = material.colorBase;
@ -230,7 +244,7 @@ void populateSurface() {
}
if ( validTextureIndex( material.indexAlbedo ) ) {
surface.material.albedo = sampleTexture( material.indexAlbedo );
surface.material.albedo *= sampleTexture( material.indexAlbedo );
}
// OPAQUE
if ( material.modeAlpha == 0 ) {
@ -244,7 +258,11 @@ void populateSurface() {
}
// Lightmap
if ( bool(ubo.useLightmaps) && validTextureIndex( surface.instance.lightmapID ) ) {
surface.light += surface.material.albedo * sampleTexture( surface.instance.lightmapID, surface.st );
vec4 light = sampleTexture( surface.instance.lightmapID, surface.st );
surface.material.lightmapped = light.a > 0.001;
if ( surface.material.lightmapped ) surface.light += surface.material.albedo * light;
} else {
surface.material.lightmapped = false;
}
// Emissive textures
if ( validTextureIndex( material.indexEmissive ) ) {
@ -262,9 +280,9 @@ void populateSurface() {
}
#else
#if !MULTISAMPLING
surface.material.albedo = subpassLoad(samplerAlbedo);
surface.material.albedo *= subpassLoad(samplerAlbedo);
#else
surface.material.albedo = subpassLoad(samplerAlbedo, msaa.currentID); // resolve(samplerAlbedo, ubo.msaa);
surface.material.albedo *= subpassLoad(samplerAlbedo, msaa.currentID); // resolve(samplerAlbedo, ubo.msaa);
#endif
#endif
}

View File

@ -0,0 +1,12 @@
#version 450
#pragma shader_stage(fragment)
#define DEFERRED_SAMPLING 1
#define MULTISAMPLING 1
#define RAYTRACE 1
#include "./subpass.h"
void main() {
resolveSurfaceFragment();
postProcess();
}

View File

@ -0,0 +1,13 @@
#version 450
#pragma shader_stage(fragment)
#define DEFERRED_SAMPLING 0
#define MULTISAMPLING 1
#define RAYTRACE 1
#include "./subpass.h"
void main() {
resolveSurfaceFragment();
postProcess();
}

View File

@ -0,0 +1,15 @@
#version 450
#pragma shader_stage(fragment)
#define VXGI 1
#define RAYTRACE 1
#define MULTISAMPLING 0
#define DEFERRED_SAMPLING 1
#include "./subpass.h"
void main() {
populateSurface();
indirectLighting();
directLighting();
postProcess();
}

View File

@ -0,0 +1,13 @@
#version 450
#pragma shader_stage(fragment)
#define VXGI 1
#define RAYTRACE 1
#define DEFERRED_SAMPLING 1
#define MULTISAMPLING 1
#include "./subpass.h"
void main() {
resolveSurfaceFragment();
postProcess();
}

View File

@ -0,0 +1,13 @@
#version 450
#pragma shader_stage(fragment)
#define VXGI 1
#define RAYTRACE 1
#define DEFERRED_SAMPLING 0
#define MULTISAMPLING 1
#include "./subpass.h"
void main() {
resolveSurfaceFragment();
postProcess();
}

View File

@ -0,0 +1,15 @@
#version 450
#pragma shader_stage(fragment)
#define VXGI 1
#define RAYTRACE 1
#define DEFERRED_SAMPLING 0
#define MULTISAMPLING 0
#include "./subpass.h"
void main() {
populateSurface();
indirectLighting();
directLighting();
postProcess();
}

View File

@ -3,7 +3,6 @@
layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
#define LAMBERT 0
#define PBR 1
#define VXGI 1
@ -16,7 +15,7 @@ layout (constant_id = 2) const uint CASCADES = 16;
#include "../common/macros.h"
#include "../common/structs.h"
layout (binding = 4) uniform UBO {
layout (binding = 0) uniform UBO {
EyeMatrices matrices[2];
Mode mode;
@ -41,34 +40,35 @@ layout (binding = 4) uniform UBO {
uint padding2;
uint padding3;
} ubo;
/*
layout (std140, binding = 5) readonly buffer DrawCommands {
layout (std140, binding = 1) readonly buffer DrawCommands {
DrawCommand drawCommands[];
};
*/
layout (std140, binding = 5) readonly buffer Instances {
layout (std140, binding = 2) readonly buffer Instances {
Instance instances[];
};
layout (std140, binding = 6) readonly buffer Materials {
layout (std140, binding = 3) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[];
};
layout (std140, binding = 4) readonly buffer Materials {
Material materials[];
};
layout (std140, binding = 7) readonly buffer Textures {
layout (std140, binding = 5) readonly buffer Textures {
Texture textures[];
};
layout (std140, binding = 8) readonly buffer Lights {
layout (std140, binding = 6) readonly buffer Lights {
Light lights[];
};
layout (binding = 9) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 10) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 11) uniform sampler3D samplerNoise;
layout (binding = 7) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 8) uniform samplerCube samplerCubemaps[CUBEMAPS];
layout (binding = 9) uniform sampler3D samplerNoise;
layout (binding = 12, rg16ui) uniform volatile coherent uimage3D voxelId[CASCADES];
layout (binding = 13, rg16f) uniform volatile coherent image3D voxelNormal[CASCADES];
layout (binding = 10, rg16ui) uniform volatile coherent uimage3D voxelId[CASCADES];
layout (binding = 11, rg16f) uniform volatile coherent image3D voxelNormal[CASCADES];
#if VXGI_HDR
layout (binding = 14, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES];
layout (binding = 12, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES];
#else
layout (binding = 14, rgba8) uniform volatile coherent image3D voxelRadiance[CASCADES];
layout (binding = 12, rgba8) uniform volatile coherent image3D voxelRadiance[CASCADES];
#endif
#include "../common/functions.h"

View File

@ -19,20 +19,26 @@ layout (binding = 6) uniform samplerCube samplerCubemaps[CUBEMAPS];
#include "../../common/macros.h"
#include "../../common/structs.h"
layout (std140, binding = 7) readonly buffer Instances {
layout (std140, binding = 7) readonly buffer DrawCommands {
DrawCommand drawCommands[];
};
layout (std140, binding = 8) readonly buffer Instances {
Instance instances[];
};
layout (std140, binding = 8) readonly buffer Materials {
layout (std140, binding = 9) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[];
};
layout (std140, binding = 10) readonly buffer Materials {
Material materials[];
};
layout (std140, binding = 9) readonly buffer Textures {
layout (std140, binding = 11) readonly buffer Textures {
Texture textures[];
};
layout (std140, binding = 10) readonly buffer Lights {
layout (std140, binding = 12) readonly buffer Lights {
Light lights[];
};
layout (binding = 11, rgba8) uniform volatile coherent image3D outAlbedos;
layout (binding = 13, rgba8) uniform volatile coherent image3D outAlbedos;
#include "../../common/functions.h"
#include "../../common/shadows.h"

View File

@ -9,15 +9,24 @@ layout (constant_id = 0) const uint TEXTURES = 1;
#include "../common/structs.h"
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES];
layout (std140, binding = 6) readonly buffer Instances {
layout (std140, binding = 6) readonly buffer DrawCommands {
DrawCommand drawCommands[];
};
layout (std140, binding = 7) readonly buffer Instances {
Instance instances[];
};
layout (std140, binding = 7) readonly buffer Materials {
layout (std140, binding = 8) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[];
};
layout (std140, binding = 9) readonly buffer Materials {
Material materials[];
};
layout (std140, binding = 8) readonly buffer Textures {
layout (std140, binding = 10) readonly buffer Textures {
Texture textures[];
};
layout (std140, binding = 11) readonly buffer Lights {
Light lights[];
};
#include "../common/functions.h"
@ -82,16 +91,16 @@ void main() {
}
#if USE_LIGHTMAP && !DEFERRED_SAMPLING
if ( validTextureIndex( instance.lightmapID ) ) {
A.rgb *= sampleTexture( instance.lightmapID, surface.st ).rgb;
vec4 light = sampleTexture( instance.lightmapID, surface.st );
if ( light.a > 0.001 ) A.rgb *= light.rgb;
}
#endif
#endif
#if !DEFERRED_SAMPLING
// sample normal
if ( validTextureIndex( material.indexNormal ) ) {
Texture t = textures[material.indexNormal];
N = inTBN * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - vec3(1.0));
}
#if !DEFERRED_SAMPLING
#if 0
// sample metallic/roughness
if ( validTextureIndex( material.indexMetallicRoughness ) ) {

View File

@ -3,6 +3,8 @@ layout (constant_id = 0) const uint PASSES = 6;
#if LAYERED
#extension GL_ARB_shader_viewport_layer_array : enable
#endif
#include "../common/macros.h"
#include "../common/structs.h"
layout (location = 0) in vec3 inPos;
@ -11,9 +13,10 @@ layout (location = 2) in vec4 inColor;
layout (location = 3) in vec2 inSt;
layout (location = 4) in vec3 inNormal;
layout (location = 5) in vec4 inTangent;
layout (location = 6) in uvec2 inId;
#if SKINNED
layout (location = 6) in uvec4 inJoints;
layout (location = 7) in vec4 inWeights;
layout (location = 7) in uvec4 inJoints;
layout (location = 8) in vec4 inWeights;
#endif
layout( push_constant ) uniform PushBlock {

View File

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

View File

@ -11,25 +11,35 @@ layout (constant_id = 1) const uint CASCADES = 16;
#include "../common/structs.h"
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES];
layout (std140, binding = 6) readonly buffer Instances {
layout (std140, binding = 6) readonly buffer DrawCommands {
DrawCommand drawCommands[];
};
layout (std140, binding = 7) readonly buffer Instances {
Instance instances[];
};
layout (std140, binding = 7) readonly buffer Materials {
Material materials[];
};
layout (std140, binding = 8) readonly buffer Textures {
Texture textures[];
layout (std140, binding = 8) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[];
};
layout (binding = 9, rg16ui) uniform volatile coherent uimage3D voxelId[CASCADES];
layout (binding = 10, rg16f) uniform volatile coherent image3D voxelNormal[CASCADES];
layout (std140, binding = 9) readonly buffer Materials {
Material materials[];
};
layout (std140, binding = 10) readonly buffer Textures {
Texture textures[];
};
layout (std140, binding = 11) readonly buffer Lights {
Light lights[];
};
layout (binding = 12, rg16ui) uniform volatile coherent uimage3D voxelId[CASCADES];
layout (binding = 13, rg16f) uniform volatile coherent image3D voxelNormal[CASCADES];
#if VXGI_HDR
layout (binding = 11, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES];
layout (binding = 14, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES];
#else
layout (binding = 11, rgba8) uniform volatile coherent image3D voxelRadiance[CASCADES];
layout (binding = 14, rgba8) uniform volatile coherent image3D voxelRadiance[CASCADES];
#endif
#if DEPTH_TEST
layout (binding = 12, r16f) uniform volatile coherent image3D voxelDepth[CASCADES];
layout (binding = 15, r16f) uniform volatile coherent image3D voxelDepth[CASCADES];
#endif
layout (location = 0) in vec2 inUv;

View File

@ -1,12 +1,14 @@
#version 460
#extension GL_EXT_ray_tracing : enable
#extension GL_ARB_shader_clock : 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
@ -14,6 +16,8 @@ layout (constant_id = 3) const uint CASCADES = 4;
#define FOG 0
#define WHITENOISE 0
#define MAX_TEXTURES TEXTURES
#define TONE_MAP 1
#define GAMMA_CORRECT 1
#include "../common/macros.h"
#include "../common/structs.h"
@ -49,7 +53,7 @@ layout (binding = 2) uniform UBO {
int indexSkybox;
uint useLightmaps;
uint padding2;
uint frameNumber;
uint padding3;
} ubo;
@ -83,47 +87,79 @@ layout (location = 0) rayPayloadEXT RayTracePayload payload;
#include "../common/vxgi.h"
#endif
float shadowFactor( const Light light, float def ) {
void trace( Ray ray, float tMin, float tMax ) {
uint rayFlags = gl_RayFlagsOpaqueEXT;
uint cullMask = 0xFF;
payload.hit = false;
traceRayEXT(tlas, rayFlags, cullMask, 0, 0, 0, ray.origin, tMin, ray.direction, tMax, 0);
}
void trace( Ray ray, float tMin ) {
uint rayFlags = gl_RayFlagsOpaqueEXT;
uint cullMask = 0xFF;
float tMax = 4096.0;
payload.hit = false;
traceRayEXT(tlas, rayFlags, cullMask, 0, 0, 0, ray.origin, tMin, ray.direction, tMax, 0);
}
void trace( Ray ray ) {
trace( ray, 0.001, 4096.0 );
}
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;
float tMin = 0.001;
float tMax = length(ray.direction);
ray.direction = normalize(ray.direction);
uint rayFlags = gl_RayFlagsOpaqueEXT | gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsSkipClosestHitShaderEXT;
uint cullMask = 0xFF;
payload.hit = true;
traceRayEXT(tlas, rayFlags, cullMask, 0, 0, 0, ray.origin.xyz, tMin, ray.direction.xyz, tMax, 0);
traceRayEXT(tlas, rayFlags, cullMask, 0, 0, 0, ray.origin, tMin, ray.direction, tMax, 0);
return payload.hit ? 0.0 : 1.0;
}
void processHit( uint instanceID, Triangle triangle ) {
const Instance instance = instances[instanceID];
void setupSurface( RayTracePayload payload ) {
const Instance instance = instances[payload.triangle.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.world = vec3( instance.model * vec4(payload.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) );
surface.normal.world = normalize(vec3( instance.model * vec4(payload.triangle.point.normal, 0.0 ) ));
// surface.normal.world = faceforward( surface.normal.world, surface.ray.direction, surface.normal.world );
// surface.normal.eye = normalize(vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) ));
// surface.tbn[0] = normalize(vec3( instance.model * vec4(payload.triangle.tbn[0], 0.0 ) ));
// surface.tbn[1] = normalize(vec3( instance.model * vec4(payload.triangle.tbn[1], 0.0 ) ));
// surface.tbn[2] = surface.normal.world;
vec3 tangent = normalize(vec3( instance.model * vec4(payload.triangle.point.tangent, 0.0) ));
vec3 bitangent = normalize(vec3( instance.model * vec4(cross( payload.triangle.point.normal, payload.triangle.point.tangent ), 0.0) ));
if ( payload.triangle.point.tangent != vec3(0) ) {
surface.tbn = mat3(tangent, bitangent, payload.triangle.point.normal);
} else {
surface.tbn = mat3(1);
}
}
// bind UVs
{
surface.uv.xy = triangle.point.uv;
surface.st.xy = triangle.point.st;
surface.uv.xy = payload.triangle.point.uv;
surface.st.xy = payload.triangle.point.st;
}
const Material material = materials[surface.instance.materialID];
@ -131,11 +167,10 @@ void processHit( uint instanceID, Triangle triangle ) {
surface.material.metallic = material.factorMetallic;
surface.material.roughness = material.factorRoughness;
surface.material.occlusion = material.factorOcclusion;
surface.fragment = material.colorEmissive;
surface.light = material.colorEmissive;
if ( validTextureIndex( material.indexAlbedo ) ) {
surface.material.albedo = sampleTexture( material.indexAlbedo );
surface.material.albedo *= sampleTexture( material.indexAlbedo );
}
// OPAQUE
if ( material.modeAlpha == 0 ) {
@ -149,7 +184,11 @@ void processHit( uint instanceID, Triangle triangle ) {
}
// Lightmap
if ( bool(ubo.useLightmaps) && validTextureIndex( surface.instance.lightmapID ) ) {
surface.light += surface.material.albedo * sampleTexture( surface.instance.lightmapID, surface.st );
vec4 light = sampleTexture( surface.instance.lightmapID, surface.st );
surface.material.lightmapped = light.a > 0.001;
if ( surface.material.lightmapped ) surface.light += surface.material.albedo * light;
} else {
surface.material.lightmapped = false;
}
// Emissive textures
if ( validTextureIndex( material.indexEmissive ) ) {
@ -165,103 +204,174 @@ void processHit( uint instanceID, Triangle triangle ) {
surface.material.metallic = samp.r;
surface.material.roughness = samp.g;
}
#if VXGI
{
indirectLighting();
// Normals
if ( validTextureIndex( material.indexNormal ) && surface.tbn != mat3(1) ) {
surface.normal.world = surface.tbn * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - vec3(1.0));
}
#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;
surface.normal.eye = normalize(vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) ));
}
}
void trace( float tMin, float tMax ) {
uint rayFlags = gl_RayFlagsOpaqueEXT;
uint cullMask = 0xFF;
void directLighting() {
#if VXGI
indirectLighting();
#endif
payload.hit = false;
traceRayEXT(tlas, rayFlags, cullMask, 0, 0, 0, surface.ray.origin.xyz, tMin, surface.ray.direction.xyz, tMax, 0);
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();
#elif LAMBERT
lambert();
#elif PHONG
phong();
#endif
surface.fragment.rgb += surface.light.rgb;
surface.fragment.a = surface.material.albedo.a;
}
vec4 traceStep( Ray ray ) {
vec4 outFrag = vec4(0);
// initial condition
{
trace( ray );
if ( payload.hit ) {
setupSurface( payload );
directLighting();
outFrag = surface.fragment;
} else if ( 0 <= ubo.indexSkybox && ubo.indexSkybox < CUBEMAPS ) {
outFrag = texture( samplerCubemaps[ubo.indexSkybox], ray.direction );
}
}
// "transparency"
if ( payload.hit && surface.material.albedo.a < 0.999 ) {
if ( surface.material.albedo.a < 0.001 ) outFrag = vec4(0);
RayTracePayload surfacePayload = payload;
Ray transparency;
transparency.direction = ray.direction;
transparency.origin = surface.position.world;
vec4 transparencyColor = vec4(1.0 - surface.material.albedo.a);
trace( transparency, 1.75 );
if ( payload.hit ) {
setupSurface( payload );
directLighting();
transparencyColor *= surface.fragment;
} else if ( 0 <= ubo.indexSkybox && ubo.indexSkybox < CUBEMAPS ) {
transparencyColor *= texture( samplerCubemaps[ubo.indexSkybox], ray.direction );
}
outFrag += transparencyColor;
payload = surfacePayload;
setupSurface( payload );
}
// reflection
if ( payload.hit ) {
const float REFLECTIVITY = 1.0 - surface.material.roughness;
const vec4 REFLECTED_ALBEDO = surface.material.albedo * REFLECTIVITY;
if ( REFLECTIVITY > 0.001 ) {
RayTracePayload surfacePayload = payload;
Ray reflection;
reflection.origin = surface.position.world;
reflection.direction = reflect( ray.direction, surface.normal.world );
trace( reflection );
vec4 reflectionColor = REFLECTED_ALBEDO;
if ( payload.hit ) {
setupSurface( payload );
directLighting();
reflectionColor *= surface.fragment;
} else if ( 0 <= ubo.indexSkybox && ubo.indexSkybox < CUBEMAPS ) {
reflectionColor *= texture( samplerCubemaps[ubo.indexSkybox], reflection.direction );
}
outFrag += reflectionColor;
payload = surfacePayload;
setupSurface( payload );
}
}
return outFrag;
}
void main() {
{
surface.fragment = vec4(0);
surface.pass = PushConstant.pass;
// if ( ubo.frameNumber > 16 ) return;
// prngSeed = tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, ubo.frameNumber);
prngSeed = tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, int(clockARB()));
surface.pass = PushConstant.pass;
vec4 outFrag = vec4(0);
const vec2 inUv = (vec2(gl_LaunchIDEXT.xy) + vec2(0.5)) / vec2(gl_LaunchSizeEXT.xy);
const uint SAMPLES = 1;
const uint NUM_PATHS = 2;
#if 0
const uint FRAME_ACCUMULATION_VALUE = ubo.frameNumber + 1;
#else
const uint FRAME_ACCUMULATION_VALUE = min(32, ubo.frameNumber + 1);
#endif
const float BLEND_FACTOR = 1.0f / float(FRAME_ACCUMULATION_VALUE);
uint FRAME_NUMBER = ubo.frameNumber;
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;
for ( uint samp = 0; samp < SAMPLES; ++samp, ++FRAME_NUMBER ) {
{
const vec2 center = ( FRAME_NUMBER > 0 ) ? vec2( rnd(), rnd() ) : vec2(0.5);
const vec2 inUv = (vec2(gl_LaunchIDEXT.xy) + center) / vec2(gl_LaunchSizeEXT.xy);
#if 0
vec4 target = ubo.eyes[surface.pass].iProjection * vec4(inUv.x * 2.0f - 1.0f, inUv.y * 2.0f - 1.0f, 1, 1);
vec4 direction = ubo.eyes[surface.pass].iView * vec4(normalize(target.xyz), 0);
surface.ray.direction = normalize( far3 - near3 );
surface.ray.origin = ubo.eyes[surface.pass].eyePos.xyz;
}
trace( 0.001, 4096.0 );
surface.ray.direction = vec3(direction);
surface.ray.origin = ubo.eyes[surface.pass].eyePos.xyz;
#else
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;
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;
}
surface.ray.direction = normalize( far3 - near3 );
surface.ray.origin = ubo.eyes[surface.pass].eyePos.xyz;
#endif
}
#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 );
{
vec4 curValue = vec4(0);
vec4 curWeight = vec4(1);
for ( uint path = 0; path <= NUM_PATHS; ++path ) {
vec4 stepValue = traceStep( surface.ray );
curValue += stepValue * curWeight;
if ( payload.hit ) {
processHit( payload.instanceID, payload.triangle );
vec4 front = surface.fragment;
if ( !payload.hit ) break;
// surface.fragment = mix( front, back, back.a );
surface.fragment.rgb = front.rgb * front.a + back.rgb * back.a;
} else {
surface.fragment = back;
surface.ray.origin = surface.position.world;
surface.ray.direction = samplingHemisphere( prngSeed, surface.normal.world );
curWeight *= surface.material.albedo * dot( surface.ray.direction, surface.normal.world );
if ( length(curWeight) < 0.01 ) break;
}
outFrag += curValue;
}
#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);
outFrag /= SAMPLES;
outFrag.a = 1;
#if BLOOM
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);
#endif
#if FOG
fog( surface.ray, surface.fragment.rgb, surface.fragment.a );
#endif
@ -274,7 +384,48 @@ void main() {
#if WHITENOISE
if ( enabled(ubo.mode.type, 1) ) whitenoise(surface.fragment.rgb, ubo.mode.parameters);
#endif
imageStore(outImage, ivec2(gl_LaunchIDEXT.xy), surface.fragment);
}
}
if ( ubo.frameNumber == 0 ) {
imageStore(outImage, ivec2(gl_LaunchIDEXT.xy), outFrag);
} else {
// if ( length(outFrag.rgb) < 0.01f ) return;
vec4 blended = mix(imageLoad(outImage, ivec2(gl_LaunchIDEXT.xy)), outFrag, BLEND_FACTOR);
imageStore(outImage, ivec2(gl_LaunchIDEXT.xy), blended);
}
}
/*
{
vec4 curValue = vec4(0);
vec4 curWeight = vec4(1);
for ( uint path = 0; path < NUM_PATHS; ++path ) {
trace( surface.ray );
if ( !payload.hit ) {
if ( path == 0 && 0 <= ubo.indexSkybox && ubo.indexSkybox < CUBEMAPS ) {
curValue = texture( samplerCubemaps[ubo.indexSkybox], surface.ray.direction );
}
break;
}
setupSurface( payload );
directLighting();
curValue += surface.fragment * curWeight;
surface.ray.origin = surface.position.world;
if ( !false ) {
surface.ray.direction = reflect( surface.ray.direction, surface.normal.world );
curWeight *= (1.0 - surface.material.roughness) * surface.material.albedo * dot( surface.ray.direction, surface.normal.world );
} else {
surface.ray.direction = samplingHemisphere( prngSeed, surface.normal.world );
curWeight *= surface.material.albedo * dot( surface.ray.direction, surface.normal.world );
}
if ( length(curWeight) < 0.01 ) break;
}
outFrag += curValue;
}
*/

View File

@ -9,7 +9,7 @@ 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 BUFFER_REFERENCE 1
#define COMPUTE 1
#define PBR 1
#define RAYTRACE 1
@ -18,6 +18,7 @@ layout (constant_id = 2) const uint CUBEMAPS = 128;
#include "../common/macros.h"
#include "../common/structs.h"
layout (std140, binding = 10) readonly buffer InstanceAddresseses {
InstanceAddresses instanceAddresses[];
};
@ -55,37 +56,56 @@ void main() {
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;
Vertex points[3];
uvec3 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[_]];
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[_]];
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[_]];
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[_]];
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[_]];
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.tangent ) {
VTangent buf = VTangent(nonuniformEXT(instanceAddresses.tangent));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].tangent = 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];
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];
triangle.point.tangent = /*triangle.*/points[0].tangent * bary[0] + /*triangle.*/points[1].tangent * bary[1] + /*triangle.*/points[2].tangent * bary[2];
triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
triangle.instanceID = instanceID;
/*
{
vec3 edge1 = points[1].position - points[0].position;
vec3 edge2 = points[2].position - points[1].position;
vec3 deltaUv1 = points[1].uv - points[0].uv;
vec3 deltaUv2 = points[2].uv - points[1].uv;
float f = 1.0f / (deltaUv1.x * deltaUv2.y - deltaUv2.x * deltaUv1.y);
vec3 tangent;
tangent1.x = f * ();
}
*/
payload.hit = true;
payload.instanceID = instanceID;
payload.triangle = triangle;
}

View File

@ -1,15 +1,13 @@
#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 BUFFER_REFERENCE 1
#define COMPUTE 1
#define PBR 1
#define RAYTRACE 1
@ -55,37 +53,56 @@ void main() {
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;
Vertex points[3];
uvec3 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[_]];
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[_]];
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[_]];
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[_]];
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[_]];
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal = buf.v[/*triangle.*/indices[_]];
}
if ( 0 < instanceAddresses.tangent ) {
VTangent buf = VTangent(nonuniformEXT(instanceAddresses.tangent));
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].tangent = 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];
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];
triangle.point.tangent = /*triangle.*/points[0].tangent * bary[0] + /*triangle.*/points[1].tangent * bary[1] + /*triangle.*/points[2].tangent * bary[2];
triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
triangle.instanceID = instanceID;
/*
{
vec3 edge1 = points[1].position - points[0].position;
vec3 edge2 = points[2].position - points[1].position;
vec3 deltaUv1 = points[1].uv - points[0].uv;
vec3 deltaUv2 = points[2].uv - points[1].uv;
float f = 1.0f / (deltaUv1.x * deltaUv2.y - deltaUv2.x * deltaUv1.y);
vec3 tangent;
tangent1.x = f * ();
}
*/
payload.hit = true;
payload.instanceID = instanceID;
payload.triangle = triangle;
}

View File

@ -2,7 +2,7 @@
#extension GL_EXT_ray_tracing : enable
#pragma shader_stage(miss)
#define ADDRESS_ENABLED 1
#define BUFFER_REFERENCE 1
#define COMPUTE 1
#define PBR 1
#define RAYTRACE 1

View File

@ -64,7 +64,7 @@ namespace pod {
uf::stl::KeyMap<pod::Instance> instances;
uf::stl::KeyMap<pod::InstanceAddresses> instanceAddresses;
uf::stl::KeyMap<pod::Instance::Addresses> instanceAddresses;
uf::stl::KeyMap<uf::stl::vector<pod::Primitive>> primitives;
uf::stl::KeyMap<uf::stl::vector<pod::DrawCommand>> drawCommands;
uf::stl::KeyMap<uf::Mesh> meshes;

View File

@ -7,6 +7,7 @@ namespace uf {
pod::ColorRgba color{ (uint8_t) ~0, (uint8_t) ~0, (uint8_t) ~0, (uint8_t) ~0 };
pod::Vector2f st{};
pod::Vector3f normal{};
pod::Vector3f tangent{};
pod::Vector<uint16_t, 2> id{};
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
@ -18,9 +19,9 @@ namespace uf {
pod::Vector2f st{};
pod::Vector3f normal{};
pod::Vector3f tangent{};
pod::Vector<uint16_t, 2> id{};
pod::Vector<uint16_t, 4> joints{};
pod::Vector4f weights{};
pod::Vector<uint16_t, 2> id{};
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
};

View File

@ -0,0 +1,16 @@
#pragma once
#include <uf/config.h>
#if UF_USE_IMGUI
namespace ext {
namespace imgui {
void initialize();
void tick();
void render();
void terminate();
}
}
#endif

View File

@ -78,6 +78,8 @@ namespace ext {
struct AccelerationStructure {
VkAccelerationStructureKHR handle{VK_NULL_HANDLE};
size_t deviceAddress{};
Buffer buffer{};
size_t instanceID{};
};
}

View File

@ -59,7 +59,8 @@ namespace uf {
// Equality checking
template<typename T=pod::Matrix4> int /*UF_API*/ compareTo( const T& left, const T& right ); // Equality check between two matrices (less than)
template<typename T=pod::Matrix4> bool /*UF_API*/ equals( const T& left, const T& right ); // Equality check between two matrices (equals)
template<typename T=pod::Matrix4> bool /*UF_API*/ equals( const T& left, const T& right ); // Equality check between two matrices (equals)
template<typename T=pod::Matrix4> bool /*UF_API*/ equals( const T& left, const T& right, float eps ); // Equality check between two matrices (equals)
// Basic arithmetic
// template<typename T=pod::Matrix4> pod::Matrix<typename T::type_t, C, C> /*UF_API*/ multiply( const T& left, const T& right ); // Multiplies two matrices of same type and size together
template<typename T, typename U> pod::Matrix<typename T::type_t, T::columns, T::columns> multiply( const T& left, const U& right ); // Multiplies two matrices of same type and size together

View File

@ -146,6 +146,15 @@ template<typename T> int uf::matrix::compareTo( const T& left, const T& right )
template<typename T> bool uf::matrix::equals( const T& left, const T& right ) {
return uf::matrix::compareTo(left, right) == 0;
}
template<typename T> bool uf::matrix::equals( const T& left, const T& right, float eps ) {
bool equals = true;
for ( size_t i = 0; i < 16; ++i ) {
if ( abs(left[i] - right[i]) <= eps ) continue;
equals = false;
break;
}
return equals;
}
// Basic arithmetic
// Multiplies two matrices of same type and size together
template<typename T> pod::Matrix<T,4,4> uf::matrix::multiply( const pod::Matrix<T,4,4>& left, const pod::Matrix<T,4,4>& right ) {

View File

@ -80,31 +80,33 @@ namespace pod {
pod::Vector3f max = { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max() };
alignas(4) float padding2 = 0;
} bounds;
struct UF_API Addresses {
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{};
alignas(8) uint64_t color{};
alignas(8) uint64_t st{};
alignas(8) uint64_t normal{};
alignas(8) uint64_t tangent{};
alignas(8) uint64_t joints{};
alignas(8) uint64_t weights{};
alignas(8) uint64_t id{};
alignas(8) uint64_t padding1{};
};
// Addresses addresses = {};
};
struct UF_API InstanceAddresses {
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{};
alignas(8) uint64_t color{};
alignas(8) uint64_t st{};
alignas(8) uint64_t normal{};
alignas(8) uint64_t tangent{};
alignas(8) uint64_t joints{};
alignas(8) uint64_t weights{};
alignas(8) uint64_t id{};
alignas(8) uint64_t padding1{};
};
struct Primitive {
pod::DrawCommand drawCommand;

View File

@ -225,6 +225,7 @@ namespace {
});
// remove extraneous buffers
#if 0
if ( !mesh.isInterleaved() ) {
uf::stl::vector<size_t> remove; remove.reserve(mesh.vertex.attributes.size());
@ -235,13 +236,13 @@ namespace {
if ( attribute.descriptor.name == "uv" ) continue;
if ( attribute.descriptor.name == "st" ) continue;
#if !UF_USE_OPENGL
if ( attribute.descriptor.name == "normal" ) continue;
if ( attribute.descriptor.name == "tangent" ) continue;
if ( graph.metadata["flags"]["SKINNED"].as<bool>() ) {
if ( attribute.descriptor.name == "tangent" ) continue;
if ( attribute.descriptor.name == "joints" ) continue;
if ( attribute.descriptor.name == "weights" ) continue;
}
#if !UF_USE_OPENGL
if ( attribute.descriptor.name == "normal" ) continue;
#endif
remove.insert(remove.begin(), i);
@ -255,6 +256,7 @@ namespace {
} else {
UF_MSG_DEBUG("Attribute removal requested yet mesh is not interleaved, ignoring...");
}
#endif
mesh.updateDescriptor();

View File

@ -22,6 +22,7 @@ UF_VERTEX_DESCRIPTOR(uf::graph::mesh::Base,
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R8G8B8A8_UNORM, color)
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R32G32_SFLOAT, st)
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R32G32B32_SFLOAT, normal)
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R32G32B32_SFLOAT, tangent)
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Base, R16G16_UINT, id)
);
UF_VERTEX_DESCRIPTOR(uf::graph::mesh::Skinned,
@ -31,9 +32,9 @@ UF_VERTEX_DESCRIPTOR(uf::graph::mesh::Skinned,
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R32G32_SFLOAT, st)
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R32G32B32_SFLOAT, normal)
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R32G32B32_SFLOAT, tangent)
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R16G16_UINT, id)
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R16G16B16A16_UINT, joints)
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R32G32B32A32_SFLOAT, weights)
UF_VERTEX_DESCRIPTION(uf::graph::mesh::Skinned, R16G16_UINT, id)
);
pod::Matrix4f uf::graph::local( pod::Graph& graph, int32_t index ) {
@ -160,7 +161,9 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
{
auto& shader = graphic.material.getShader("fragment");
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.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() );
@ -235,7 +238,9 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
}
}
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.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() );
@ -287,7 +292,9 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
}
}
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.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() );
@ -345,7 +352,9 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
}
}
shader.buffers.emplace_back( uf::graph::storage.buffers.drawCommands.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.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() );
@ -598,6 +607,8 @@ void uf::graph::process( pod::Graph& graph ) {
// remap instance variables
for ( auto& name : graph.instances ) {
auto& instance = uf::graph::storage.instances[name];
// auto& instanceAddresses = uf::graph::storage.instanceAddresses[name];
// instance.addresses = instanceAddresses;
if ( 0 <= instance.materialID && instance.materialID < graph.materials.size() ) {
auto& keys = /*graph.storage*/uf::graph::storage.materials.keys;
@ -772,6 +783,7 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
});
if ( ext::json::isObject( tag ) ) {
if ( tag["ignore"].as<bool>() ) return;
if ( graph.metadata["baking"]["enabled"].as<bool>(false) && !tag["bake"].as<bool>(true) ) return;
if ( tag["action"].as<uf::stl::string>() == "load" ) {
if ( tag["filename"].is<uf::stl::string>() ) {
@ -1155,7 +1167,7 @@ void uf::graph::initialize() {
uf::graph::storage.buffers.camera.initialize( (const void*) nullptr, sizeof(pod::Camera::Viewports), uf::renderer::enums::Buffer::UNIFORM );
uf::graph::storage.buffers.drawCommands.initialize( (const void*) nullptr, sizeof(pod::DrawCommand) * MAX_SIZE, uf::renderer::enums::Buffer::STORAGE );
uf::graph::storage.buffers.instance.initialize( (const void*) nullptr, sizeof(pod::Instance) * MAX_SIZE, uf::renderer::enums::Buffer::STORAGE );
uf::graph::storage.buffers.instanceAddresses.initialize( (const void*) nullptr, sizeof(pod::InstanceAddresses) * MAX_SIZE, uf::renderer::enums::Buffer::STORAGE );
uf::graph::storage.buffers.instanceAddresses.initialize( (const void*) nullptr, sizeof(pod::Instance::Addresses) * MAX_SIZE, uf::renderer::enums::Buffer::STORAGE );
uf::graph::storage.buffers.joint.initialize( (const void*) nullptr, sizeof(pod::Matrix4f) * MAX_SIZE, uf::renderer::enums::Buffer::STORAGE );
uf::graph::storage.buffers.material.initialize( (const void*) nullptr, sizeof(pod::Material) * MAX_SIZE, uf::renderer::enums::Buffer::STORAGE );
uf::graph::storage.buffers.texture.initialize( (const void*) nullptr, sizeof(pod::Texture) * MAX_SIZE, uf::renderer::enums::Buffer::STORAGE );
@ -1170,12 +1182,12 @@ void uf::graph::tick() {
uf::stl::vector<pod::Instance> instances = uf::graph::storage.instances.flatten();
uf::graph::storage.buffers.instance.update( (const void*) instances.data(), instances.size() * sizeof(pod::Instance) );
/*
uf::stl::vector<pod::InstanceAddresses> instanceAddresses; instanceAddresses.reserve(uf::graph::storage.instanceAddresses.map.size());
uf::stl::vector<pod::Instance::Addresses> instanceAddresses; instanceAddresses.reserve(uf::graph::storage.instanceAddresses.map.size());
for ( auto& key : uf::graph::storage.instances.keys ) instanceAddresses.emplace_back( uf::graph::storage.instanceAddresses.map[key] );
if ( !instanceAddresses.empty() ) uf::graph::storage.buffers.instanceAddresses.update( (const void*) instanceAddresses.data(), instanceAddresses.size() * sizeof(pod::InstanceAddresses) );
if ( !instanceAddresses.empty() ) uf::graph::storage.buffers.instanceAddresses.update( (const void*) instanceAddresses.data(), instanceAddresses.size() * sizeof(pod::Instance::Addresses) );
*/
uf::stl::vector<pod::InstanceAddresses> instanceAddresses = uf::graph::storage.instanceAddresses.flatten();
uf::graph::storage.buffers.instanceAddresses.update( (const void*) instanceAddresses.data(), instanceAddresses.size() * sizeof(pod::InstanceAddresses) );
uf::stl::vector<pod::Instance::Addresses> instanceAddresses = uf::graph::storage.instanceAddresses.flatten();
uf::graph::storage.buffers.instanceAddresses.update( (const void*) instanceAddresses.data(), instanceAddresses.size() * sizeof(pod::Instance::Addresses) );
uf::stl::vector<pod::Matrix4f> joints; joints.reserve(uf::graph::storage.joints.map.size());
for ( auto& key : uf::graph::storage.joints.keys ) {

View File

@ -0,0 +1,32 @@
#if UF_USE_IMGUI
#include <uf/ext/imgui/imgui.h>
#include <uf/utils/math/vector.h>
#include <imgui/imgui.h>
void ext::imgui::initialize() {
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
uint8_t* tex_pixels{};
pod::Vector2i tex_size{};
io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_size.x, &tex_size.y);
for ( size_t frame = 0; frame < 32; ++frame ) {
io.DisplaySize = ImVec2(800,600);
io.DeltaTime = 1.0f / 60.0f;
ImGui::NewFrame();
ImGui::ShowDemoWindow(NULL);
ImGui::Render();
}
}
void ext::imgui::tick() {
}
void ext::imgui::render() {
}
void ext::imgui::terminate() {
ImGui::DestroyContext();
}
#endif

View File

@ -905,7 +905,9 @@ void ext::vulkan::Device::initialize() {
VkPhysicalDeviceRobustness2FeaturesEXT robustnessFeatures{};
VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddresFeatures{};
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rayTracingPipelineFeatures{};
VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures{};
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructureFeatures{};
VkPhysicalDeviceShaderClockFeaturesKHR shaderClockFeatures{};
{
physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
@ -934,11 +936,20 @@ void ext::vulkan::Device::initialize() {
rayTracingPipelineFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR;
rayTracingPipelineFeatures.rayTracingPipeline = VK_TRUE;
}
{
rayQueryFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR;
rayQueryFeatures.rayQuery = VK_TRUE;
}
{
accelerationStructureFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
accelerationStructureFeatures.accelerationStructure = VK_TRUE;
// accelerationStructureFeatures.accelerationStructureHostCommands = VK_TRUE;
}
{
shaderClockFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR;
shaderClockFeatures.shaderSubgroupClock = VK_TRUE;
shaderClockFeatures.shaderDeviceClock = VK_TRUE;
}
deviceCreateInfo.pNext = &physicalDeviceFeatures2;
physicalDeviceFeatures2.pNext = &descriptorIndexingFeatures;
@ -946,7 +957,9 @@ void ext::vulkan::Device::initialize() {
shaderDrawParametersFeatures.pNext = &robustnessFeatures;
robustnessFeatures.pNext = &bufferDeviceAddresFeatures;
bufferDeviceAddresFeatures.pNext = &rayTracingPipelineFeatures;
rayTracingPipelineFeatures.pNext = &accelerationStructureFeatures;
rayTracingPipelineFeatures.pNext = &rayQueryFeatures;
rayQueryFeatures.pNext = &accelerationStructureFeatures;
accelerationStructureFeatures.pNext = &shaderClockFeatures;
if ( settings::experimental::enableMultiGPU ) {
UF_MSG_DEBUG("Multiple devices supported, using " << groupDeviceCreateInfo.physicalDeviceCount << " devices...");

View File

@ -459,7 +459,8 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip
uf::stl::vector<VkDescriptorBufferInfo> uniform;
uf::stl::vector<VkDescriptorBufferInfo> storage;
uf::stl::vector<VkDescriptorBufferInfo> accelerationStructure;
uf::stl::vector<VkWriteDescriptorSetAccelerationStructureKHR> accelerationStructureInfos;
uf::stl::vector<VkDescriptorImageInfo> image;
uf::stl::vector<VkDescriptorImageInfo> image2D;
uf::stl::vector<VkDescriptorImageInfo> image2DA;
@ -480,25 +481,25 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip
for ( auto& buffer : renderMode.buffers ) {
if ( buffer.usage & uf::renderer::enums::Buffer::UNIFORM ) infos.uniform.emplace_back(buffer.descriptor);
if ( buffer.usage & uf::renderer::enums::Buffer::STORAGE ) infos.storage.emplace_back(buffer.descriptor);
if ( buffer.usage & uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE ) infos.accelerationStructure.emplace_back(buffer.descriptor);
// if ( buffer.usage & uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE ) infos.accelerationStructure.emplace_back(buffer.descriptor);
}
// add per-shader buffers
for ( auto& buffer : shader->buffers ) {
if ( buffer.usage & uf::renderer::enums::Buffer::UNIFORM ) infos.uniform.emplace_back(buffer.descriptor);
if ( buffer.usage & uf::renderer::enums::Buffer::STORAGE ) infos.storage.emplace_back(buffer.descriptor);
if ( buffer.usage & uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE ) infos.accelerationStructure.emplace_back(buffer.descriptor);
// if ( buffer.usage & uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE ) infos.accelerationStructure.emplace_back(buffer.descriptor);
}
// add per-pipeline buffers
for ( auto& buffer : this->buffers ) {
if ( buffer.usage & uf::renderer::enums::Buffer::UNIFORM ) infos.uniform.emplace_back(buffer.descriptor);
if ( buffer.usage & uf::renderer::enums::Buffer::STORAGE ) infos.storage.emplace_back(buffer.descriptor);
if ( buffer.usage & uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE ) infos.accelerationStructure.emplace_back(buffer.descriptor);
// if ( buffer.usage & uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE ) infos.accelerationStructure.emplace_back(buffer.descriptor);
}
// add per-graphics buffers
for ( auto& buffer : graphic.buffers ) {
if ( buffer.usage & uf::renderer::enums::Buffer::UNIFORM ) infos.uniform.emplace_back(buffer.descriptor);
if ( buffer.usage & uf::renderer::enums::Buffer::STORAGE ) infos.storage.emplace_back(buffer.descriptor);
if ( buffer.usage & uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE ) infos.accelerationStructure.emplace_back(buffer.descriptor);
// if ( buffer.usage & uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE ) infos.accelerationStructure.emplace_back(buffer.descriptor);
}
if ( descriptor.subpass < renderTarget.passes.size() ) {
@ -545,13 +546,7 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip
descriptorAccelerationStructureInfo.accelerationStructureCount = 1;
descriptorAccelerationStructureInfo.pAccelerationStructures = &graphic.accelerationStructures.top.handle;
}
*/
VkWriteDescriptorSetAccelerationStructureKHR descriptorAccelerationStructureInfo{};
descriptorAccelerationStructureInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
descriptorAccelerationStructureInfo.accelerationStructureCount = 1;
descriptorAccelerationStructureInfo.pAccelerationStructures = &graphic.accelerationStructures.top.handle;
*/
// check if we can even consume that many infos
size_t consumes = 0;
@ -595,10 +590,19 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip
else if ( type == ext::vulkan::enums::Image::VIEW_TYPE_2D ) infos.image.emplace_back(Texture2D::empty.descriptor);
else infos.image.emplace_back(Texture2D::empty.descriptor);
}
infos.accelerationStructure.emplace_back(graphic.accelerationStructures.top.buffer.descriptor);
for ( auto& info : infos.accelerationStructure ) {
auto& descriptorAccelerationStructureInfo = infos.accelerationStructureInfos.emplace_back();
descriptorAccelerationStructureInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
descriptorAccelerationStructureInfo.accelerationStructureCount = 1;
descriptorAccelerationStructureInfo.pAccelerationStructures = &graphic.accelerationStructures.top.handle;
}
auto uniformBufferInfo = infos.uniform.begin();
auto storageBufferInfo = infos.storage.begin();
auto accelerationStructureInfo = infos.accelerationStructure.begin();
auto accelerationStructureInfos = infos.accelerationStructureInfos.begin();
auto imageInfo = infos.image.begin();
auto image2DInfo = infos.image2D.begin();
@ -722,9 +726,10 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip
&(*accelerationStructureInfo),
layout.descriptorCount
));
writeDescriptorSet.pNext = &descriptorAccelerationStructureInfo;
writeDescriptorSet.pNext = &(*accelerationStructureInfos);
accelerationStructureInfo += layout.descriptorCount;
accelerationStructureInfos += layout.descriptorCount;
} break;
}
}
@ -1289,11 +1294,14 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
UF_MSG_DEBUG("Scratch buffer size: " << maxScratchBufferSize);
for ( auto& blasData : blasDatas ) {
blasData.as.buffer = this->buffers[blasBufferIndex].alias();
blasData.as.buffer.descriptor.offset = blasBufferOffset;
VkAccelerationStructureCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR};
createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
createInfo.size = blasData.sizeInfo.accelerationStructureSize;
createInfo.buffer = this->buffers[blasBufferIndex].buffer;
createInfo.offset = blasBufferOffset;
createInfo.buffer = blasData.as.buffer.buffer;
createInfo.offset = blasData.as.buffer.descriptor.offset;
blasBufferOffset += blasData.sizeInfo.accelerationStructureSize;
@ -1422,12 +1430,13 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
}
rebuild = rebuild || this->updateBuffer( NULL, sizeInfo.accelerationStructureSize, tlasBufferIndex );
}
tlas.buffer = this->buffers[tlasBufferIndex].alias();
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;
createInfo.buffer = tlas.buffer.buffer;
VK_CHECK_RESULT(uf::renderer::vkCreateAccelerationStructureKHR(device, &createInfo, nullptr, &tlas.handle));
@ -1482,15 +1491,6 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
}
{
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;
//
shader.buffers.emplace_back( this->buffers[tlasBufferIndex].alias() );
}
}

View File

@ -247,6 +247,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
{ uf::renderer::settings::pipelines::vxgi, "vxgi.frag" },
{ msaa > 1, "msaa.frag" },
{ uf::renderer::settings::invariant::deferredSampling, "deferredSampling.frag" },
{ uf::renderer::settings::pipelines::rt, "rt.frag" },
};
FOR_ARRAY( settings ) if ( settings[i].first ) fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", settings[i].second );
}
@ -285,11 +286,12 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
// 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.drawCommands.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.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() );
if ( ext::vulkan::settings::pipelines::vxgi ) {
uint32_t* specializationConstants = (uint32_t*) (void*) shader.specializationConstants;

View File

@ -324,11 +324,12 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
auto& shader = blitter.material.getShader("compute");
// 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.drawCommands.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instanceAddresses.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 ) {

View File

@ -15,7 +15,7 @@
#include "../light/behavior.h"
#include "../scene/behavior.h"
#define UF_BAKER_SAVE_MULTITHREAD 1
#define UF_BAKER_SAVE_MULTITHREAD 0
UF_BEHAVIOR_REGISTER_CPP(ext::BakingBehavior)
UF_BEHAVIOR_TRAITS_CPP(ext::BakingBehavior, ticks = true, renders = false, multithread = false)
@ -98,7 +98,6 @@ void ext::BakingBehavior::initialize( uf::Object& self ) {
#endif
}
void ext::BakingBehavior::tick( uf::Object& self ) {
#if 1
#if UF_USE_VULKAN
if ( !this->hasComponent<uf::renderer::RenderTargetRenderMode>() ) return;
auto& metadata = this->getComponent<ext::BakingBehavior::Metadata>();
@ -122,7 +121,6 @@ PREPARE: {
return;
}
SAVE: {
#if 1
renderMode.execute = false;
UF_MSG_DEBUG("Baking...");
@ -163,11 +161,9 @@ SAVE: {
payload["message"] = "Termination after lightmap baking requested.";
uf::scene::getCurrentScene().queueHook("system:Quit", payload);
}
#endif
return;
}
#endif
#endif
}
void ext::BakingBehavior::render( uf::Object& self ){}
void ext::BakingBehavior::destroy( uf::Object& self ){

View File

@ -16,6 +16,8 @@
#include <sstream>
#include "../scene/behavior.h"
UF_BEHAVIOR_REGISTER_CPP(ext::PlayerBehavior)
UF_BEHAVIOR_TRAITS_CPP(ext::PlayerBehavior, ticks = true, renders = false, multithread = false)
#define this (&self)
@ -79,39 +81,14 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
// Rotate Camera
this->addHook( "window:Mouse.Moved", [&](pod::payloads::windowMouseMoved& payload ){
const pod::Vector2ui deadZone{6, 6};
const pod::Vector2ui deadZone{0, 0};
if ( (payload.mouse.delta.x == 0 && payload.mouse.delta.y == 0) || !metadata.system.control ) return;
pod::Vector2f delta = {
(float) metadata.mouse.sensitivity.x * (abs(payload.mouse.delta.x) < deadZone.x ? 0 : payload.mouse.delta.x) / payload.window.size.x,
(float) metadata.mouse.sensitivity.y * (abs(payload.mouse.delta.y) < deadZone.y ? 0 : payload.mouse.delta.y) / payload.window.size.y
};
// pod::Vector2f delta = metadata.mouse.sensitivity * payload.mouse.delta / payload.window.size;
if ( (payload.mouse.delta.x == 0 && payload.mouse.delta.y == 0) || !metadata.system.control ) return;
metadata.camera.queued += delta;
// UF_MSG_DEBUG( "Window size: " << uf::vector::toString( payload.window.size ));
// UF_MSG_DEBUG( "Delta: " << uf::vector::toString( payload.mouse.delta ));
// UF_MSG_DEBUG( "Sensitivity: " << uf::vector::toString( metadata.mouse.sensitivity ) );
/*
if ( relta.x != 0 ) {
if ( metadata.camera.invert.x ) relta.x *= -1;
metadata.camera.limit.current.x += relta.x;
if ( metadata.camera.limit.current.x != metadata.camera.limit.current.x || ( metadata.camera.limit.current.x < metadata.camera.limit.max.x && metadata.camera.limit.current.x > metadata.camera.limit.min.x ) ) {
if ( collider.body ) uf::physics::impl::applyRotation( collider, transform.up, relta.x ); else
uf::transform::rotate( transform, transform.up, relta.x );
} else metadata.camera.limit.current.x -= relta.x;
}
if ( relta.y != 0 ) {
if ( metadata.camera.invert.y ) relta.y *= -1;
metadata.camera.limit.current.y += relta.y;
if ( metadata.camera.limit.current.y != metadata.camera.limit.current.y || ( metadata.camera.limit.current.y < metadata.camera.limit.max.y && metadata.camera.limit.current.y > metadata.camera.limit.min.y ) ) {
// if ( collider.body && !collider.shared ) uf::physics::impl::applyRotation( collider, cameraTransform.right, relta.y ); else
uf::transform::rotate( cameraTransform, cameraTransform.right, relta.y );
} else metadata.camera.limit.current.y -= relta.y;
}
camera.update(true);
*/
});
#if UF_USE_DISCORD
@ -212,6 +189,8 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
bool noclipped = false;
uf::stl::string menu = "";
uf::stl::string targetAnimation = "";
pod::Matrix4f previous;
} stats;
auto& metadata = this->getComponent<ext::PlayerBehavior::Metadata>();

View File

@ -20,6 +20,8 @@ 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 ) {
auto& metadata = this->getComponent<ext::RayTraceSceneBehavior::Metadata>();
if ( !uf::renderer::hasRenderMode("Compute", true) ) {
auto* renderMode = new uf::renderer::RenderTargetRenderMode;
renderMode->setTarget("Compute");
@ -31,28 +33,70 @@ void ext::RayTraceSceneBehavior::initialize( uf::Object& self ) {
renderMode->execute = false;
uf::renderer::addRenderMode( renderMode, "Compute" );
}
if ( ext::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].is<float>() ) {
metadata.renderer.scale = ext::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].as(metadata.renderer.scale);
}
}
void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
auto& metadata = this->getComponent<ext::RayTraceSceneBehavior::Metadata>();
auto instances = uf::graph::storage.instances.flatten();
static uf::stl::vector<pod::Instance> previousInstances;
uf::stl::vector<pod::Instance> instances = uf::graph::storage.instances.flatten();
if ( instances.empty() ) return;
static uf::stl::vector<uf::Graphic*> previousGraphics;
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 = entity->getComponent<uf::Graphic>();
if ( graphic.accelerationStructures.bottoms.empty() ) return;
graphics.emplace_back(&graphic);
});
if ( graphics.empty() ) return;
auto& graphic = this->getComponent<uf::renderer::Graphic>();
if ( !metadata.renderer.bound ) graphic.initialize("Compute");
graphic.generateTopAccelerationStructure( graphics, instances );
bool update = false;
auto& graphic = this->getComponent<uf::renderer::Graphic>();
if ( !metadata.renderer.bound ) {
graphic.initialize("Compute");
update = true;
} else {
if ( previousInstances.size() != instances.size() ) update = true;
else if ( previousGraphics.size() != graphics.size() ) update = true;
// else if ( memcmp( previousInstances.data(), instances.data(), instances.size() * sizeof(decltype(instances)::value_type) ) != 0 ) update = true;
else if ( memcmp( previousGraphics.data(), graphics.data(), graphics.size() * sizeof(decltype(graphics)::value_type) ) != 0 ) update = true;
else for ( size_t i = 0; i < instances.size() && !update; ++i ) {
if ( !uf::matrix::equals( instances[i].model, previousInstances[i].model, 0.0001f ) )
update = true;
}
}
if ( update ) {
graphic.generateTopAccelerationStructure( graphics, instances );
auto& sceneMetadata = this->getComponent<ext::ExtSceneBehavior::Metadata>();
sceneMetadata.shader.frameAccumulateReset = true;
previousInstances = instances;
previousGraphics = graphics;
}
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& image = shader.textures.emplace_back();
image.fromBuffers(
NULL, 0,
uf::renderer::enums::Format::R8G8B8A8_UNORM,
uf::renderer::settings::width * metadata.renderer.scale, uf::renderer::settings::height * metadata.renderer.scale, 1, 1,
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL
);
graphic.descriptor.pipeline = uf::renderer::settings::pipelines::names::rt;
graphic.descriptor.inputs.width = image.width;
graphic.descriptor.inputs.height = image.height;
//
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);
@ -112,7 +156,11 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
if ( blitter.material.hasShader("fragment") ) {
auto& shader = blitter.material.getShader("fragment");
if ( shader.textures.empty() ) {
shader.textures.emplace_back().aliasTexture( image );
auto& tex = shader.textures.emplace_back();
tex.aliasTexture( image );
tex.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
tex.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
renderMode.execute = true;
graphic.process = true;
}
@ -120,7 +168,12 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
if ( uf::renderer::states::resized ) {
image.destroy();
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 );
image.fromBuffers(
NULL, 0,
uf::renderer::enums::Format::R8G8B8A8_UNORM,
uf::renderer::settings::width * metadata.renderer.scale, uf::renderer::settings::height * metadata.renderer.scale, 1, 1,
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL
);
graphic.descriptor.inputs.width = image.width;
graphic.descriptor.inputs.height = image.height;

View File

@ -16,6 +16,7 @@ namespace ext {
UF_BEHAVIOR_DEFINE_METADATA(
struct {
bool bound = false;
float scale = 1;
} renderer;
);
}

View File

@ -210,6 +210,15 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
#if 1
uf::hooks.call("game:Frame.Start");
++metadata.shader.frameAccumulate;
if ( !metadata.shader.frameAccumulateReset && metadata.shader.frameAccumulateLimit && metadata.shader.frameAccumulate > metadata.shader.frameAccumulateLimit ) {
metadata.shader.frameAccumulateReset = true;
}
if ( metadata.shader.frameAccumulateReset ) {
metadata.shader.frameAccumulate = 0;
metadata.shader.frameAccumulateReset = false;
}
/* Print World Tree */ {
TIMER(1, uf::inputs::kbm::states::U && ) {
std::function<void(uf::Entity*, int)> filter = []( uf::Entity* entity, int indent ) {
@ -640,6 +649,7 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali
/*this->*/shader.mode = serializer["system"]["renderer"]["shader"]["mode"].as<uint32_t>();
/*this->*/shader.scalar = serializer["system"]["renderer"]["shader"]["scalar"].as<uint32_t>();
/*this->*/shader.parameters = uf::vector::decode( serializer["system"]["renderer"]["shader"]["parameters"], pod::Vector4f{0,0,0,0} );
/*this->*/shader.frameAccumulateLimit = serializer["system"]["renderer"]["shader"]["frame accumulate limit"].as<uint32_t>(0);
ext::json::forEach( serializer["system"]["renderer"]["shader"]["parameters"], [&]( uint32_t i, const ext::json::Value& value ){
if ( value.as<uf::stl::string>() == "time" ) /*this->*/shader.time = i;
});
@ -779,7 +789,7 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
alignas(4) uint32_t indexSkybox;
alignas(4) uint32_t useLightmaps;
alignas(4) uint32_t padding2;
alignas(4) uint32_t frameAccumulate;
alignas(4) uint32_t padding3;
};
@ -883,9 +893,9 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
uniforms.indexSkybox = indexSkybox;
// use sample lightmaps during deferred pass
uniforms.useLightmaps = metadata.light.useLightmaps;
uniforms.frameAccumulate = metadata.shader.frameAccumulate;
}
uf::stl::vector<VkImage> previousTextures;
for ( auto& texture : graphic.material.textures ) previousTextures.emplace_back(texture.image);
graphic.material.textures.clear();
@ -900,10 +910,20 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
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();
if ( shouldUpdate ) {
graphic.updatePipelines();
metadata.shader.invalidated = false;
}
auto& shader = graphic.material.getShader(shaderType, shaderPipeline);
shader.updateBuffer( (const void*) &uniforms, sizeof(uniforms), shader.getUniformBuffer("UBO") );
static UniformDescriptor previousUniforms;
bool shouldUpdate2 = !uf::matrix::equals( uniforms.matrices[0].view, previousUniforms.matrices[0].view, 0.0001f );
if ( shouldUpdate || shouldUpdate2 ) {
metadata.shader.frameAccumulateReset = true;
previousUniforms = uniforms;
}
#endif
}
#undef this

View File

@ -46,7 +46,12 @@ namespace ext {
uint32_t scalar;
pod::Vector4f parameters = {0,0,0,0};
int8_t time = 3;
bool invalidated = true;
uint32_t frameAccumulate = 0;
uint32_t frameAccumulateLimit = 0;
bool frameAccumulateReset = false;
} shader;
struct {
pod::Vector3f color = {1,1,1};

View File

@ -45,6 +45,7 @@
#include <uf/ext/openvr/openvr.h>
#include <uf/ext/lua/lua.h>
#include <uf/ext/ultralight/ultralight.h>
#include <uf/ext/imgui/imgui.h>
bool ext::ready = false;
uf::stl::vector<uf::stl::string> ext::arguments;
@ -587,6 +588,11 @@ void EXT_API ext::initialize() {
ext::ultralight::log = ::json["engine"]["ext"]["ultralight"]["log"].as( ext::ultralight::log );
ext::ultralight::initialize();
}
#endif
#if UF_USE_IMGUI
{
ext::imgui::initialize();
}
#endif
/* Add hooks */ {
uf::hooks.addHook( "game:Scene.Load", [&](ext::json::Value& json){
@ -715,6 +721,11 @@ void EXT_API ext::tick() {
/* Discord */ if ( ::config.engine.ext.discord.enabled ) {
ext::discord::tick();
}
#endif
#if UF_USE_IMGUI
{
ext::imgui::tick();
}
#endif
/* FPS Print */ if ( ::config.engine.fps.print ) {
++::times.frames;
@ -789,6 +800,11 @@ void EXT_API ext::terminate() {
/* Kill physics */ {
uf::physics::terminate();
}
#if UF_USE_IMGUI
{
ext::imgui::terminate();
}
#endif
#if UF_USE_ULTRALIGHT
/* Ultralight-UX */ if ( ::config.engine.ext.ultralight.enabled ) {
ext::ultralight::terminate();