Commit for 2022.06.28 23-53-39.7z
This commit is contained in:
parent
813907f0a3
commit
c536d24e63
7
Makefile
7
Makefile
@ -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 +=
|
||||
|
@ -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"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
39
bin/data/entities/cornell.json
Normal file
39
bin/data/entities/cornell.json
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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 },
|
||||
|
@ -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] } } },
|
||||
|
@ -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,
|
||||
|
@ -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 },
|
@ -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 ] } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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": {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
13
bin/data/shaders/display/subpass.msaa.rt.frag.glsl
Normal file
13
bin/data/shaders/display/subpass.msaa.rt.frag.glsl
Normal 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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
13
bin/data/shaders/display/subpass.vxgi.msaa.rt.frag.glsl
Normal file
13
bin/data/shaders/display/subpass.vxgi.msaa.rt.frag.glsl
Normal 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();
|
||||
}
|
15
bin/data/shaders/display/subpass.vxgi.rt.frag.glsl
Normal file
15
bin/data/shaders/display/subpass.vxgi.rt.frag.glsl
Normal 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();
|
||||
}
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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 ) ) {
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
*/
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
16
engine/inc/uf/ext/imgui/imgui.h
Normal file
16
engine/inc/uf/ext/imgui/imgui.h
Normal 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
|
@ -78,6 +78,8 @@ namespace ext {
|
||||
struct AccelerationStructure {
|
||||
VkAccelerationStructureKHR handle{VK_NULL_HANDLE};
|
||||
size_t deviceAddress{};
|
||||
Buffer buffer{};
|
||||
|
||||
size_t instanceID{};
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 ) {
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 ) {
|
||||
|
32
engine/src/ext/imgui/imgui.cpp
Normal file
32
engine/src/ext/imgui/imgui.cpp
Normal 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
|
@ -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...");
|
||||
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 ) {
|
||||
|
@ -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 ){
|
||||
|
@ -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>();
|
||||
|
@ -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;
|
||||
|
@ -16,6 +16,7 @@ namespace ext {
|
||||
UF_BEHAVIOR_DEFINE_METADATA(
|
||||
struct {
|
||||
bool bound = false;
|
||||
float scale = 1;
|
||||
} renderer;
|
||||
);
|
||||
}
|
||||
|
@ -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
|
@ -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};
|
||||
|
16
ext/main.cpp
16
ext/main.cpp
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user