Commit for 2022.12.21 16-25-26.7z
This commit is contained in:
parent
e816814186
commit
de54bcad8f
2
Makefile
2
Makefile
@ -49,6 +49,7 @@ VULKAN_SDK_PATH += /c/VulkanSDK/1.3.224.1/
|
||||
|
||||
GLSLC += $(VULKAN_SDK_PATH)/Bin/glslc
|
||||
SPV_OPTIMIZER += $(VULKAN_SDK_PATH)/Bin/spirv-opt
|
||||
SPV_LINTER += $(VULKAN_SDK_PATH)/Bin/spirv-lint
|
||||
# Base Engine's DLL
|
||||
INC_DIR += $(ENGINE_INC_DIR)
|
||||
LIB_DIR += $(ENGINE_LIB_DIR)
|
||||
@ -343,6 +344,7 @@ endif
|
||||
|
||||
%.spv: %.glsl
|
||||
$(GLSLC) --target-env=vulkan1.2 -o $@ $<
|
||||
$(SPV_LINTER) $@
|
||||
$(SPV_OPTIMIZER) --preserve-bindings --preserve-spec-constants -O $@ -o $@
|
||||
|
||||
shaders: $(TARGET_SHADERS)
|
||||
|
||||
383
belly/bin/data/config.json
Normal file
383
belly/bin/data/config.json
Normal file
@ -0,0 +1,383 @@
|
||||
{
|
||||
"engine": {
|
||||
"scenes": {
|
||||
"start": "SourceEngine",
|
||||
"matrix": { "reverseInfinite": true },
|
||||
"meshes": { "interleaved": false },
|
||||
"lights": { "enabled": true,
|
||||
"useLightmaps": false,
|
||||
"max": 16,
|
||||
"shadows": {
|
||||
"enabled": true,
|
||||
"update": 2,
|
||||
"max": 4,
|
||||
"samples": 1
|
||||
},
|
||||
"bloom": {
|
||||
"scale": 1.0,
|
||||
"strength": 0.125,
|
||||
"sigma": 0.8,
|
||||
"samples": 5,
|
||||
"threshold": 1.0
|
||||
}
|
||||
},
|
||||
"textures": {
|
||||
"max": {
|
||||
"2D": 1024,
|
||||
"cube": 1024,
|
||||
"3D": 128
|
||||
}
|
||||
},
|
||||
"vxgi": {
|
||||
"limiter": 0.5,
|
||||
// "limiter": 0.125,
|
||||
"size": 192,
|
||||
"dispatch": 8,
|
||||
"cascades": 3,
|
||||
"cascadePower": 1.5,
|
||||
"granularity": 12,
|
||||
"voxelizeScale": 1,
|
||||
"occlusionFalloff": 2,
|
||||
"traceStartOffsetFactor": 1,
|
||||
"shadows": 0,
|
||||
"extents": {
|
||||
"min": [ -16, -4, -16 ],
|
||||
"max": [ 16, 4, 16 ]
|
||||
}
|
||||
},
|
||||
"rt": {
|
||||
// "size": [ 1280, 720 ],
|
||||
"full": false,
|
||||
"filter": "nearest",
|
||||
"defaultRayBounds": [ 0.5, 256.0 ],
|
||||
"alphaTestOffset": 0.01,
|
||||
"samples": 1,
|
||||
"paths": 2,
|
||||
"frameAccumulationMinimum": 0
|
||||
}
|
||||
},
|
||||
"graph": {
|
||||
"initial buffer elements": 131072
|
||||
},
|
||||
"ext": {
|
||||
"vulkan": {
|
||||
"version": 1.3,
|
||||
"validation": { "enabled": true,
|
||||
"filters": [
|
||||
// "0x4dae5635" // UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout
|
||||
|
||||
"0x609a13b" // UNASSIGNED-CoreValidation-Shader-OutputNotConsumed (from depth-only calls)
|
||||
,"0x141cb623" // UNASSIGNED-Threading-MultipleThreads ("false-positive" multithreading)
|
||||
,"0xe5d1743c" // VUID-vkCmdDispatch-None-02699 (problem when using VXGI)
|
||||
,"0x71500fba" // VUID-vkDestroyDevice-device-00378 (don't care about a clean cleanup)
|
||||
,"0x35d7ea98" // VUID-vkUpdateDescriptorSets-None-03047 (bitches without VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT or VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT)
|
||||
,"0x8e1000ad" // VUID-vkCmdDrawIndexedIndirect-None-04008 (bitches without nullDescriptor)
|
||||
,"0x9dd97212" // VUID-vkCmdDrawIndexedIndirect-None-02721 (bitches without nullDescriptor)
|
||||
,"0x36481fcb" // VUID-vkCmdBindVertexBuffers-pBuffers-04001 (bitches without nullDescriptor)
|
||||
]
|
||||
},
|
||||
"framebuffer": {
|
||||
"msaa": 1,
|
||||
"size": 1
|
||||
// "size": [ 640, 480, "NEAREST" ]
|
||||
// "size": [ 1280, 720 ]
|
||||
// "size": [ 960, 540 ]
|
||||
// "size": [ 640, 480 ]
|
||||
},
|
||||
"gpu": 1,
|
||||
"experimental": {
|
||||
"rebuild on tick begin": false,
|
||||
"batch queue submissions": true,
|
||||
"dedicated thread": false,
|
||||
"memory budget": false
|
||||
},
|
||||
"invariant": {
|
||||
"default stage buffers": true
|
||||
},
|
||||
"pipelines": {
|
||||
"deferred": true,
|
||||
"vsync": true,
|
||||
"hdr": false,
|
||||
"vxgi": false,
|
||||
"culling": false,
|
||||
"bloom": false,
|
||||
"rt": false,
|
||||
"postProcess": false,
|
||||
"fsr": false
|
||||
},
|
||||
"formats": {
|
||||
"depth": "D32_SFLOAT",
|
||||
"color": "R16G16B16A16_SFLOAT", // "R32G32B32A32_SFLOAT",
|
||||
"normal": "R16G16B16A16_SFLOAT",
|
||||
"position": "R16G16B16A16_SFLOAT"
|
||||
},
|
||||
"versions": {
|
||||
"1.0": {
|
||||
"extensions": {
|
||||
"instance": [],
|
||||
"device": [
|
||||
"VK_KHR_swapchain"
|
||||
]
|
||||
},
|
||||
"features": [
|
||||
"shaderDrawParameters",
|
||||
"multiDrawIndirect",
|
||||
"fillModeNonSolid",
|
||||
"wideLines",
|
||||
"independentBlend",
|
||||
"deviceCoherentMemory",
|
||||
"robustBufferAccess",
|
||||
"samplerAnisotropy",
|
||||
"sampleRateShading"
|
||||
],
|
||||
"featureChain": []
|
||||
},
|
||||
"1.1": {
|
||||
"extensions": {
|
||||
"instance": [
|
||||
"VK_KHR_get_physical_device_properties2"
|
||||
,"VK_KHR_get_surface_capabilities2"
|
||||
],
|
||||
"device": [
|
||||
"VK_EXT_memory_budget"
|
||||
,"VK_EXT_descriptor_indexing"
|
||||
,"VK_KHR_buffer_device_address"
|
||||
]
|
||||
},
|
||||
"features": [
|
||||
"nullDescriptor"
|
||||
,"fragmentStoresAndAtomics"
|
||||
,"geometryShader"
|
||||
,"multiViewport"
|
||||
,"shaderInt16"
|
||||
,"shaderFloat16"
|
||||
,"shaderInt64"
|
||||
,"shaderFloat64"
|
||||
,"shaderSubgroupClock"
|
||||
,"shaderSampledImageArrayDynamicIndexing"
|
||||
,"shaderStorageImageArrayDynamicIndexing"
|
||||
,"shaderStorageImageMultisample"
|
||||
|
||||
,"shaderSampledImageArrayNonUniformIndexing"
|
||||
,"shaderStorageImageArrayNonUniformIndexing"
|
||||
|
||||
,"descriptorIndexing"
|
||||
,"bufferDeviceAddress"
|
||||
],
|
||||
"featureChain": [
|
||||
"physicalDevice2"
|
||||
,"shaderDrawParameters"
|
||||
,"robustness"
|
||||
,"shaderClock"
|
||||
|
||||
,"descriptorIndexing"
|
||||
,"bufferDeviceAddress"
|
||||
]
|
||||
},
|
||||
"1.2": {
|
||||
"extensions": {
|
||||
"instance": [
|
||||
"VK_KHR_get_physical_device_properties2",
|
||||
"VK_KHR_get_surface_capabilities2"
|
||||
],
|
||||
"device": [
|
||||
"VK_KHR_deferred_host_operations"
|
||||
,"VK_EXT_shader_viewport_index_layer"
|
||||
,"VK_KHR_spirv_1_4"
|
||||
,"VK_KHR_shader_float_controls"
|
||||
,"VK_KHR_shader_clock"
|
||||
,"VK_EXT_subgroup_size_control"
|
||||
,"VK_KHR_acceleration_structure"
|
||||
,"VK_KHR_ray_tracing_pipeline"
|
||||
,"VK_KHR_ray_query"
|
||||
|
||||
// ,"VK_AMD_shader_explicit_vertex_parameter"
|
||||
// ,"VK_KHR_fragment_shader_barycentric"
|
||||
]
|
||||
},
|
||||
"features": [
|
||||
"hostQueryReset",
|
||||
|
||||
"runtimeDescriptorArray",
|
||||
"descriptorBindingVariableDescriptorCount",
|
||||
|
||||
"shaderOutputViewportIndex",
|
||||
"shaderOutputLayer"
|
||||
],
|
||||
"featureChain": [
|
||||
"physicalDeviceVulkan12"
|
||||
// for ray-tracing
|
||||
,"fragmentShaderBarycentric"
|
||||
,"rayTracingPipeline"
|
||||
,"rayQuery"
|
||||
,"accelerationStructure"
|
||||
,"subgroupSizeControl"
|
||||
]
|
||||
},
|
||||
"1.3": {
|
||||
"extensions": {
|
||||
"instance": [],
|
||||
"device": []
|
||||
},
|
||||
"features": [],
|
||||
"featureChain": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"opengl": {
|
||||
"validation": { "enabled": false },
|
||||
"framebuffer": { "size": 1, "msaa": 1 },
|
||||
"experimental": {
|
||||
"rebuild on tick begin": true
|
||||
},
|
||||
"pipelines": {
|
||||
"culling": true
|
||||
},
|
||||
"experimental": {
|
||||
"rebuild on tick begin": true
|
||||
},
|
||||
"invariant": {
|
||||
"multithreaded recording": false
|
||||
},
|
||||
"formats": {
|
||||
"depth": "D32_SFLOAT",
|
||||
"color": "R8G8B8A8_UNORM", // "R32G32B32A32_SFLOAT",
|
||||
"normal": "R16G16B16A16_SFLOAT",
|
||||
"position": "R16G16B16A16_SFLOAT"
|
||||
},
|
||||
"features": [],
|
||||
"extensions": { "instance": [], "device": [] }
|
||||
},
|
||||
"lua": {
|
||||
"enabled": true,
|
||||
"main": "/main.lua",
|
||||
"modules": {
|
||||
"json": "/json.lua"
|
||||
}
|
||||
},
|
||||
"json": {
|
||||
"encoding": "msgpack",
|
||||
"compression": "gz"
|
||||
},
|
||||
"imgui": {
|
||||
"enabled": false
|
||||
},
|
||||
"fsr": {
|
||||
"enabled": true,
|
||||
"sharpness": 1,
|
||||
"jitter scale": 0.0625,
|
||||
"preset": "ultra" // native (1x), quality (1.5x), balanced (1.7x), performance (2.0x), ultra (3.0x)
|
||||
},
|
||||
"reactphysics": {
|
||||
"timescale": 0.01666666666,
|
||||
"interpolate": true,
|
||||
"gravity": {
|
||||
"mode": "universal",
|
||||
"constant": 6.67408e-11
|
||||
},
|
||||
"debug draw": {
|
||||
"enabled": false,
|
||||
"line width": 8,
|
||||
// "layer": "Gui",
|
||||
"rate": 0.0125
|
||||
}
|
||||
},
|
||||
"vr" : {
|
||||
"enable" : false,
|
||||
"manifest": "./data/openvr_manifest.json",
|
||||
"swap eyes": false,
|
||||
"dominant eye": 0,
|
||||
"scale": 1.0
|
||||
},
|
||||
"ultralight": { "enabled": true, "scale": 1.5 },
|
||||
"discord": { "enabled": false }
|
||||
},
|
||||
"audio": {
|
||||
"mute": false,
|
||||
"buffers": {
|
||||
"size": 32768,
|
||||
"count": 4
|
||||
},
|
||||
"volumes": {
|
||||
"sfx": 0.35,
|
||||
"bgm": 0.15,
|
||||
"voice": 1.0
|
||||
},
|
||||
"streams by default": true
|
||||
},
|
||||
"memory pool": {
|
||||
"enabled": true,
|
||||
"subPools": true,
|
||||
"alignment": 64,
|
||||
"override": false,
|
||||
"size": "512 MiB",
|
||||
"pools": {
|
||||
"entity": "128 MiB",
|
||||
"userdata": "128 MiB",
|
||||
"component": "128 MiB"
|
||||
}
|
||||
},
|
||||
"render modes": { "gui": true, "deferred": true },
|
||||
"limiters": {
|
||||
"deltaTime": 5,
|
||||
"framerate": 0 // "auto"
|
||||
},
|
||||
"threads": {
|
||||
"workers" : "auto",
|
||||
"frame limiter": 0 // "auto"
|
||||
},
|
||||
"debug": {
|
||||
"framerate": {
|
||||
"print": true,
|
||||
"every": 2
|
||||
},
|
||||
"garbage collection": {
|
||||
"enabled": true,
|
||||
"mode": 1,
|
||||
"rate": 4,
|
||||
"announce": true
|
||||
},
|
||||
"entity": {
|
||||
"delete children on destroy": false,
|
||||
"delete components on destroy": false
|
||||
},
|
||||
"userdata": {
|
||||
"auto destruct": true,
|
||||
"auto validate": false
|
||||
},
|
||||
"loader": {
|
||||
"assert": true
|
||||
},
|
||||
"hooks": {
|
||||
"defer lazy calls": true
|
||||
},
|
||||
"scene": {
|
||||
"print task calls": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"window" : {
|
||||
"terminal" : {
|
||||
"ncurses" : false,
|
||||
"visible" : true
|
||||
},
|
||||
"keyboard" : {
|
||||
"repeat" : false
|
||||
},
|
||||
"cursor" : {
|
||||
"visible" : true,
|
||||
"center" : false,
|
||||
"sensitivity": [ 0.75, 0.75 ],
|
||||
"smoothing": [ 4, 4 ]
|
||||
},
|
||||
"mode" : "windowed", // fullscreen, borderless, windowed
|
||||
"icon" : "./data/textures/icon.png",
|
||||
// "size" : [ 1920, 1080 ],
|
||||
// "size" : [ 1280, 720 ],
|
||||
"size" : [ 960, 540 ],
|
||||
// "size" : [ 640, 480 ],
|
||||
// "size" : [ 256, 224 ],
|
||||
"title" : "Grimgram",
|
||||
"visible" : true
|
||||
}
|
||||
}
|
||||
13
belly/bin/data/shaders/base/line/frag.glsl
Normal file
13
belly/bin/data/shaders/base/line/frag.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
layout (location = 0) in vec3 inPosition;
|
||||
layout (location = 1) in vec3 inColor;
|
||||
|
||||
layout (location = 0) out uvec2 outId;
|
||||
layout (location = 1) out vec2 outNormals;
|
||||
layout (location = 2) out vec4 outAlbedo;
|
||||
|
||||
void main() {
|
||||
outAlbedo = vec4(inColor, 1);
|
||||
}
|
||||
29
belly/bin/data/shaders/base/line/vert.glsl
Normal file
29
belly/bin/data/shaders/base/line/vert.glsl
Normal file
@ -0,0 +1,29 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec3 inColor;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 0) uniform Camera {
|
||||
Viewport viewport[PASSES];
|
||||
} camera;
|
||||
|
||||
layout (location = 0) out vec3 outPosition;
|
||||
layout (location = 1) out vec3 outColor;
|
||||
|
||||
void main() {
|
||||
outPosition = vec3(camera.viewport[PushConstant.pass].view * vec4(inPos.xyz, 1.0));
|
||||
outColor = inColor;
|
||||
|
||||
gl_Position = camera.viewport[PushConstant.pass].projection * camera.viewport[PushConstant.pass].view * vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
56
belly/bin/data/shaders/common/fog.h
Normal file
56
belly/bin/data/shaders/common/fog.h
Normal file
@ -0,0 +1,56 @@
|
||||
// Perlin Fog
|
||||
void fog( in Ray ray, inout vec3 i, float scale ) {
|
||||
if ( ubo.settings.fog.stepScale <= 0 || ubo.settings.fog.range.x == 0 || ubo.settings.fog.range.y == 0 ) return;
|
||||
#if FOG_RAY_MARCH
|
||||
const float range = ubo.settings.fog.range.y;
|
||||
const vec3 boundsMin = vec3(-range,-range,-range) + ray.origin;
|
||||
const vec3 boundsMax = vec3(range,range,range) + ray.origin;
|
||||
const int numSteps = int(length(boundsMax - boundsMin) * ubo.settings.fog.stepScale );
|
||||
|
||||
const vec2 rayBoxInfo = rayBoxDst( boundsMin, boundsMax, ray );
|
||||
const float dstToBox = rayBoxInfo.x;
|
||||
const float dstInsideBox = rayBoxInfo.y;
|
||||
const float depth = surface.position.eye.z;
|
||||
|
||||
const float aperture = 0; // PI * 0.5;
|
||||
const float coneCoefficient = 2.0 * tan(aperture * 0.5);
|
||||
|
||||
// march
|
||||
if ( 0 <= dstInsideBox && dstToBox <= depth ) {
|
||||
float stepSize = dstInsideBox / numSteps;
|
||||
float dstLimit = min( depth - dstToBox, dstInsideBox );
|
||||
float totalDensity = 0;
|
||||
float transmittance = 1;
|
||||
float lightFactor = scale;
|
||||
float coneDiameter = coneCoefficient * ray.distance;
|
||||
float level = aperture > 0 ? log2( coneDiameter ) : 0;
|
||||
float density = 0;
|
||||
vec3 uvw;
|
||||
ray.distance = dstToBox;
|
||||
while ( ray.distance < dstLimit ) {
|
||||
ray.distance += stepSize;
|
||||
ray.position = ray.origin + ray.direction * ray.distance;
|
||||
coneDiameter = coneCoefficient * ray.distance;
|
||||
level = aperture > 0 ? log2( coneDiameter ) : 0;
|
||||
uvw = ray.position * ubo.settings.fog.densityScale * 0.001 + ubo.settings.fog.offset * 0.01;
|
||||
density = max(0, textureLod(samplerNoise, uvw, level).r - ubo.settings.fog.densityThreshold) * ubo.settings.fog.densityMultiplier;
|
||||
if ( density > 0 ) {
|
||||
density = exp(-density * stepSize * ubo.settings.fog.absorbtion);
|
||||
transmittance *= density;
|
||||
lightFactor *= density;
|
||||
if ( transmittance < 0.1 ) break;
|
||||
}
|
||||
}
|
||||
i.rgb = mix(ubo.settings.fog.color.rgb, i.rgb, transmittance );
|
||||
}
|
||||
#endif
|
||||
#if FOG_BASIC
|
||||
const vec3 color = ubo.settings.fog.color.rgb;
|
||||
const float inner = ubo.settings.fog.range.x;
|
||||
const float outer = ubo.settings.fog.range.y * scale;
|
||||
const float distance = length(-surface.position.eye);
|
||||
const float factor = clamp( (distance - inner) / (outer - inner), 0.0, 1.0 );
|
||||
|
||||
i.rgb = mix(i.rgb, color, factor);
|
||||
#endif
|
||||
}
|
||||
419
belly/bin/data/shaders/common/functions.h
Normal file
419
belly/bin/data/shaders/common/functions.h
Normal file
@ -0,0 +1,419 @@
|
||||
// Helper Functions
|
||||
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); }
|
||||
//
|
||||
float mipLevel( in vec2 dx_vtc, in vec2 dy_vtc ) {
|
||||
const float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
|
||||
return 0.5 * log2(delta_max_sqr);
|
||||
// return max(0.0, 0.5 * log2(delta_max_sqr) - 1.0);
|
||||
|
||||
// return 0.5 * log2(max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)));
|
||||
}
|
||||
float mipLevels( vec2 size ) {
|
||||
return floor(log2(max(size.x, size.y)));
|
||||
}
|
||||
float mipLevels( ivec2 size ) {
|
||||
return floor(log2(max(size.x, size.y)));
|
||||
}
|
||||
//
|
||||
void toneMap( inout vec3 color, float exposure ) {
|
||||
color.rgb = vec3(1.0) - exp(-color.rgb * exposure);
|
||||
}
|
||||
void gammaCorrect( inout vec3 color, float gamma ) {
|
||||
color.rgb = pow(color.rgb, vec3(1.0 / gamma));
|
||||
}
|
||||
void toneMap( inout vec4 color, float exposure ) { toneMap(color.rgb, exposure); }
|
||||
void gammaCorrect( inout vec4 color, float gamma ) { gammaCorrect(color.rgb, gamma); }
|
||||
//
|
||||
uint tea(uint val0, uint val1) {
|
||||
uint v0 = val0;
|
||||
uint v1 = val1;
|
||||
uint s0 = 0;
|
||||
|
||||
#pragma unroll 16
|
||||
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); }
|
||||
//
|
||||
float ndfGGX(float cosLh, float roughness) {
|
||||
const float alpha = roughness * roughness;
|
||||
const float alphaSq = alpha * alpha;
|
||||
const float denom = (cosLh * cosLh) * (alphaSq - 1.0) + 1.0;
|
||||
return alphaSq / (PI * denom * denom);
|
||||
}
|
||||
float gaSchlickG1(float cosTheta, float k) { return cosTheta / (cosTheta * (1.0 - k) + k); }
|
||||
float gaSchlickGGX(float cosLi, float cosLo, float roughness) {
|
||||
const float r = roughness + 1.0;
|
||||
const float k = (r * r) / 8.0;
|
||||
return gaSchlickG1(cosLi, k) * gaSchlickG1(cosLo, k);
|
||||
}
|
||||
vec3 fresnelSchlick(vec3 F0, float cosTheta) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); }
|
||||
//
|
||||
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;
|
||||
}
|
||||
//
|
||||
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)); }
|
||||
float wrap( float i ) { return fract(i); }
|
||||
vec2 wrap( vec2 uv ) { return vec2( wrap( uv.x ), wrap( uv.y ) ); }
|
||||
vec3 orthogonal(vec3 u){
|
||||
u = normalize(u);
|
||||
const vec3 v = vec3(0.99146, 0.11664, 0.05832); // Pick any normalized vector.
|
||||
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);
|
||||
}
|
||||
float gauss( float x, float sigma ) {
|
||||
return (1.0 / (2.0 * 3.14157 * sigma) * exp(-(x*x) / (2.0 * sigma)));
|
||||
}
|
||||
bool enabled( uint flag, uint bit ) {
|
||||
return (flag & (1 << bit)) != 0;
|
||||
}
|
||||
vec3 decodeNormals( vec2 enc ) {
|
||||
const vec2 ang = enc*2-1;
|
||||
const vec2 scth = vec2( sin(ang.x * PI), cos(ang.x * PI) );
|
||||
const vec2 scphi = vec2(sqrt(1.0 - ang.y*ang.y), ang.y);
|
||||
return normalize( vec3(scth.y*scphi.x, scth.x*scphi.x, scphi.y) );
|
||||
}
|
||||
vec2 encodeNormals( vec3 n ) {
|
||||
// float p = sqrt(n.z*8+8);
|
||||
// return n.xy/p + 0.5;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
bool validTextureIndex( int textureIndex ) {
|
||||
return 0 <= textureIndex && textureIndex < MAX_TEXTURES;
|
||||
}
|
||||
#if MAX_CUBEMAPS
|
||||
bool validCubemapIndex( int textureIndex ) {
|
||||
return 0 <= textureIndex && textureIndex < MAX_CUBEMAPS;
|
||||
}
|
||||
#endif
|
||||
#if !BLOOM && (DEFERRED || FRAGMENT || COMPUTE || RT)
|
||||
bool validTextureIndex( uint id ) {
|
||||
return 0 <= id && id < MAX_TEXTURES;
|
||||
}
|
||||
bool validTextureIndex( uint start, int offset ) {
|
||||
return 0 <= offset && start + offset < MAX_TEXTURES;
|
||||
}
|
||||
uint textureIndex( uint start, int offset ) {
|
||||
return start + offset;
|
||||
}
|
||||
vec4 sampleTexture( uint id, vec2 uv ) {
|
||||
const Texture t = textures[id];
|
||||
return texture( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ) );
|
||||
}
|
||||
vec4 sampleTexture( uint id, vec2 uv, float mip ) {
|
||||
#if QUERY_MIPMAP
|
||||
return sampleTexture( id, uv );
|
||||
#else
|
||||
const Texture t = textures[id];
|
||||
return textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
|
||||
#endif
|
||||
}
|
||||
vec4 sampleTexture( uint id, vec3 uvm ) { return sampleTexture( id, uvm.xy, uvm.z ); }
|
||||
vec4 sampleTexture( uint id ) { return sampleTexture( id, surface.uv.xy, surface.uv.z ); }
|
||||
vec4 sampleTexture( uint id, float mip ) { return sampleTexture( id, surface.uv.xy, mip ); }
|
||||
#endif
|
||||
vec2 rayBoxDst( vec3 boundsMin, vec3 boundsMax, in Ray ray ) {
|
||||
const vec3 t0 = (boundsMin - ray.origin) / ray.direction;
|
||||
const vec3 t1 = (boundsMax - ray.origin) / ray.direction;
|
||||
const vec3 tmin = min(t0, t1);
|
||||
const vec3 tmax = max(t0, t1);
|
||||
const float tStart = max(0, max( max(tmin.x, tmin.y), tmin.z ));
|
||||
const float tEnd = max(0, min( tmax.x, min(tmax.y, tmax.z) ) - tStart);
|
||||
return vec2(tStart, tEnd);
|
||||
}
|
||||
#if VXGI
|
||||
float cascadePower( uint x ) {
|
||||
return pow(1 + x, ubo.settings.vxgi.cascadePower);
|
||||
// return max( 1, x * ubo.settings.vxgi.cascadePower );
|
||||
}
|
||||
#endif
|
||||
#if FRAGMENT
|
||||
void whitenoise(inout vec3 color, const vec4 parameters) {
|
||||
const float flicker = parameters.x;
|
||||
const float pieces = parameters.y;
|
||||
const float blend = parameters.z;
|
||||
const float time = parameters.w;
|
||||
if ( blend < 0.0001 ) return;
|
||||
const float freq = sin(pow(mod(time, flicker) + flicker, 1.9));
|
||||
const float whiteNoise = rand2( floor(gl_FragCoord.xy / pieces) + mod(time, freq) );
|
||||
color = mix( color, vec3(whiteNoise), blend );
|
||||
}
|
||||
vec4 resolve( subpassInputMS t, const uint samples ) {
|
||||
vec4 resolved = vec4(0);
|
||||
for ( int i = 0; i < samples; ++i ) resolved += subpassLoad(t, i);
|
||||
resolved /= vec4(samples);
|
||||
return resolved;
|
||||
}
|
||||
uvec4 resolve( usubpassInputMS t, const uint samples ) {
|
||||
uvec4 resolved = uvec4(0);
|
||||
for ( int i = 0; i < samples; ++i ) resolved += subpassLoad(t, i);
|
||||
resolved /= uvec4(samples);
|
||||
return resolved;
|
||||
}
|
||||
#endif
|
||||
vec4 resolve( sampler2DMS t, ivec2 uv ) {
|
||||
vec4 resolved = vec4(0);
|
||||
int samples = textureSamples(t);
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
resolved += texelFetch(t, uv, i);
|
||||
}
|
||||
resolved /= float(samples);
|
||||
return resolved;
|
||||
}
|
||||
//
|
||||
|
||||
vec2 encodeBarycentrics( vec3 barycentric ) {
|
||||
return barycentric.yz;
|
||||
}
|
||||
vec3 decodeBarycentrics( vec2 attributes ) {
|
||||
return vec3(
|
||||
1.0 - attributes.x - attributes.y,
|
||||
attributes.x,
|
||||
attributes.y
|
||||
);
|
||||
}
|
||||
#if DEFERRED_SAMPLING
|
||||
void populateSurfaceMaterial() {
|
||||
const Material material = materials[surface.instance.materialID];
|
||||
surface.material.albedo = material.colorBase;
|
||||
surface.material.metallic = material.factorMetallic;
|
||||
surface.material.roughness = material.factorRoughness;
|
||||
surface.material.occlusion = material.factorOcclusion;
|
||||
surface.light = material.colorEmissive;
|
||||
|
||||
if ( validTextureIndex( material.indexAlbedo ) ) {
|
||||
surface.material.albedo *= sampleTexture( material.indexAlbedo );
|
||||
}
|
||||
// OPAQUE
|
||||
if ( material.modeAlpha == 0 ) {
|
||||
surface.material.albedo.a = 1;
|
||||
// BLEND
|
||||
} else if ( material.modeAlpha == 1 ) {
|
||||
|
||||
// MASK
|
||||
} else if ( material.modeAlpha == 2 ) {
|
||||
|
||||
}
|
||||
// Lightmap
|
||||
if ( (/*surface.subID++ > 0 ||*/ bool(ubo.settings.lighting.useLightmaps)) && validTextureIndex( surface.instance.lightmapID ) ) {
|
||||
vec4 light = sampleTexture( surface.instance.lightmapID, surface.st );
|
||||
/*surface.material.lightmapped = light.a > 0.000000001;
|
||||
if ( surface.material.lightmapped )*/ surface.light += surface.material.albedo * light;
|
||||
} else {
|
||||
surface.material.lightmapped = false;
|
||||
}
|
||||
// Emissive textures
|
||||
if ( validTextureIndex( material.indexEmissive ) ) {
|
||||
surface.light += sampleTexture( material.indexEmissive );
|
||||
}
|
||||
// Occlusion map
|
||||
if ( validTextureIndex( material.indexOcclusion ) ) {
|
||||
surface.material.occlusion = sampleTexture( material.indexOcclusion ).r;
|
||||
}
|
||||
// Metallic/Roughness map
|
||||
if ( validTextureIndex( material.indexMetallicRoughness ) ) {
|
||||
vec4 samp = sampleTexture( material.indexMetallicRoughness );
|
||||
surface.material.metallic = samp.r;
|
||||
surface.material.roughness = samp.g;
|
||||
}
|
||||
// Normals
|
||||
if ( validTextureIndex( material.indexNormal ) && surface.tangent.world != vec3(0) ) {
|
||||
surface.normal.world = surface.tbn * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - vec3(1.0));
|
||||
}
|
||||
{
|
||||
surface.normal.eye = normalize(vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) ));
|
||||
}
|
||||
|
||||
surface.light *= surface.material.albedo;
|
||||
}
|
||||
|
||||
bool isValidAddress( uint64_t address ) {
|
||||
#if UINT64_ENABLED
|
||||
return bool(address);
|
||||
#else
|
||||
return bool(address.x) && bool(address.y);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BUFFER_REFERENCE
|
||||
void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
|
||||
Triangle triangle;
|
||||
Vertex points[3];
|
||||
|
||||
if ( isValidAddress(instanceAddresses.vertex) ) {
|
||||
Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex));
|
||||
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_] = vertices.v[/*triangle.*/indices[_]];
|
||||
} else {
|
||||
if ( isValidAddress(instanceAddresses.position) ) {
|
||||
VPos buf = VPos(nonuniformEXT(instanceAddresses.position));
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].position = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( isValidAddress(instanceAddresses.uv) ) {
|
||||
VUv buf = VUv(nonuniformEXT(instanceAddresses.uv));
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].uv = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( isValidAddress(instanceAddresses.st) ) {
|
||||
VSt buf = VSt(nonuniformEXT(instanceAddresses.st));
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].st = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( isValidAddress(instanceAddresses.normal) ) {
|
||||
VNormal buf = VNormal(nonuniformEXT(instanceAddresses.normal));
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( isValidAddress(instanceAddresses.tangent) ) {
|
||||
VTangent buf = VTangent(nonuniformEXT(instanceAddresses.tangent));
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].tangent = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
}
|
||||
|
||||
#if BARYCENTRIC_CALCULATE
|
||||
{
|
||||
const vec3 p = vec3(inverse( surface.instance.model ) * vec4(surface.position.world, 1));
|
||||
|
||||
const vec3 a = points[0].position;
|
||||
const vec3 b = points[1].position;
|
||||
const vec3 c = points[2].position;
|
||||
|
||||
const vec3 v0 = b - a;
|
||||
const vec3 v1 = c - a;
|
||||
const vec3 v2 = p - a;
|
||||
const float d00 = dot(v0, v0);
|
||||
const float d01 = dot(v0, v1);
|
||||
const float d11 = dot(v1, v1);
|
||||
const float d20 = dot(v2, v0);
|
||||
const float d21 = dot(v2, v1);
|
||||
const float denom = d00 * d11 - d01 * d01;
|
||||
|
||||
const float v = (d11 * d20 - d01 * d21) / denom;
|
||||
const float w = (d00 * d21 - d01 * d20) / denom;
|
||||
const float u = 1.0f - v - w;
|
||||
|
||||
surface.barycentric = vec3( u, v, w );
|
||||
}
|
||||
#endif
|
||||
|
||||
triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
|
||||
triangle.point.normal = /*triangle.*/points[0].normal * surface.barycentric[0] + /*triangle.*/points[1].normal * surface.barycentric[1] + /*triangle.*/points[2].normal * surface.barycentric[2];
|
||||
|
||||
triangle.point.position = /*triangle.*/points[0].position * surface.barycentric[0] + /*triangle.*/points[1].position * surface.barycentric[1] + /*triangle.*/points[2].position * surface.barycentric[2];
|
||||
triangle.point.uv = /*triangle.*/points[0].uv * surface.barycentric[0] + /*triangle.*/points[1].uv * surface.barycentric[1] + /*triangle.*/points[2].uv * surface.barycentric[2];
|
||||
triangle.point.st = /*triangle.*/points[0].st * surface.barycentric[0] + /*triangle.*/points[1].st * surface.barycentric[1] + /*triangle.*/points[2].st * surface.barycentric[2];
|
||||
triangle.point.tangent = /*triangle.*/points[0].tangent * surface.barycentric[0] + /*triangle.*/points[1].tangent * surface.barycentric[1] + /*triangle.*/points[2].tangent * surface.barycentric[2];
|
||||
|
||||
|
||||
if ( triangle.point.tangent != vec3(0) ) {
|
||||
surface.tangent.world = normalize(vec3( surface.instance.model * vec4(triangle.point.tangent, 0.0) ));
|
||||
vec3 bitangent = normalize(vec3( surface.instance.model * vec4(cross( triangle.point.normal, triangle.point.tangent ), 0.0) ));
|
||||
surface.tbn = mat3(surface.tangent.world, bitangent, triangle.point.normal);
|
||||
}
|
||||
|
||||
// bind position
|
||||
#if 1 || BARYCENTRIC_CALCULATE
|
||||
{
|
||||
surface.position.world = vec3( surface.instance.model * vec4(triangle.point.position, 1.0 ) );
|
||||
surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.position.world, 1.0) );
|
||||
}
|
||||
#endif
|
||||
// bind normals
|
||||
{
|
||||
surface.normal.world = normalize(vec3( surface.instance.model * vec4(triangle.point.normal, 0.0 ) ));
|
||||
// surface.normal.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) );
|
||||
}
|
||||
// bind UVs
|
||||
{
|
||||
surface.uv.xy = triangle.point.uv;
|
||||
surface.uv.z = 0;
|
||||
surface.st.xy = triangle.point.st;
|
||||
surface.st.z = 0;
|
||||
}
|
||||
|
||||
populateSurfaceMaterial();
|
||||
}
|
||||
void populateSurface( uint instanceID, uint primitiveID ) {
|
||||
surface.fragment = vec4(0);
|
||||
surface.light = vec4(0);
|
||||
surface.instance = instances[instanceID];
|
||||
|
||||
const InstanceAddresses instanceAddresses = instanceAddresses[instanceID];
|
||||
if ( !isValidAddress(instanceAddresses.index) ) return;
|
||||
const DrawCommand drawCommand = Indirects(nonuniformEXT(instanceAddresses.indirect)).dc[instanceAddresses.drawID];
|
||||
const uint triangleID = primitiveID + (drawCommand.indexID / 3);
|
||||
uvec3 indices = Indices(nonuniformEXT(instanceAddresses.index)).i[triangleID];
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/indices[_] += drawCommand.vertexID;
|
||||
|
||||
populateSurface( instanceAddresses, indices );
|
||||
}
|
||||
void populateSurface( RayTracePayload payload ) {
|
||||
surface.fragment = vec4(0);
|
||||
surface.light = vec4(0);
|
||||
surface.instance = instances[payload.instanceID];
|
||||
|
||||
if ( !payload.hit ) return;
|
||||
surface.barycentric = decodeBarycentrics(payload.attributes);
|
||||
populateSurface( payload.instanceID, payload.primitiveID );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
66
belly/bin/data/shaders/common/lambert.h
Normal file
66
belly/bin/data/shaders/common/lambert.h
Normal file
@ -0,0 +1,66 @@
|
||||
float shadowFactor( const Light light, float def );
|
||||
void lambert() {
|
||||
// outcoming light from surface to eye
|
||||
const vec3 Lo = normalize( -surface.position.eye );
|
||||
// angle of outcoming light
|
||||
const float cosLo = max(0.0, dot(surface.normal.eye, Lo));
|
||||
|
||||
for ( uint i = 0, shadows = 0; i < MAX_LIGHTS; ++i ) {
|
||||
#if BAKING
|
||||
// skip if surface is a dynamic light, we aren't baking dynamic lights
|
||||
if ( lights[i].type < 0 ) continue;
|
||||
#else
|
||||
// skip if surface is already baked, and this isn't a dynamic light
|
||||
if ( surface.material.lightmapped && lights[i].type >= 0 ) continue;
|
||||
#endif
|
||||
if ( lights[i].power <= LIGHT_POWER_CUTOFF ) continue;
|
||||
if ( surface.material.lightmapped && lights[i].type >= 0 ) continue;
|
||||
|
||||
vec3 Li = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
|
||||
// magnitude of incoming light vector (for inverse-square attenuation)
|
||||
const float Lmagnitude = dot(Li, Li);
|
||||
// distance incoming light travels (reuse from above)
|
||||
const float Ldistance = sqrt(Lmagnitude);
|
||||
// "free" normalization, since we need to compute the above values anyways
|
||||
Li = Li / Ldistance;
|
||||
// attenuation factor
|
||||
// const float Lattenuation = 1.0 / (1 + (PI * Lmagnitude));
|
||||
const float Lattenuation = 1.0 / (1 + Lmagnitude);
|
||||
// skip if attenuation factor is too low
|
||||
// if ( Lattenuation <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// ray cast if our surface is occluded from the light
|
||||
const float Lshadow = 1; // ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
|
||||
// skip if our shadow factor is too low
|
||||
if ( Lshadow <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// light radiance
|
||||
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
|
||||
// skip if our radiance is too low
|
||||
// if ( Lr <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// halfway vector
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
// angle of incoming light
|
||||
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
|
||||
// angle of halfway light vector
|
||||
const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
|
||||
/*
|
||||
const vec3 Liu = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
|
||||
const vec3 Li = normalize(Liu);
|
||||
// const float Lattenuation = 1.0 / (PI * pow(length(Liu), 2.0));
|
||||
// const float Lattenuation = 1.0 / (1 + (PI * pow(length(Liu), 2.0)));
|
||||
const float Lattenuation = 1.0 / (1 + pow(length(Liu), 2.0));
|
||||
const float Lshadow = ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
|
||||
if ( lights[i].power * Lattenuation * Lshadow <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
|
||||
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
|
||||
// const vec3 Lh = normalize(Li + Lo);
|
||||
// const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
|
||||
*/
|
||||
|
||||
const vec3 diffuse = surface.material.albedo.rgb;
|
||||
const vec3 specular = vec3(0);
|
||||
|
||||
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
surface.light.a += lights[i].power * Lattenuation * Lshadow;
|
||||
}
|
||||
}
|
||||
11
belly/bin/data/shaders/common/light.h
Normal file
11
belly/bin/data/shaders/common/light.h
Normal file
@ -0,0 +1,11 @@
|
||||
float shadowFactor( const Light light, float def );
|
||||
|
||||
#if PBR
|
||||
#include "../common/pbr.h"
|
||||
#endif
|
||||
#if LAMBERT
|
||||
#include "../common/lambert.h"
|
||||
#endif
|
||||
#if PHONG
|
||||
#include "../common/phong.h"
|
||||
#endif
|
||||
104
belly/bin/data/shaders/common/macros.h
Normal file
104
belly/bin/data/shaders/common/macros.h
Normal file
@ -0,0 +1,104 @@
|
||||
#ifndef NO_NONUNIFORM_EXT
|
||||
#define NO_NONUNIFORM_EXT 0
|
||||
// enable if shaderNonUniform is not supported
|
||||
// Nvidia hardware does not require nonuniformEXT, but AMD does
|
||||
#endif
|
||||
|
||||
// implicit variables
|
||||
#ifndef MULTISAMPLING
|
||||
#define MULTISAMPLING 1
|
||||
#endif
|
||||
#ifndef MAX_MSAA_SAMPLES
|
||||
#define MAX_MSAA_SAMPLES 16
|
||||
#endif
|
||||
#ifndef MAX_TEXTURES
|
||||
#define MAX_TEXTURES TEXTURES
|
||||
#endif
|
||||
#ifndef MAX_LIGHTS
|
||||
#define MAX_LIGHTS ubo.settings.lengths.lights
|
||||
#endif
|
||||
#ifndef MAX_SHADOWS
|
||||
#define MAX_SHADOWS ubo.settings.lighting.maxShadows
|
||||
#endif
|
||||
#ifndef VIEW_MATRIX
|
||||
#define VIEW_MATRIX ubo.eyes[surface.pass].view
|
||||
#endif
|
||||
|
||||
// implicit shader settings
|
||||
#ifndef CAN_DISCARD
|
||||
#define CAN_DISCARD 1
|
||||
#endif
|
||||
#ifndef USE_LIGHTMAP
|
||||
#define USE_LIGHTMAP 1
|
||||
#endif
|
||||
#if VXGI
|
||||
#define VXGI_NDC 1
|
||||
#define VXGI_SHADOWS 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifndef FOG
|
||||
#define FOG 1
|
||||
#endif
|
||||
#ifndef FOG_RAY_MARCH
|
||||
#define FOG_RAY_MARCH 1
|
||||
#endif
|
||||
#ifndef WHITENOISE
|
||||
#define WHITENOISE 1
|
||||
#endif
|
||||
#ifndef GAMMA_CORRECT
|
||||
#define GAMMA_CORRECT 1
|
||||
#endif
|
||||
#ifndef TONE_MAP
|
||||
#define TONE_MAP 1
|
||||
#endif
|
||||
#ifndef PHONG
|
||||
#define PHONG 0
|
||||
#endif
|
||||
#ifndef LAMBERT
|
||||
#define LAMBERT 0
|
||||
#endif
|
||||
#ifndef PBR
|
||||
#define PBR 1
|
||||
#endif
|
||||
*/
|
||||
|
||||
#if NO_NONUNIFORM_EXT
|
||||
#define nonuniformEXT(X) X
|
||||
#else
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
#endif
|
||||
|
||||
#if !UINT64_ENABLED
|
||||
#define uint64_t uvec2
|
||||
#endif
|
||||
|
||||
// easy and accessible in one place
|
||||
#ifndef BARYCENTRIC
|
||||
#define BARYCENTRIC 0
|
||||
#endif
|
||||
#if BARYCENTRIC
|
||||
#ifndef BARYCENTRIC_CALCULATE
|
||||
#define BARYCENTRIC_CALCULATE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BUFFER_REFERENCE
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
#extension GL_EXT_buffer_reference : enable
|
||||
#extension GL_EXT_buffer_reference2 : enable
|
||||
#if UINT64_ENABLED
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable
|
||||
#else
|
||||
#extension GL_EXT_buffer_reference_uvec2 : enable
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
const float EPSILON = 0.00001;
|
||||
const float SQRT2 = 1.41421356237;
|
||||
|
||||
const float LIGHT_POWER_CUTOFF = 0.0005;
|
||||
const float LIGHTMAP_GAMMA = 1.0;
|
||||
|
||||
#define SETTINGS_TYPE_FULLBRIGHT 0x10
|
||||
121
belly/bin/data/shaders/common/pbr.h
Normal file
121
belly/bin/data/shaders/common/pbr.h
Normal file
@ -0,0 +1,121 @@
|
||||
// PBR
|
||||
void pbr() {
|
||||
// per-surface, not per-light, compute once
|
||||
|
||||
// Freslen reflectance for a dieletric
|
||||
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
|
||||
// outcoming light from surface to eye
|
||||
const vec3 Lo = normalize( -surface.position.eye );
|
||||
// angle of outcoming light
|
||||
const float cosLo = max(0.0, dot(surface.normal.eye, Lo));
|
||||
|
||||
const float Rs = 4.0;
|
||||
|
||||
for ( uint i = 0, shadows = 0; i < MAX_LIGHTS; ++i ) {
|
||||
#if BAKING
|
||||
// skip if surface is a dynamic light, we aren't baking dynamic lights
|
||||
if ( lights[i].type < 0 ) continue;
|
||||
#else
|
||||
// skip if surface is already baked, and this isn't a dynamic light
|
||||
if ( surface.material.lightmapped && lights[i].type >= 0 ) continue;
|
||||
#endif
|
||||
/*
|
||||
// skip if light power is too low
|
||||
if ( lights[i].power <= LIGHT_POWER_CUTOFF ) continue;
|
||||
if ( surface.material.lightmapped && lights[i].type >= 0 ) continue;
|
||||
|
||||
const vec3 Liu = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
|
||||
const vec3 Li = normalize(Liu);
|
||||
const float Lshadow = ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
|
||||
// const float Lattenuation = 1.0 / (PI * pow(length(Liu), 2.0));
|
||||
// const float Lattenuation = 1.0 / (1 + (PI * pow(length(Liu), 2.0)));
|
||||
const float Lattenuation = 1.0 / (1 + pow(length(Liu), 2.0));
|
||||
if ( lights[i].power * Lattenuation * Lshadow <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
|
||||
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
|
||||
*/
|
||||
// incoming light to surface (non-const to normalize it later)
|
||||
// vec3 Li = lights[i].position - surface.position.world;
|
||||
vec3 Li = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
|
||||
// magnitude of incoming light vector (for inverse-square attenuation)
|
||||
const float Lmagnitude = dot(Li, Li);
|
||||
// distance incoming light travels (reuse from above)
|
||||
const float Ldistance = sqrt(Lmagnitude);
|
||||
// "free" normalization, since we need to compute the above values anyways
|
||||
Li = Li / Ldistance;
|
||||
// attenuation factor
|
||||
// const float Lattenuation = 1.0 / (1 + (PI * Lmagnitude));
|
||||
const float Lattenuation = 1.0 / (1 + Lmagnitude);
|
||||
// skip if attenuation factor is too low
|
||||
// if ( Lattenuation <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// ray cast if our surface is occluded from the light
|
||||
const float Lshadow = ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
|
||||
// skip if our shadow factor is too low
|
||||
if ( Lshadow <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// light radiance
|
||||
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
|
||||
// skip if our radiance is too low
|
||||
// if ( Lr <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// halfway vector
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
// angle of incoming light
|
||||
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
|
||||
// angle of halfway light vector
|
||||
const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
|
||||
|
||||
// Fresnel term for direct lighting
|
||||
const vec3 F = fresnelSchlick(F0, max(0.0, dot(Lh, Lo)));
|
||||
// Distribution for specular lighting
|
||||
const float D = ndfGGX( cosLh, surface.material.roughness * Rs);
|
||||
// Geometric attenuation for specular lighting
|
||||
const float G = gaSchlickGGX(cosLi, cosLo, surface.material.roughness * Rs);
|
||||
|
||||
// final lighting
|
||||
const vec3 diffuse = mix(vec3(1.0) - F, vec3(0), surface.material.metallic) * surface.material.albedo.rgb;
|
||||
const vec3 specular = ( shadows < MAX_SHADOWS ) ? ((F * D * G) / max(EPSILON, 4.0 * cosLi * cosLo)) : vec3(0);
|
||||
|
||||
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
surface.light.a += lights[i].power * Lattenuation * Lshadow;
|
||||
}
|
||||
#if 0
|
||||
const float Rs = 4.0; // specular lighting looks gross without this
|
||||
uint shadows = 0;
|
||||
for ( uint i = 0; i < ubo.settings.lengths.lights; ++i ) {
|
||||
const Light light = lights[i];
|
||||
if ( light.power <= LIGHT_POWER_CUTOFF ) continue;
|
||||
if ( surface.material.lightmapped && light.type >= 0 ) continue;
|
||||
|
||||
const vec3 Liu = vec3(ubo.eyes[surface.pass].view * vec4(light.position, 1)) - surface.position.eye;
|
||||
const float Ld = length(Liu);
|
||||
const float La = 1.0 / (1 + (PI * pow(Ld, 2.0)));
|
||||
if ( La <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const vec3 Li = normalize(Liu);
|
||||
const float Ls = ( shadows++ < ubo.settings.lighting.maxShadows ) ? shadowFactor( light, 0.0 ) : 1;
|
||||
if ( light.power * La * Ls <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
|
||||
const vec3 Lr = light.color.rgb * light.power * La * Ls;
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
|
||||
|
||||
const vec3 F = fresnelSchlick( F0, max( 0.0, dot(Lh, Lo) ) );
|
||||
const float D = ndfGGX( cosLh, surface.material.roughness * Rs );
|
||||
const float G = gaSchlickGGX(cosLi, cosLo, surface.material.roughness);
|
||||
const vec3 diffuse = mix( vec3(1.0) - F, vec3(0.0), surface.material.metallic ) * surface.material.albedo.rgb;
|
||||
const vec3 specular = (F * D * G) / max(EPSILON, 4.0 * cosLi * cosLo);
|
||||
/*
|
||||
// lightmapped, compute only specular
|
||||
if ( light.type >= 0 && validTextureIndex( surface.instance.lightmapID ) ) surface.light.rgb += (specular) * Lr * cosLi;
|
||||
// point light, compute only diffuse
|
||||
// else if ( abs(light.type) == 1 ) surface.light.rgb += (diffuse) * Lr * cosLi;
|
||||
else surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
*/
|
||||
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
surface.light.a += light.power * La * Ls;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
171
belly/bin/data/shaders/common/shadows.h
Normal file
171
belly/bin/data/shaders/common/shadows.h
Normal file
@ -0,0 +1,171 @@
|
||||
const vec2 poissonDisk[16] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 ),
|
||||
vec2( -0.91588581, 0.45771432 ),
|
||||
vec2( -0.81544232, -0.87912464 ),
|
||||
vec2( -0.38277543, 0.27676845 ),
|
||||
vec2( 0.97484398, 0.75648379 ),
|
||||
vec2( 0.44323325, -0.97511554 ),
|
||||
vec2( 0.53742981, -0.47373420 ),
|
||||
vec2( -0.26496911, -0.41893023 ),
|
||||
vec2( 0.79197514, 0.19090188 ),
|
||||
vec2( -0.24188840, 0.99706507 ),
|
||||
vec2( -0.81409955, 0.91437590 ),
|
||||
vec2( 0.19984126, 0.78641367 ),
|
||||
vec2( 0.14383161, -0.14100790 )
|
||||
);
|
||||
|
||||
#ifndef SHADOW_SAMPLES
|
||||
#define SHADOW_SAMPLES ubo.settings.lighting.shadowSamples
|
||||
#endif
|
||||
#if VXGI
|
||||
float voxelShadowFactor( const Light, float def );
|
||||
#endif
|
||||
|
||||
#if CUBEMAPS
|
||||
float omniShadowMap( const Light light, float def ) {
|
||||
return 1.0;
|
||||
}
|
||||
#else
|
||||
float omniShadowMap( const Light light, float def ) {
|
||||
float factor = 1.0;
|
||||
|
||||
const mat4 views[6] = {
|
||||
mat4( 0, 0, 1, 0, 0, 1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 1 ),
|
||||
mat4( 0, 0,-1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 ),
|
||||
mat4( 1, 0, 0, 0, 0, 0, 1, 0, 0,-1, 0, 0, 0, 0, 0, 1 ),
|
||||
mat4( 1, 0, 0, 0, 0, 0,-1, 0, 0, 1, 0, 0, 0, 0, 0, 1 ),
|
||||
mat4( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ),
|
||||
mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0,-1, 0, 0, 0, 0, 1 ),
|
||||
};
|
||||
|
||||
const vec3 D = normalize(surface.position.world - light.position);
|
||||
const vec3 N = abs(D);
|
||||
uint A = N.y > N.x ? 1 : 0;
|
||||
A = N.z > N[A] ? 2 : A;
|
||||
uint index = A * 2;
|
||||
if ( D[A] < 0.0 ) ++index;
|
||||
|
||||
vec4 positionClip = light.projection * views[index] * vec4(surface.position.world - light.position, 1.0);
|
||||
positionClip.xy /= positionClip.w;
|
||||
|
||||
if ( positionClip.x < -1 || positionClip.x >= 1 ) return 0.0;
|
||||
if ( positionClip.y < -1 || positionClip.y >= 1 ) return 0.0;
|
||||
if ( positionClip.z < -1 || positionClip.z >= 1 ) return 0.0;
|
||||
|
||||
const float eyeDepthScale = 1.0;
|
||||
const float sampledDepthScale = light.view[1][1]; // light view matricies will incorporate scaling factors for some retarded reason, so we need to rescale it by grabbing from here, hopefully it remains coherent between all light matrices to ever exist in engine
|
||||
|
||||
const float bias = light.depthBias;
|
||||
const float eyeDepth = abs(positionClip.z / positionClip.w) * eyeDepthScale;
|
||||
|
||||
const vec3 sampleOffsetDirections[20] = {
|
||||
vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
|
||||
vec3( 1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
|
||||
vec3( 1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
|
||||
vec3( 1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
|
||||
vec3( 0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
|
||||
};
|
||||
|
||||
float sampled = 0;
|
||||
const int samples = int(SHADOW_SAMPLES);
|
||||
// cubemap point light
|
||||
if ( light.typeMap == 1 ) {
|
||||
if ( samples < 1 ) {
|
||||
sampled = texture(samplerCubemaps[nonuniformEXT(light.indexMap)], D).r * sampledDepthScale;
|
||||
} else {
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
const int idx = int( float(samples) * random(floor(surface.position.world.xyz * 1000.0), i)) % samples;
|
||||
vec2 poisson = poissonDisk[idx] / 700.0;
|
||||
vec3 P = vec3( poisson.xy, (poisson.x + poisson.y) * 0.5 );
|
||||
sampled = texture(samplerCubemaps[nonuniformEXT(light.indexMap)], D + P ).r * sampledDepthScale;
|
||||
if ( eyeDepth < sampled - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
// separated point lights
|
||||
} else if ( light.typeMap == 2 ) {
|
||||
const vec2 uv = positionClip.xy * 0.5 + 0.5;
|
||||
if ( samples < 1 ) {
|
||||
sampled = texture(samplerTextures[nonuniformEXT(light.indexMap + index)], uv).r * sampledDepthScale;
|
||||
} else {
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
const int idx = int( float(samples) * random(floor(surface.position.world.xyz * 1000.0), i)) % samples;
|
||||
sampled = texture(samplerTextures[nonuniformEXT(light.indexMap + index)], uv + poissonDisk[idx] / 700.0 ).r * sampledDepthScale;
|
||||
if ( eyeDepth < sampled - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
}
|
||||
return eyeDepth < sampled - bias ? 0.0 : factor;
|
||||
}
|
||||
#endif
|
||||
#if RT
|
||||
float shadowFactorRT( const Light light, float def ) {
|
||||
Ray ray;
|
||||
ray.origin = surface.position.world;
|
||||
ray.direction = light.position - ray.origin;
|
||||
|
||||
float tMin = ubo.settings.rt.defaultRayBounds.x;
|
||||
float tMax = length(ray.direction) - ubo.settings.rt.defaultRayBounds.x;
|
||||
|
||||
ray.direction = normalize(ray.direction);
|
||||
|
||||
uint rayFlags = gl_RayFlagsOpaqueEXT | gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsSkipClosestHitShaderEXT;
|
||||
uint cullMask = 0xFF;
|
||||
|
||||
rayQueryEXT rayQuery;
|
||||
rayQueryInitializeEXT(rayQuery, tlas, rayFlags, cullMask, ray.origin, tMin, ray.direction, tMax);
|
||||
|
||||
while(rayQueryProceedEXT(rayQuery));
|
||||
|
||||
return rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionNoneEXT ? 1.0 : 0.0;
|
||||
}
|
||||
#endif
|
||||
float shadowFactor( const Light light, float def ) {
|
||||
#if RT
|
||||
return shadowFactorRT( light, def );
|
||||
#endif
|
||||
if ( light.typeMap != 0 ) return omniShadowMap( light, def );
|
||||
|
||||
if ( !validTextureIndex(light.indexMap) )
|
||||
#if VXGI
|
||||
return voxelShadowFactor( light, def );
|
||||
#else
|
||||
return 1.0;
|
||||
#endif
|
||||
|
||||
vec4 positionClip = light.projection * light.view * vec4(surface.position.world, 1.0);
|
||||
positionClip.xyz /= positionClip.w;
|
||||
|
||||
if ( positionClip.x < -1 || positionClip.x >= 1 ) return def; //0.0;
|
||||
if ( positionClip.y < -1 || positionClip.y >= 1 ) return def; //0.0;
|
||||
if ( positionClip.z <= 0 || positionClip.z >= 1 ) return def; //0.0;
|
||||
|
||||
float factor = 1.0;
|
||||
|
||||
// spot light
|
||||
if ( abs(light.type) == 2 || abs(light.type) == 3 ) {
|
||||
const float dist = length( positionClip.xy );
|
||||
if ( dist > 0.5 ) return def; //0.0;
|
||||
|
||||
// spot light with attenuation
|
||||
if ( abs(light.type) == 3 ) {
|
||||
factor = 1.0 - (pow(dist * 2,2.0));
|
||||
}
|
||||
}
|
||||
|
||||
const vec2 uv = positionClip.xy * 0.5 + 0.5;
|
||||
const float bias = light.depthBias;
|
||||
const float eyeDepth = positionClip.z;
|
||||
const int samples = int(SHADOW_SAMPLES);
|
||||
if ( samples < 1 ) return eyeDepth < texture(samplerTextures[nonuniformEXT(light.indexMap)], uv).r - bias ? 0.0 : factor;
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
const int index = int( float(samples) * random(floor(surface.position.world.xyz * 1000.0), i)) % samples;
|
||||
const float lightDepth = texture(samplerTextures[nonuniformEXT(light.indexMap)], uv + poissonDisk[index] / 700.0 ).r;
|
||||
if ( eyeDepth < lightDepth - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
308
belly/bin/data/shaders/common/structs.h
Normal file
308
belly/bin/data/shaders/common/structs.h
Normal file
@ -0,0 +1,308 @@
|
||||
struct EyeMatrices {
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
|
||||
mat4 model;
|
||||
mat4 previous;
|
||||
|
||||
mat4 iView;
|
||||
mat4 iProjection;
|
||||
|
||||
vec4 eyePos;
|
||||
};
|
||||
|
||||
struct Viewport {
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
|
||||
struct Cursor {
|
||||
vec2 position;
|
||||
vec2 radius;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
struct Ray {
|
||||
vec3 origin;
|
||||
vec3 direction;
|
||||
|
||||
vec3 position;
|
||||
float distance;
|
||||
};
|
||||
|
||||
struct Space {
|
||||
vec3 eye;
|
||||
vec3 world;
|
||||
};
|
||||
|
||||
struct Light {
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
|
||||
vec3 position;
|
||||
float radius;
|
||||
|
||||
vec3 color;
|
||||
float power;
|
||||
|
||||
int type;
|
||||
int typeMap;
|
||||
int indexMap;
|
||||
float depthBias;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
vec4 colorBase;
|
||||
vec4 colorEmissive;
|
||||
|
||||
float factorMetallic;
|
||||
float factorRoughness;
|
||||
float factorOcclusion;
|
||||
float factorAlphaCutoff;
|
||||
|
||||
int indexAlbedo;
|
||||
int indexNormal;
|
||||
int indexEmissive;
|
||||
int indexOcclusion;
|
||||
|
||||
int indexMetallicRoughness;
|
||||
int padding1;
|
||||
int padding2;
|
||||
int modeAlpha;
|
||||
};
|
||||
|
||||
struct Texture {
|
||||
int index;
|
||||
int samp;
|
||||
int remap;
|
||||
float blend;
|
||||
|
||||
vec4 lerp;
|
||||
};
|
||||
|
||||
struct DrawCommand {
|
||||
uint indices; // triangle count
|
||||
uint instances; // instance count
|
||||
uint indexID; // starting triangle position
|
||||
int vertexID; // starting vertex position
|
||||
|
||||
uint instanceID; // starting instance position
|
||||
float padding1; //
|
||||
float padding2; // material to use for this draw call
|
||||
uint vertices; // number of vertices used
|
||||
};
|
||||
|
||||
struct Bounds {
|
||||
vec3 min;
|
||||
float padding1;
|
||||
vec3 max;
|
||||
float padding2;
|
||||
};
|
||||
|
||||
struct Instance {
|
||||
mat4 model;
|
||||
mat4 previous;
|
||||
|
||||
vec4 color;
|
||||
|
||||
uint materialID;
|
||||
uint primitiveID;
|
||||
uint meshID;
|
||||
uint objectID;
|
||||
|
||||
int jointID;
|
||||
int lightmapID;
|
||||
uint imageID;
|
||||
uint auxID;
|
||||
|
||||
Bounds bounds;
|
||||
// InstanceAddresses addresses;
|
||||
};
|
||||
|
||||
struct InstanceAddresses {
|
||||
uint64_t vertex;
|
||||
uint64_t index;
|
||||
|
||||
uint64_t indirect;
|
||||
uint drawID;
|
||||
uint padding0;
|
||||
|
||||
uint64_t position;
|
||||
uint64_t uv;
|
||||
|
||||
uint64_t color;
|
||||
uint64_t st;
|
||||
|
||||
uint64_t normal;
|
||||
uint64_t tangent;
|
||||
|
||||
uint64_t joints;
|
||||
uint64_t weights;
|
||||
|
||||
uint64_t id;
|
||||
uint64_t padding1;
|
||||
};
|
||||
|
||||
struct SurfaceMaterial {
|
||||
vec4 albedo;
|
||||
vec4 indirect;
|
||||
|
||||
float metallic;
|
||||
float roughness;
|
||||
float occlusion;
|
||||
bool lightmapped;
|
||||
};
|
||||
|
||||
struct Surface {
|
||||
uint pass;
|
||||
uint subID;
|
||||
|
||||
vec3 uv;
|
||||
vec3 st;
|
||||
Space position;
|
||||
Space normal;
|
||||
Space tangent;
|
||||
mat3 tbn;
|
||||
vec3 barycentric;
|
||||
vec2 motion;
|
||||
|
||||
Ray ray;
|
||||
|
||||
SurfaceMaterial material;
|
||||
Instance instance;
|
||||
|
||||
vec4 light;
|
||||
vec4 fragment;
|
||||
} surface;
|
||||
|
||||
// MSAA info
|
||||
#if MULTISAMPLING
|
||||
struct MSAA {
|
||||
int currentID;
|
||||
uvec2 IDs[MAX_MSAA_SAMPLES];
|
||||
vec4 fragment;
|
||||
vec4 fragments[MAX_MSAA_SAMPLES];
|
||||
} msaa;
|
||||
#endif
|
||||
// UBO settings
|
||||
struct SettingsLengths {
|
||||
uint lights;
|
||||
uint materials;
|
||||
uint textures;
|
||||
uint drawCommands;
|
||||
};
|
||||
struct SettingsMode {
|
||||
vec4 parameters;
|
||||
uint type;
|
||||
uint scalar;
|
||||
uint msaa;
|
||||
uint frameNumber;
|
||||
};
|
||||
struct SettingsLighting {
|
||||
vec3 ambient;
|
||||
uint indexSkybox;
|
||||
|
||||
uint maxShadows;
|
||||
uint shadowSamples;
|
||||
uint useLightmaps;
|
||||
};
|
||||
struct SettingsFog {
|
||||
vec3 color;
|
||||
float stepScale;
|
||||
|
||||
vec3 offset;
|
||||
float densityScale;
|
||||
|
||||
vec2 range;
|
||||
float densityThreshold;
|
||||
float densityMultiplier;
|
||||
|
||||
float absorbtion;
|
||||
float padding1;
|
||||
float padding2;
|
||||
float padding3;
|
||||
};
|
||||
struct SettingsBloom {
|
||||
float exposure;
|
||||
float gamma;
|
||||
float threshold;
|
||||
uint padding;
|
||||
};
|
||||
struct SettingsVxgi {
|
||||
mat4 matrix;
|
||||
|
||||
float cascadePower;
|
||||
float granularity;
|
||||
float voxelizeScale;
|
||||
float occlusionFalloff;
|
||||
|
||||
float traceStartOffsetFactor;
|
||||
uint shadows;
|
||||
uint padding2;
|
||||
uint padding3;
|
||||
};
|
||||
struct SettingsRayTrace {
|
||||
vec2 defaultRayBounds;
|
||||
float alphaTestOffset;
|
||||
float padding1;
|
||||
|
||||
uint samples;
|
||||
uint paths;
|
||||
uint frameAccumulationMinimum;
|
||||
uint padding2;
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
SettingsLengths lengths;
|
||||
SettingsMode mode;
|
||||
SettingsLighting lighting;
|
||||
SettingsFog fog;
|
||||
SettingsBloom bloom;
|
||||
SettingsVxgi vxgi;
|
||||
SettingsRayTrace rt;
|
||||
};
|
||||
struct Voxel {
|
||||
uvec2 id;
|
||||
vec3 position;
|
||||
vec3 normal;
|
||||
vec2 uv;
|
||||
vec4 color;
|
||||
};
|
||||
struct VoxelInfo {
|
||||
vec3 min;
|
||||
vec3 max;
|
||||
|
||||
float mipmapLevels;
|
||||
float radianceSize;
|
||||
float radianceSizeRecip;
|
||||
} voxelInfo;
|
||||
|
||||
// Raytrace stuff
|
||||
|
||||
struct Vertex {
|
||||
vec3 position;
|
||||
vec2 uv;
|
||||
uint color;
|
||||
vec2 st;
|
||||
vec3 normal;
|
||||
vec3 tangent;
|
||||
uvec2 joints;
|
||||
vec4 weights;
|
||||
uint id;
|
||||
};
|
||||
|
||||
struct Triangle {
|
||||
Vertex point;
|
||||
|
||||
vec3 geomNormal;
|
||||
|
||||
uint instanceID;
|
||||
};
|
||||
|
||||
struct RayTracePayload {
|
||||
bool hit;
|
||||
uint instanceID;
|
||||
uint primitiveID;
|
||||
vec2 attributes;
|
||||
// Triangle triangle;
|
||||
};
|
||||
189
belly/bin/data/shaders/common/vxgi.h
Normal file
189
belly/bin/data/shaders/common/vxgi.h
Normal file
@ -0,0 +1,189 @@
|
||||
// GI
|
||||
uint cascadeIndex( vec3 v ) {
|
||||
float x = max3( abs( v ) );
|
||||
for ( uint cascade = 0; cascade < CASCADES; ++cascade )
|
||||
if ( x / cascadePower(cascade) < 1 - voxelInfo.radianceSizeRecip ) return cascade;
|
||||
return CASCADES - 1;
|
||||
}
|
||||
|
||||
vec4 voxelTrace( inout Ray ray, float aperture, float maxDistance ) {
|
||||
ray.origin += ray.direction * voxelInfo.radianceSizeRecip * 2 * SQRT2;
|
||||
#if VXGI_NDC
|
||||
ray.origin = vec3( ubo.settings.vxgi.matrix * vec4( ray.origin, 1.0 ) );
|
||||
ray.direction = vec3( ubo.settings.vxgi.matrix * vec4( ray.direction, 0.0 ) );
|
||||
uint cascade = cascadeIndex(ray.origin);
|
||||
#else
|
||||
uint cascade = cascadeIndex( vec3( ubo.settings.vxgi.matrix * vec4( ray.origin, 1.0 ) ) );
|
||||
#endif
|
||||
const float granularityRecip = ubo.settings.vxgi.granularity; //2.0; // 0.25f * (CASCADES - cascade);
|
||||
const float granularity = 1.0f / granularityRecip;
|
||||
const float occlusionFalloff = ubo.settings.vxgi.occlusionFalloff; //128.0f;
|
||||
const vec3 voxelBounds = voxelInfo.max - voxelInfo.min;
|
||||
const vec3 voxelBoundsRecip = 1.0f / voxelBounds;
|
||||
const float coneCoefficient = 2.0 * tan(aperture * 0.5);
|
||||
const uint maxSteps = uint(voxelInfo.radianceSize * cascadePower(CASCADES-1) * granularityRecip);
|
||||
// box
|
||||
const vec2 rayBoxInfoA = rayBoxDst( voxelInfo.min * cascadePower(cascade), voxelInfo.max * cascadePower(cascade), ray );
|
||||
const vec2 rayBoxInfoB = rayBoxDst( voxelInfo.min * cascadePower(CASCADES-1), voxelInfo.max * cascadePower(CASCADES-1), ray );
|
||||
|
||||
const float tStart = rayBoxInfoA.x;
|
||||
const float tEnd = maxDistance > 0 ? min(maxDistance, rayBoxInfoB.y) : rayBoxInfoB.y;
|
||||
const float tDelta = voxelInfo.radianceSizeRecip * granularityRecip;
|
||||
// marcher
|
||||
ray.distance = tStart + tDelta * ubo.settings.vxgi.traceStartOffsetFactor;
|
||||
ray.position = vec3(0);
|
||||
|
||||
vec4 radiance = vec4(0);
|
||||
vec3 uvw = vec3(0);
|
||||
float coneDiameter = coneCoefficient * ray.distance;
|
||||
float level = aperture > 0 ? log2( coneDiameter ) : 0;
|
||||
vec4 color = vec4(0);
|
||||
float occlusion = 0.0;
|
||||
uint stepCounter = 0;
|
||||
while ( color.a < 1.0 && occlusion < 1.0 && ray.distance < tEnd && stepCounter++ < maxSteps ) {
|
||||
ray.distance += tDelta * cascadePower(cascade) * max(1, coneDiameter);
|
||||
ray.position = ray.origin + ray.direction * ray.distance;
|
||||
|
||||
#if VXGI_NDC
|
||||
uvw = ray.position;
|
||||
#else
|
||||
uvw = vec3( ubo.settings.vxgi.matrix * vec4( ray.position, 1.0 ) );
|
||||
#endif
|
||||
cascade = cascadeIndex( uvw );
|
||||
uvw = (uvw / cascadePower(cascade)) * 0.5 + 0.5;
|
||||
if ( cascade >= CASCADES || uvw.x < 0.0 || uvw.y < 0.0 || uvw.z < 0.0 || uvw.x >= 1.0 || uvw.y >= 1.0 || uvw.z >= 1.0 ) break;
|
||||
coneDiameter = coneCoefficient * ray.distance;
|
||||
level = aperture > 0 ? log2( coneDiameter ) : 0;
|
||||
if ( level >= voxelInfo.mipmapLevels ) break;
|
||||
radiance = textureLod(voxelRadiance[nonuniformEXT(cascade)], uvw.xzy, level);
|
||||
color += (1.0 - color.a) * radiance;
|
||||
occlusion += ((1.0f - occlusion) * radiance.a) / (1.0f + occlusionFalloff * coneDiameter);
|
||||
}
|
||||
return maxDistance > 0 ? color : vec4(color.rgb, occlusion);
|
||||
// return vec4(color.rgb, occlusion);
|
||||
}
|
||||
vec4 voxelConeTrace( inout Ray ray, float aperture ) {
|
||||
return voxelTrace( ray, aperture, 0 );
|
||||
}
|
||||
vec4 voxelTrace( inout Ray ray, float maxDistance ) {
|
||||
return voxelTrace( ray, 0, maxDistance );
|
||||
}
|
||||
uint voxelShadowsCount = 0;
|
||||
float voxelShadowFactor( const Light light, float def ) {
|
||||
if ( ubo.settings.vxgi.shadows < ++voxelShadowsCount ) return 1.0;
|
||||
|
||||
const float SHADOW_APERTURE = 0.2;
|
||||
const float DEPTH_BIAS = 0.0;
|
||||
|
||||
Ray ray;
|
||||
ray.direction = normalize( light.position - surface.position.world );
|
||||
ray.origin = surface.position.world + ray.direction * 0.5;
|
||||
float z = distance( surface.position.world, light.position ) - DEPTH_BIAS;
|
||||
return 1.0 - voxelTrace( ray, SHADOW_APERTURE, z ).a;
|
||||
}
|
||||
void indirectLighting() {
|
||||
voxelInfo.radianceSize = textureSize( voxelRadiance[0], 0 ).x;
|
||||
voxelInfo.radianceSizeRecip = 1.0 / voxelInfo.radianceSize;
|
||||
voxelInfo.mipmapLevels = log2(voxelInfo.radianceSize) + 1;
|
||||
#if VXGI_NDC
|
||||
voxelInfo.min = vec3( -1 );
|
||||
voxelInfo.max = vec3( 1 );
|
||||
#else
|
||||
const mat4 inverseOrtho = inverse( ubo.settings.vxgi.matrix );
|
||||
voxelInfo.min = vec3( inverseOrtho * vec4( -1, -1, -1, 1 ) );
|
||||
voxelInfo.max = vec3( inverseOrtho * vec4( 1, 1, 1, 1 ) );
|
||||
#endif
|
||||
|
||||
const vec3 P = surface.position.world;
|
||||
const vec3 N = surface.normal.world;
|
||||
|
||||
#if 1
|
||||
const vec3 right = normalize(orthogonal(N));
|
||||
const vec3 up = normalize(cross(right, N));
|
||||
|
||||
const uint CONES_COUNT = 6;
|
||||
const vec3 CONES[] = {
|
||||
N,
|
||||
normalize(N + 0.0f * right + 0.866025f * up),
|
||||
normalize(N + 0.823639f * right + 0.267617f * up),
|
||||
normalize(N + 0.509037f * right + -0.7006629f * up),
|
||||
normalize(N + -0.50937f * right + -0.7006629f * up),
|
||||
normalize(N + -0.823639f * right + 0.267617f * up),
|
||||
};
|
||||
#else
|
||||
const vec3 ortho = normalize(orthogonal(N));
|
||||
const vec3 ortho2 = normalize(cross(ortho, N));
|
||||
|
||||
const vec3 corner = 0.5f * (ortho + ortho2);
|
||||
const vec3 corner2 = 0.5f * (ortho - ortho2);
|
||||
|
||||
const uint CONES_COUNT = 9;
|
||||
const vec3 CONES[] = {
|
||||
N,
|
||||
normalize(mix(N, ortho, 0.5)),
|
||||
normalize(mix(N, -ortho, 0.5)),
|
||||
normalize(mix(N, ortho2, 0.5)),
|
||||
normalize(mix(N, -ortho2, 0.5)),
|
||||
normalize(mix(N, corner, 0.5)),
|
||||
normalize(mix(N, -corner, 0.5)),
|
||||
normalize(mix(N, corner2, 0.5)),
|
||||
normalize(mix(N, -corner2, 0.5)),
|
||||
};
|
||||
#endif
|
||||
|
||||
const float DIFFUSE_CONE_APERTURE = 2.0 * 0.57735f;
|
||||
const float DIFFUSE_INDIRECT_FACTOR = 0; // 1.0f / float(CONES_COUNT) * 0.125f;
|
||||
|
||||
const float SPECULAR_CONE_APERTURE = clamp(tan(PI * 0.5f * surface.material.roughness), 0.0174533f, PI); // tan( R * PI * 0.5f * 0.1f );
|
||||
const float SPECULAR_INDIRECT_FACTOR = (1.0 - surface.material.metallic); // * 0.25; // 1.0f;
|
||||
|
||||
vec4 indirectDiffuse = vec4(0);
|
||||
vec4 indirectSpecular = vec4(0);
|
||||
|
||||
// outFragColor.rgb = voxelConeTrace( surface.ray, 0 ).rgb; return;
|
||||
if ( DIFFUSE_INDIRECT_FACTOR > 0.0f ) {
|
||||
float weight = PI * 0.25f;
|
||||
for ( uint i = 0; i < CONES_COUNT; ++i ) {
|
||||
Ray ray;
|
||||
ray.direction = CONES[i].xyz;
|
||||
ray.origin = P; // + ray.direction;
|
||||
indirectDiffuse += voxelConeTrace( ray, DIFFUSE_CONE_APERTURE ) * weight;
|
||||
weight = PI * 0.15f;
|
||||
}
|
||||
// indirectDiffuse.rgb *= surface.material.albedo.rgb;
|
||||
surface.material.occlusion += 1.0 - clamp(indirectDiffuse.a, 0.0, 1.0);
|
||||
// outFragColor.rgb = indirectDiffuse.rgb; return;
|
||||
// outFragColor.rgb = vec3(surface.material.occlusion); return;
|
||||
}
|
||||
if ( SPECULAR_INDIRECT_FACTOR > 0.0f ) {
|
||||
const vec3 R = reflect( normalize(P - surface.ray.origin), N );
|
||||
Ray ray;
|
||||
ray.direction = R;
|
||||
ray.origin = P; // + ray.direction;
|
||||
indirectSpecular = voxelConeTrace( ray, SPECULAR_CONE_APERTURE );
|
||||
// indirectSpecular.rgb *= surface.material.albedo.rgb;
|
||||
// outFragColor.rgb = indirectSpecular.rgb; return;
|
||||
}
|
||||
|
||||
/*
|
||||
if ( true ) {
|
||||
gammaCorrect(indirectDiffuse.rgb, 1.0 / ubo.settings.bloom.gamma);
|
||||
}
|
||||
*/
|
||||
indirectDiffuse *= DIFFUSE_INDIRECT_FACTOR;
|
||||
indirectSpecular *= SPECULAR_INDIRECT_FACTOR;
|
||||
|
||||
|
||||
surface.material.indirect = indirectDiffuse + indirectSpecular;
|
||||
// outFragColor.rgb = surface.material.indirect.rgb; return;
|
||||
|
||||
// deferred sampling doesn't have a blended albedo buffer
|
||||
// in place we'll just cone trace behind the window
|
||||
if ( surface.material.albedo.a < 1.0 ) {
|
||||
Ray ray;
|
||||
ray.direction = surface.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;
|
||||
}
|
||||
}
|
||||
67
belly/bin/data/shaders/display/bloom/comp.glsl
Normal file
67
belly/bin/data/shaders/display/bloom/comp.glsl
Normal file
@ -0,0 +1,67 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define COMPUTE 1
|
||||
#define TEXTURES 0
|
||||
#define CUBEMAPS 0
|
||||
#define BLOOM 1
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint eye;
|
||||
uint mode;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
float scale;
|
||||
float strength;
|
||||
float threshold;
|
||||
float sigma;
|
||||
|
||||
float gamma;
|
||||
float exposure;
|
||||
uint samples;
|
||||
uint padding;
|
||||
} ubo;
|
||||
|
||||
layout (binding = 1, rgba16f) uniform volatile coherent image2D imageColor;
|
||||
layout (binding = 2, rgba16f) uniform volatile coherent image2D imageBloom;
|
||||
layout (binding = 3, rgba16f) uniform volatile coherent image2D imagePingPong;
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
#include "../../common/functions.h"
|
||||
|
||||
void main() {
|
||||
const uint mode = PushConstant.mode;
|
||||
const ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||
const ivec2 size = imageSize( imageColor );
|
||||
if ( texel.x >= size.x || texel.y >= size.y ) return;
|
||||
|
||||
if ( mode == 0 ) { // fill bloom
|
||||
vec3 result = imageLoad( imageColor, texel ).rgb;
|
||||
float brightness = dot(result, vec3(0.2126, 0.7152, 0.0722));
|
||||
if ( brightness < ubo.threshold ) result = vec3(0, 0, 0);
|
||||
imageStore( imageBloom, texel, vec4( result, 1.0 ) );
|
||||
} else if ( mode == 1 ) { // bloom horizontal
|
||||
vec3 result = imageLoad( imageBloom, texel ).rgb * gauss( 0, ubo.sigma ) * ubo.strength;
|
||||
for( int i = 1; i < ubo.samples; ++i ) {
|
||||
result += imageLoad( imageBloom, texel + ivec2(i * ubo.scale, 0.0)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
result += imageLoad( imageBloom, texel - ivec2(i * ubo.scale, 0.0)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
}
|
||||
// write to PingPong
|
||||
imageStore( imagePingPong, texel, vec4( result, 1.0 ) );
|
||||
} else if ( mode == 2 ) { // bloom vertical
|
||||
vec3 result = imageLoad( imagePingPong, texel ).rgb * gauss( 0, ubo.sigma ) * ubo.strength;
|
||||
for( int i = 1; i < ubo.samples; ++i ) {
|
||||
result += imageLoad( imagePingPong, texel + ivec2(0.0, i * ubo.scale)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
result += imageLoad( imagePingPong, texel - ivec2(0.0, i * ubo.scale)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
}
|
||||
// write to Bloom
|
||||
imageStore( imageBloom, texel, vec4( result, 1.0 ) );
|
||||
} else if ( mode == 3 ) { // combine
|
||||
vec3 result = imageLoad( imageColor, texel ).rgb + imageLoad( imageBloom, texel ).rgb;
|
||||
imageStore( imageColor, texel, vec4( result, 1.0 ) );
|
||||
}
|
||||
}
|
||||
13
belly/bin/data/shaders/display/deferred/comp/comp.glsl
Normal file
13
belly/bin/data/shaders/display/deferred/comp/comp.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 0
|
||||
#define VXGI 0
|
||||
#define MULTISAMPLING 0
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
287
belly/bin/data/shaders/display/deferred/comp/comp.h
Normal file
287
belly/bin/data/shaders/display/deferred/comp/comp.h
Normal file
@ -0,0 +1,287 @@
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
||||
#if RT
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_EXT_ray_query : enable
|
||||
#endif
|
||||
|
||||
layout (local_size_x = 4, local_size_y = 4, local_size_z = 1) in;
|
||||
|
||||
#define COMPUTE 1
|
||||
#define DEFERRED 1
|
||||
#define DEFERRED_SAMPLING 1
|
||||
|
||||
#define PBR 1
|
||||
#define LAMBERT 0
|
||||
#if RT || BARYCENTRIC
|
||||
#define BUFFER_REFERENCE 0
|
||||
#define UINT64_ENABLED 0
|
||||
#endif
|
||||
#define FOG 1
|
||||
#define FOG_RAY_MARCH 1
|
||||
|
||||
#include "../../../common/macros.h"
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 512;
|
||||
layout (constant_id = 1) const uint CUBEMAPS = 128;
|
||||
#if VXGI
|
||||
layout (constant_id = 2) const uint CASCADES = 16;
|
||||
#endif
|
||||
|
||||
#if !MULTISAMPLING
|
||||
layout(binding = 0) uniform utexture2D samplerId;
|
||||
#if BARYCENTRIC
|
||||
#if !BARYCENTRIC_CALCULATE
|
||||
layout(binding = 1) uniform texture2D samplerBary;
|
||||
#endif
|
||||
#else
|
||||
layout(binding = 1) uniform texture2D samplerUv;
|
||||
layout(binding = 2) uniform texture2D samplerNormal;
|
||||
#endif
|
||||
layout(binding = 3) uniform texture2D samplerDepth;
|
||||
#else
|
||||
layout(binding = 0) uniform utexture2DMS samplerId;
|
||||
#if BARYCENTRIC
|
||||
#if !BARYCENTRIC_CALCULATE
|
||||
layout(binding = 1) uniform texture2DMS samplerBary;
|
||||
#endif
|
||||
#else
|
||||
layout(binding = 1) uniform texture2DMS samplerUv;
|
||||
layout(binding = 2) uniform texture2DMS samplerNormal;
|
||||
#endif
|
||||
layout(binding = 3) uniform texture2DMS samplerDepth;
|
||||
#endif
|
||||
|
||||
|
||||
layout(binding = 7, rgba16f) uniform volatile coherent image2D imageColor;
|
||||
layout(binding = 8, rgba16f) uniform volatile coherent image2D imageBright;
|
||||
layout(binding = 9, rg16f) uniform volatile coherent image2D imageMotion;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
#include "../../../common/structs.h"
|
||||
|
||||
layout (binding = 10) uniform UBO {
|
||||
EyeMatrices eyes[2];
|
||||
|
||||
Settings settings;
|
||||
} ubo;
|
||||
/*
|
||||
*/
|
||||
layout (std140, binding = 11) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 12) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
layout (std140, binding = 13) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
layout (std140, binding = 14) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 15) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 16) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout (binding = 17) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 18) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 19) uniform sampler3D samplerNoise;
|
||||
#if VXGI
|
||||
layout (binding = 20) uniform usampler3D voxelId[CASCADES];
|
||||
layout (binding = 21) uniform sampler3D voxelNormal[CASCADES];
|
||||
layout (binding = 22) uniform sampler3D voxelRadiance[CASCADES];
|
||||
#endif
|
||||
#if RT
|
||||
layout (binding = 23) uniform accelerationStructureEXT tlas;
|
||||
#endif
|
||||
|
||||
#if BUFFER_REFERENCE
|
||||
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[]; };
|
||||
#endif
|
||||
|
||||
#include "../../../common/functions.h"
|
||||
#include "../../../common/fog.h"
|
||||
#include "../../../common/light.h"
|
||||
#include "../../../common/shadows.h"
|
||||
#if VXGI
|
||||
#include "../../../common/vxgi.h"
|
||||
#endif
|
||||
|
||||
#if MULTISAMPLING
|
||||
#define IMAGE_LOAD(X) texelFetch( X, ivec2(gl_GlobalInvocationID.xy), msaa.currentID )
|
||||
#else
|
||||
#define IMAGE_LOAD(X) texelFetch( X, ivec2(gl_GlobalInvocationID.xy), 0 )
|
||||
#endif
|
||||
|
||||
#define IMAGE_STORE(X, Y) imageStore( X, ivec2(gl_GlobalInvocationID.xy), Y )
|
||||
|
||||
void postProcess() {
|
||||
#if FOG
|
||||
fog( surface.ray, surface.fragment.rgb, surface.fragment.a );
|
||||
#endif
|
||||
float brightness = dot(surface.fragment.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
bool bloom = brightness > ubo.settings.bloom.threshold;
|
||||
//if ( bloom ) toneMap( surface.fragment.rgb, brightness );
|
||||
vec4 outFragColor = vec4(surface.fragment.rgb, 1.0);
|
||||
vec4 outFragBright = bloom ? vec4(surface.fragment.rgb, 1.0) : vec4(0, 0, 0, 1);
|
||||
vec2 outFragMotion = surface.motion;
|
||||
|
||||
if ( ubo.settings.mode.type == 0x0001 ) {
|
||||
outFragColor = vec4(surface.material.albedo.rgb, 1);
|
||||
} else if ( ubo.settings.mode.type == 0x0002 ) {
|
||||
outFragColor = vec4(surface.normal.eye.rgb, 1);
|
||||
} else if ( ubo.settings.mode.type == 0x0003 ) {
|
||||
outFragColor = vec4(surface.uv.xy, 0, 1);
|
||||
} else if ( ubo.settings.mode.type == 0x0004 ) {
|
||||
outFragColor = vec4(surface.st.xy, 0, 1);
|
||||
}
|
||||
|
||||
IMAGE_STORE( imageColor, outFragColor );
|
||||
IMAGE_STORE( imageBright, outFragBright );
|
||||
IMAGE_STORE( imageMotion, vec4(outFragMotion, 0, 0) );
|
||||
}
|
||||
|
||||
void populateSurface() {
|
||||
uvec2 renderSize = imageSize(imageColor);
|
||||
if ( gl_GlobalInvocationID.x >= renderSize.x || gl_GlobalInvocationID.y >= renderSize.y || gl_GlobalInvocationID.z > PushConstant.pass ) return;
|
||||
|
||||
surface.fragment = vec4(0);
|
||||
surface.pass = PushConstant.pass;
|
||||
|
||||
{
|
||||
vec2 inUv = (vec2(gl_GlobalInvocationID.xy) / vec2(renderSize)) * 2.0f - 1.0f;
|
||||
const mat4 iProjectionView = inverse( ubo.eyes[surface.pass].projection * mat4(mat3(ubo.eyes[surface.pass].view)) );
|
||||
const vec4 near4 = iProjectionView * (vec4(inUv, -1.0, 1.0));
|
||||
const vec4 far4 = iProjectionView * (vec4(inUv, 1.0, 1.0));
|
||||
const vec3 near3 = near4.xyz / near4.w;
|
||||
const vec3 far3 = far4.xyz / far4.w;
|
||||
|
||||
surface.ray.direction = normalize( far3 - near3 );
|
||||
surface.ray.origin = /*near3.xyz;*/ ubo.eyes[surface.pass].eyePos.xyz;
|
||||
|
||||
const float depth = IMAGE_LOAD(samplerDepth).r;
|
||||
|
||||
vec4 eye = ubo.eyes[surface.pass].iProjection * vec4(inUv, depth, 1.0);
|
||||
eye /= eye.w;
|
||||
|
||||
surface.position.eye = eye.xyz;
|
||||
surface.position.world = vec3( ubo.eyes[surface.pass].iView * eye );
|
||||
}
|
||||
|
||||
#if !MULTISAMPLING
|
||||
const uvec2 ID = uvec2(IMAGE_LOAD(samplerId).xy);
|
||||
#else
|
||||
const uvec2 ID = msaa.IDs[msaa.currentID];
|
||||
#endif
|
||||
surface.motion = vec2(0);
|
||||
|
||||
if ( ID.x == 0 || ID.y == 0 ) {
|
||||
if ( 0 <= ubo.settings.lighting.indexSkybox && ubo.settings.lighting.indexSkybox < CUBEMAPS ) {
|
||||
surface.fragment.rgb = texture( samplerCubemaps[ubo.settings.lighting.indexSkybox], surface.ray.direction ).rgb;
|
||||
}
|
||||
surface.fragment.a = 0.0;
|
||||
return;
|
||||
}
|
||||
{
|
||||
const uint triangleID = ID.x - 1;
|
||||
const uint instanceID = ID.y - 1;
|
||||
surface.subID = 1;
|
||||
|
||||
#if BARYCENTRIC
|
||||
#if !BARYCENTRIC_CALCULATE
|
||||
surface.barycentric = decodeBarycentrics(IMAGE_LOAD(samplerBary).xy).xyz;
|
||||
#endif
|
||||
populateSurface( instanceID, triangleID );
|
||||
#else
|
||||
vec4 uvst = IMAGE_LOAD(samplerUv);
|
||||
vec4 normaltangent = IMAGE_LOAD(samplerNormal);
|
||||
|
||||
surface.uv.xy = uvst.xy;
|
||||
surface.uv.z = 0;
|
||||
surface.st.xy = uvst.zw;
|
||||
surface.st.z = 0;
|
||||
|
||||
surface.normal.world = decodeNormals(normaltangent.xy);
|
||||
// surface.tangent.world = decodeNormals(normaltangent.zw);
|
||||
|
||||
surface.fragment = vec4(0);
|
||||
surface.light = vec4(0);
|
||||
surface.instance = instances[instanceID];
|
||||
|
||||
populateSurfaceMaterial();
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
vec4 pNDC = ubo.eyes[surface.pass].previous * surface.instance.previous * vec4(surface.position.world, 1);
|
||||
vec4 cNDC = ubo.eyes[surface.pass].model * surface.instance.model * vec4(surface.position.world, 1);
|
||||
pNDC /= pNDC.w;
|
||||
cNDC /= cNDC.w;
|
||||
|
||||
surface.motion = cNDC.xy - pNDC.xy;
|
||||
}
|
||||
}
|
||||
|
||||
void directLighting() {
|
||||
surface.light.rgb += surface.material.albedo.rgb * ubo.settings.lighting.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;
|
||||
}
|
||||
|
||||
#if MULTISAMPLING
|
||||
void resolveSurfaceFragment() {
|
||||
for ( int i = 0; i < ubo.settings.mode.msaa; ++i ) {
|
||||
msaa.currentID = i;
|
||||
msaa.IDs[i] = uvec3(IMAGE_LOAD(samplerId)).xy;
|
||||
|
||||
// check if ID is already used
|
||||
bool unique = true;
|
||||
for ( int j = msaa.currentID - 1; j >= 0; --j ) {
|
||||
if ( msaa.IDs[j] == msaa.IDs[i] ) {
|
||||
surface.fragment = msaa.fragments[j];
|
||||
unique = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( unique ) {
|
||||
populateSurface();
|
||||
#if VXGI
|
||||
indirectLighting();
|
||||
#endif
|
||||
directLighting();
|
||||
}
|
||||
|
||||
msaa.fragment += surface.fragment;
|
||||
msaa.fragments[msaa.currentID] = surface.fragment;
|
||||
}
|
||||
|
||||
surface.fragment = msaa.fragment / ubo.settings.mode.msaa;
|
||||
}
|
||||
#endif
|
||||
13
belly/bin/data/shaders/display/deferred/comp/msaa.comp.glsl
Normal file
13
belly/bin/data/shaders/display/deferred/comp/msaa.comp.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 0
|
||||
#define VXGI 0
|
||||
#define MULTISAMPLING 1
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
resolveSurfaceFragment();
|
||||
|
||||
postProcess();
|
||||
}
|
||||
13
belly/bin/data/shaders/display/deferred/comp/rt.comp.glsl
Normal file
13
belly/bin/data/shaders/display/deferred/comp/rt.comp.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 460
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 1
|
||||
#define VXGI 0
|
||||
#define MULTISAMPLING 0
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
#version 460
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 1
|
||||
#define VXGI 0
|
||||
#define MULTISAMPLING 1
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
#version 460
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 1
|
||||
#define VXGI 1
|
||||
#define MULTISAMPLING 0
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
indirectLighting();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
#version 460
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 1
|
||||
#define VXGI 1
|
||||
#define MULTISAMPLING 1
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
14
belly/bin/data/shaders/display/deferred/comp/vxgi.comp.glsl
Normal file
14
belly/bin/data/shaders/display/deferred/comp/vxgi.comp.glsl
Normal file
@ -0,0 +1,14 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 0
|
||||
#define VXGI 1
|
||||
#define MULTISAMPLING 0
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
indirectLighting();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 0
|
||||
#define VXGI 1
|
||||
#define MULTISAMPLING 1
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
resolveSurfaceFragment();
|
||||
postProcess();
|
||||
}
|
||||
30
belly/bin/data/shaders/display/depth-pyramid/comp.glsl
Normal file
30
belly/bin/data/shaders/display/depth-pyramid/comp.glsl
Normal file
@ -0,0 +1,30 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
//#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
||||
layout (constant_id = 0) const uint MIPS = 6;
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
|
||||
#define COMPUTE 1
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint _;
|
||||
uint pass;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 3) uniform sampler2D inImage[MIPS];
|
||||
layout (binding = 4, r32f) uniform volatile coherent image2D outImage[MIPS];
|
||||
|
||||
void main() {
|
||||
vec2 imageSize = imageSize(outImage[PushConstant.pass]);
|
||||
uvec2 pos = gl_GlobalInvocationID.xy;
|
||||
if ( pos.x >= imageSize.x || pos.y >= imageSize.y ) return;
|
||||
|
||||
float depth = texture(inImage[PushConstant.pass], (vec2(pos) + vec2(0.5)) / imageSize).x;
|
||||
|
||||
imageStore(outImage[PushConstant.pass], ivec2(pos), vec4(depth));
|
||||
}
|
||||
35
belly/bin/data/shaders/display/renderTarget/frag.glsl
Normal file
35
belly/bin/data/shaders/display/renderTarget/frag.glsl
Normal file
@ -0,0 +1,35 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) flat in uint inPass;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
layout (binding = 0) uniform sampler2D samplerColor;
|
||||
|
||||
layout (binding = 1) uniform UBO {
|
||||
float curTime;
|
||||
float gamma;
|
||||
float exposure;
|
||||
uint padding;
|
||||
} ubo;
|
||||
|
||||
#define TONE_MAP 1
|
||||
#define GAMMA_CORRECT 1
|
||||
#define TEXTURES 1
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
#include "../../common/functions.h"
|
||||
|
||||
void main() {
|
||||
outColor = texture( samplerColor, inUv );
|
||||
#if TONE_MAP
|
||||
toneMap(outColor, ubo.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,392 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) flat in uint inPass;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
layout (binding = 0) uniform sampler2D samplerColor;
|
||||
|
||||
layout (binding = 1) uniform UBO {
|
||||
float curTime;
|
||||
float gamma;
|
||||
float exposure;
|
||||
uint padding;
|
||||
} ubo;
|
||||
|
||||
#define TONE_MAP 1
|
||||
#define GAMMA_CORRECT 1
|
||||
#define TEXTURES 1
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
#include "../../common/functions.h"
|
||||
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
const float u_imgx = 0;
|
||||
const float u_imgy = 0;
|
||||
const float u_imgw = 1;
|
||||
const float u_imgh = 1;
|
||||
const float u_img_gain = 2;
|
||||
const float u_img_bias = 0;
|
||||
const float u_beam_bias = 0.185;
|
||||
const float u_beam_gain = 0.25;
|
||||
const float u_corner = 0.05;
|
||||
const float u_zoom = 1.0;
|
||||
const float u_shape = 2;
|
||||
const float u_round = -0.02;
|
||||
const float u_grain = 0.4;
|
||||
const float u_vpitch = 936.1;
|
||||
const float u_hpitch = 1024.6;
|
||||
const float u_top = 1;
|
||||
const float u_bot = 1;
|
||||
|
||||
void main() {
|
||||
const vec2 screenResolution = textureSize( samplerColor, 0 );
|
||||
const float u_lines = screenResolution.y * 0.75;
|
||||
|
||||
vec2 uv_orig = (inUv.xy * 2.0 - 1.0);
|
||||
vec2 uv_mod = uv_orig * pow(1.0-abs(uv_orig),vec2(u_round)) * (u_zoom + u_corner * pow( abs(uv_orig.yx), vec2(u_shape)) );
|
||||
vec2 uv = uv_mod / 2.0 + 0.5;
|
||||
|
||||
if ( abs(uv_mod).x > 1.0 || abs(uv_mod.y) > 1.0 ) {
|
||||
outColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float spacing = 1.0/u_lines;
|
||||
uv+=spacing*0.5;
|
||||
|
||||
float line_top = ( ceil(uv.y*u_lines)) / u_lines;
|
||||
float line_bot = line_top - spacing;
|
||||
|
||||
vec2 scale = vec2(u_imgw, u_imgh);
|
||||
vec2 offset = vec2(u_imgx, u_imgy);
|
||||
|
||||
vec2 uv_top = (vec2(uv.x, line_top)+offset) * scale - (scale-1.0)*0.5 ;
|
||||
vec2 uv_bot = (vec2(uv.x, line_bot)+offset) * scale - (scale-1.0)*0.5 ;
|
||||
|
||||
uv_top -= spacing * 0.5;
|
||||
uv_bot -= spacing * 0.5;
|
||||
|
||||
vec4 sampled_top = texture(samplerColor, uv_top);
|
||||
vec4 sampled_bot = texture(samplerColor, uv_bot);
|
||||
|
||||
vec3 color_top = sampled_top.xyz * u_img_gain + u_img_bias;
|
||||
vec3 color_bot = sampled_bot.xyz * u_img_gain + u_img_bias;
|
||||
|
||||
float dist_top = pow(abs(uv.y - line_top), 1.0);
|
||||
float dist_bot = pow(abs(uv.y - line_bot), 1.0);
|
||||
|
||||
vec3 beam_top = 1.0 - (dist_top / (spacing * (color_top * u_beam_gain + u_beam_bias)));
|
||||
vec3 beam_bot = 1.0 - (dist_bot / (spacing * (color_bot * u_beam_gain + u_beam_bias)));
|
||||
|
||||
beam_top = clamp(beam_top, 0.0, 1.0) ;
|
||||
beam_bot = clamp(beam_bot, 0.0, 1.0) ;
|
||||
|
||||
vec3 color = (color_top*beam_top)*u_top + (color_bot*beam_bot)*u_bot;
|
||||
|
||||
vec2 dot;
|
||||
dot.y = floor(uv.y * u_vpitch) ;
|
||||
dot.x = uv.x;
|
||||
|
||||
if (mod(dot.y, 2.0) > 0.5)
|
||||
dot.x += (4.5/3.0) / u_hpitch;
|
||||
|
||||
dot.x = (floor(dot.x*u_hpitch)) ;
|
||||
|
||||
int fil = int(mod(dot.x, 3.0));
|
||||
|
||||
vec3 out_color = color * (1.0-u_grain);
|
||||
|
||||
vec3 passthru = vec3(
|
||||
float(fil == 0),
|
||||
float(fil == 1),
|
||||
float(fil == 2)
|
||||
) * (u_grain);
|
||||
|
||||
out_color += color * passthru;
|
||||
|
||||
outColor = vec4(out_color, (sampled_top.a + sampled_bot.a) * 0.5 );
|
||||
|
||||
#if TONE_MAP
|
||||
toneMap(outColor, ubo.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
float iTime = 0;
|
||||
float noise(vec2 p) {
|
||||
float s = (fract(sin(dot(p * sin( iTime * 0.5 ), vec2(12.9898,78.233)*2.0)) * 43758.5453)); // texture(iChannel1,vec2(1.,2.*cos(iTime))*iTime*8. + p*1.).x;
|
||||
s *= s;
|
||||
return s;
|
||||
}
|
||||
|
||||
float onOff(float a, float b, float c) {
|
||||
return step(c, sin(iTime + a*cos(iTime*b)));
|
||||
}
|
||||
|
||||
float ramp(float y, float start, float end) {
|
||||
float inside = step(start,y) - step(end,y);
|
||||
float fact = (y-start)/(end-start)*inside;
|
||||
return (1.-fact) * inside;
|
||||
|
||||
}
|
||||
|
||||
float stripes(vec2 uv) {
|
||||
float noi = noise(uv*vec2(0.5,1.) + vec2(1.,3.));
|
||||
return ramp(mod(uv.y*4. + iTime/2.+sin(iTime + sin(iTime*0.63)),1.),0.5,0.6)*noi;
|
||||
}
|
||||
|
||||
vec4 getVideo(vec2 uv) {
|
||||
vec2 look = uv;
|
||||
float window = 1./(1.+20.*(look.y-mod(iTime/4.,1.))*(look.y-mod(iTime/4.,1.)));
|
||||
look.x = look.x + sin(look.y*10. + iTime)/50.*onOff(4.,4.,.3)*(1.+cos(iTime*80.))*window;
|
||||
float vShift = 0.4*onOff(2.,3.,.9)*(sin(iTime)*sin(iTime*20.) +
|
||||
(0.5 + 0.1*sin(iTime*200.)*cos(iTime)));
|
||||
look.y = mod(look.y + vShift, 1.);
|
||||
return texture(samplerColor,look);
|
||||
}
|
||||
|
||||
vec2 screenDistort(vec2 uv) {
|
||||
uv -= vec2(.5,.5);
|
||||
uv = uv*1.2*(1./1.2+2.*uv.x*uv.x*uv.y*uv.y);
|
||||
uv += vec2(.5,.5);
|
||||
return uv;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = inUv.xy; // fragCoord.xy / iResolution.xy;
|
||||
iTime = ubo.curTime;
|
||||
|
||||
uv = screenDistort(uv);
|
||||
vec4 video = getVideo(uv);
|
||||
float vigAmt = 3.+.3*sin(iTime + 5.*cos(iTime*5.));
|
||||
float vignette = (1.-vigAmt*(uv.y-.5)*(uv.y-.5))*(1.-vigAmt*(uv.x-.5)*(uv.x-.5));
|
||||
|
||||
video.rgb += stripes(uv);
|
||||
video.rgb += noise(uv*2.)/4.;
|
||||
video.rgb *= vignette;
|
||||
video.rgb *= (12.+mod(uv.y*30.+iTime,1.))/13.;
|
||||
|
||||
outColor = video;
|
||||
#if TONE_MAP
|
||||
toneMap(outColor, ubo.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
vec2 curveRemapUV(vec2 uv, vec2 curvature) {
|
||||
uv = uv * 2.0 - 1.0;
|
||||
vec2 offset = abs(uv.yx) / vec2(curvature.x, curvature.y);
|
||||
uv = uv + uv * offset * offset;
|
||||
uv = uv * 0.5 + 0.5;
|
||||
return uv;
|
||||
}
|
||||
|
||||
vec4 scanLineIntensity(float uv, float resolution, float opacity) {
|
||||
float intensity = sin(uv * resolution * PI * 2.0);
|
||||
intensity = ((0.5 * intensity) + 0.5) * 0.9 + 0.1;
|
||||
return vec4(vec3(pow(intensity, opacity)), 1.0);
|
||||
}
|
||||
|
||||
vec4 vignetteIntensity(vec2 uv, vec2 resolution, float opacity, float roundness) {
|
||||
float intensity = uv.x * uv.y * (1.0 - uv.x) * (1.0 - uv.y);
|
||||
return vec4(vec3(clamp(pow((resolution.x / roundness) * intensity, opacity), 0.0, 1.0)), 1.0);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
const vec2 screenResolution = textureSize( samplerColor, 0 );
|
||||
const vec2 scanLineOpacity = vec2(0.5);
|
||||
const float brightness = 2;
|
||||
const float vignetteOpacity = 0.5;
|
||||
const float vignetteRoundness = 0.5;
|
||||
const vec2 curvature = vec2(8);
|
||||
|
||||
const vec2 remappedUV = curveRemapUV(vec2(inUv.x, inUv.y), curvature);
|
||||
vec4 baseColor = texture(samplerColor, remappedUV);
|
||||
|
||||
baseColor *= vignetteIntensity(remappedUV, screenResolution, vignetteOpacity, vignetteRoundness);
|
||||
|
||||
baseColor *= scanLineIntensity(remappedUV.x, screenResolution.y, scanLineOpacity.x);
|
||||
baseColor *= scanLineIntensity(remappedUV.y, screenResolution.x, scanLineOpacity.y);
|
||||
|
||||
baseColor *= vec4(vec3(brightness), 1.0);
|
||||
|
||||
if (remappedUV.x < 0.0 || remappedUV.y < 0.0 || remappedUV.x > 1.0 || remappedUV.y > 1.0){
|
||||
outColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
} else {
|
||||
outColor = baseColor;
|
||||
}
|
||||
|
||||
#if TONE_MAP
|
||||
toneMap(outColor, ubo.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
vec2 fragCoord = vec2(0,0);
|
||||
vec2 iResolution = vec2(640,480);
|
||||
|
||||
// Emulated input resolution.
|
||||
#if 0
|
||||
// Fix resolution to set amount.
|
||||
#define res (vec2(320.0/1.0,160.0/1.0))
|
||||
#else
|
||||
// Optimize for resize.
|
||||
#define res (iResolution.xy/6.0)
|
||||
#endif
|
||||
|
||||
// Hardness of scanline.
|
||||
// -8.0 = soft
|
||||
// -16.0 = medium
|
||||
float hardScan=-8.0;
|
||||
|
||||
// Hardness of pixels in scanline.
|
||||
// -2.0 = soft
|
||||
// -4.0 = hard
|
||||
float hardPix=-3.0;
|
||||
|
||||
// Display warp.
|
||||
// 0.0 = none
|
||||
// 1.0/8.0 = extreme
|
||||
vec2 warp=vec2(1.0/32.0,1.0/24.0);
|
||||
|
||||
// Amount of shadow mask.
|
||||
float maskDark=0.5;
|
||||
float maskLight=1.5;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// sRGB to Linear.
|
||||
// Assuing using sRGB typed textures this should not be needed.
|
||||
float ToLinear1(float c){return(c<=0.04045)?c/12.92:pow((c+0.055)/1.055,2.4);}
|
||||
vec3 ToLinear(vec3 c){return vec3(ToLinear1(c.r),ToLinear1(c.g),ToLinear1(c.b));}
|
||||
|
||||
// Linear to sRGB.
|
||||
// Assuing using sRGB typed textures this should not be needed.
|
||||
float ToSrgb1(float c){return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);}
|
||||
vec3 ToSrgb(vec3 c){return vec3(ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));}
|
||||
|
||||
// Nearest emulated sample given floating point position and texel offset.
|
||||
// Also zero's off screen.
|
||||
vec3 Fetch(vec2 pos,vec2 off){
|
||||
pos=floor(pos*res+off)/res;
|
||||
if(max(abs(pos.x-0.5),abs(pos.y-0.5))>0.5)return vec3(0.0,0.0,0.0);
|
||||
return ToLinear(texture(samplerColor,pos.xy,-16.0).rgb);}
|
||||
|
||||
// Distance in emulated pixels to nearest texel.
|
||||
vec2 Dist(vec2 pos){pos=pos*res;return -((pos-floor(pos))-vec2(0.5));}
|
||||
|
||||
// 1D Gaussian.
|
||||
float Gaus(float pos,float scale){return exp2(scale*pos*pos);}
|
||||
|
||||
// 3-tap Gaussian filter along horz line.
|
||||
vec3 Horz3(vec2 pos,float off){
|
||||
vec3 b=Fetch(pos,vec2(-1.0,off));
|
||||
vec3 c=Fetch(pos,vec2( 0.0,off));
|
||||
vec3 d=Fetch(pos,vec2( 1.0,off));
|
||||
float dst=Dist(pos).x;
|
||||
// Convert distance to weight.
|
||||
float scale=hardPix;
|
||||
float wb=Gaus(dst-1.0,scale);
|
||||
float wc=Gaus(dst+0.0,scale);
|
||||
float wd=Gaus(dst+1.0,scale);
|
||||
// Return filtered sample.
|
||||
return (b*wb+c*wc+d*wd)/(wb+wc+wd);}
|
||||
|
||||
// 5-tap Gaussian filter along horz line.
|
||||
vec3 Horz5(vec2 pos,float off){
|
||||
vec3 a=Fetch(pos,vec2(-2.0,off));
|
||||
vec3 b=Fetch(pos,vec2(-1.0,off));
|
||||
vec3 c=Fetch(pos,vec2( 0.0,off));
|
||||
vec3 d=Fetch(pos,vec2( 1.0,off));
|
||||
vec3 e=Fetch(pos,vec2( 2.0,off));
|
||||
float dst=Dist(pos).x;
|
||||
// Convert distance to weight.
|
||||
float scale=hardPix;
|
||||
float wa=Gaus(dst-2.0,scale);
|
||||
float wb=Gaus(dst-1.0,scale);
|
||||
float wc=Gaus(dst+0.0,scale);
|
||||
float wd=Gaus(dst+1.0,scale);
|
||||
float we=Gaus(dst+2.0,scale);
|
||||
// Return filtered sample.
|
||||
return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);}
|
||||
|
||||
// Return scanline weight.
|
||||
float Scan(vec2 pos,float off){
|
||||
float dst=Dist(pos).y;
|
||||
return Gaus(dst+off,hardScan);}
|
||||
|
||||
// Allow nearest three lines to effect pixel.
|
||||
vec3 Tri(vec2 pos){
|
||||
vec3 a=Horz3(pos,-1.0);
|
||||
vec3 b=Horz5(pos, 0.0);
|
||||
vec3 c=Horz3(pos, 1.0);
|
||||
float wa=Scan(pos,-1.0);
|
||||
float wb=Scan(pos, 0.0);
|
||||
float wc=Scan(pos, 1.0);
|
||||
return a*wa+b*wb+c*wc;}
|
||||
|
||||
// Distortion of scanlines, and end of screen alpha.
|
||||
vec2 Warp(vec2 pos){
|
||||
pos=pos*2.0-1.0;
|
||||
pos*=vec2(1.0+(pos.y*pos.y)*warp.x,1.0+(pos.x*pos.x)*warp.y);
|
||||
return pos*0.5+0.5;}
|
||||
|
||||
// Shadow mask.
|
||||
vec3 Mask(vec2 pos){
|
||||
pos.x+=pos.y*3.0;
|
||||
vec3 mask=vec3(maskDark,maskDark,maskDark);
|
||||
pos.x=fract(pos.x/6.0);
|
||||
if(pos.x<0.333)mask.r=maskLight;
|
||||
else if(pos.x<0.666)mask.g=maskLight;
|
||||
else mask.b=maskLight;
|
||||
return mask;}
|
||||
|
||||
void main() {
|
||||
iResolution = textureSize( samplerColor, 0 );
|
||||
fragCoord = inUv * iResolution;
|
||||
|
||||
vec2 pos = Warp(fragCoord.xy / iResolution.xy);
|
||||
|
||||
hardScan = -12.0;
|
||||
maskDark = maskLight = 1.0;
|
||||
|
||||
outColor.rgb = Tri(pos) * Mask(fragCoord.xy);
|
||||
outColor.rgb = ToSrgb(outColor.rgb);
|
||||
outColor.a = 1.0;
|
||||
|
||||
#if TONE_MAP
|
||||
toneMap(outColor, ubo.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
void main() {
|
||||
const vec2 uv = 0.025 * sin( ubo.curTime ) * inUv.xy;
|
||||
const float mdf = 0.5;
|
||||
const float noise = (fract(sin(dot(uv, vec2(12.9898,78.233)*2.0)) * 43758.5453));
|
||||
const vec4 sampled = texture( samplerColor, inUv );
|
||||
|
||||
outColor = sampled - noise * mdf;
|
||||
|
||||
toneMap(outColor, ubo.exposure);
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
}
|
||||
#endif
|
||||
16
belly/bin/data/shaders/display/renderTarget/vert.glsl
Normal file
16
belly/bin/data/shaders/display/renderTarget/vert.glsl
Normal file
@ -0,0 +1,16 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out flat uint outPass;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
void main() {
|
||||
outUv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
outPass = PushConstant.pass;
|
||||
gl_Position = vec4(outUv * 2.0f + -1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
148
belly/bin/data/shaders/display/vxgi/comp.glsl
Normal file
148
belly/bin/data/shaders/display/vxgi/comp.glsl
Normal file
@ -0,0 +1,148 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
||||
|
||||
#define COMPUTE 1
|
||||
|
||||
#define VXGI 1
|
||||
#define MAX_CUBEMAPS CUBEMAPS
|
||||
#define GAMMA_CORRECT 1
|
||||
#define PBR 1
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 512;
|
||||
layout (constant_id = 1) const uint CUBEMAPS = 128;
|
||||
layout (constant_id = 2) const uint CASCADES = 16;
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
EyeMatrices eyes[2];
|
||||
|
||||
Settings settings;
|
||||
} ubo;
|
||||
layout (std140, binding = 1) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 2) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
layout (std140, binding = 3) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
layout (std140, binding = 4) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 5) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 6) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout (binding = 7) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 8) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 9) uniform sampler3D samplerNoise;
|
||||
|
||||
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 = 12, rgba32f) uniform volatile coherent image3D voxelRadiance[CASCADES];
|
||||
#else
|
||||
layout (binding = 12, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES];
|
||||
#endif
|
||||
|
||||
#include "../../common/functions.h"
|
||||
#include "../../common/light.h"
|
||||
#undef VXGI //
|
||||
#include "../../common/shadows.h"
|
||||
void main() {
|
||||
const vec3 tUvw = gl_GlobalInvocationID.xzy;
|
||||
for ( uint CASCADE = 0; CASCADE < CASCADES; ++CASCADE ) {
|
||||
surface.normal.world = decodeNormals( vec2(imageLoad(voxelNormal[CASCADE], ivec3(tUvw) ).xy) );
|
||||
surface.normal.eye = vec3( ubo.settings.vxgi.matrix * vec4( surface.normal.world, 0.0f ) );
|
||||
|
||||
surface.position.eye = (vec3(gl_GlobalInvocationID.xyz) / vec3(imageSize(voxelRadiance[CASCADE])) * 2.0f - 1.0f) * cascadePower(CASCADE);
|
||||
surface.position.world = vec3( inverse(ubo.settings.vxgi.matrix) * vec4( surface.position.eye, 1.0f ) );
|
||||
|
||||
const uvec2 ID = uvec2(imageLoad(voxelId[CASCADE], ivec3(tUvw) ).xy);
|
||||
const uint drawID = ID.x - 1;
|
||||
const uint instanceID = ID.y - 1;
|
||||
if ( ID.x == 0 || ID.y == 0 ) {
|
||||
imageStore(voxelRadiance[CASCADE], ivec3(tUvw), vec4(0));
|
||||
continue;
|
||||
}
|
||||
const DrawCommand drawCommand = drawCommands[drawID];
|
||||
surface.instance = instances[instanceID];
|
||||
const Material material = materials[surface.instance.materialID];
|
||||
surface.material.albedo = material.colorBase;
|
||||
surface.fragment = material.colorEmissive;
|
||||
|
||||
surface.material.albedo = imageLoad(voxelRadiance[CASCADE], ivec3(tUvw) );
|
||||
surface.material.metallic = material.factorMetallic;
|
||||
surface.material.roughness = material.factorRoughness;
|
||||
surface.material.occlusion = material.factorOcclusion;
|
||||
|
||||
const vec3 ambient = ubo.settings.lighting.ambient.rgb * surface.material.occlusion;
|
||||
if ( validTextureIndex( surface.instance.lightmapID ) ) {
|
||||
surface.fragment.rgb += surface.material.albedo.rgb;
|
||||
} else {
|
||||
surface.fragment.rgb += surface.material.albedo.rgb * ambient;
|
||||
// corrections
|
||||
surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4( surface.position.world, 1 ) );
|
||||
surface.normal.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0) );
|
||||
pbr();
|
||||
/*
|
||||
surface.material.roughness *= 4.0;
|
||||
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
|
||||
const vec3 Lo = normalize( surface.position.world );
|
||||
const float cosLo = max(0.0, dot(surface.normal.world, Lo));
|
||||
for ( uint i = 0; i < ubo.settings.lengths.lights; ++i ) {
|
||||
const Light light = lights[i];
|
||||
if ( light.power <= LIGHT_POWER_CUTOFF ) continue;
|
||||
if ( light.type >= 0 && validTextureIndex( surface.instance.lightmapID ) ) continue;
|
||||
const vec3 Lp = light.position;
|
||||
const vec3 Liu = light.position - surface.position.world;
|
||||
const vec3 Li = normalize(Liu);
|
||||
const float Ls = shadowFactor( light, 0.0 );
|
||||
const float La = 1.0 / (1 + (PI * pow(length(Liu), 2.0)));
|
||||
if ( light.power * La * Ls <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const float cosLi = max(0.0, dot(surface.normal.world, Li));
|
||||
const vec3 Lr = light.color.rgb * light.power * La * Ls;
|
||||
#if LAMBERT
|
||||
const vec3 diffuse = surface.material.albedo.rgb;
|
||||
const vec3 specular = vec3(0);
|
||||
#elif PBR
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
const float cosLh = max(0.0, dot(surface.normal.world, Lh));
|
||||
|
||||
const vec3 F = fresnelSchlick( F0, max( 0.0, dot(Lh, Lo) ) );
|
||||
const float D = ndfGGX( cosLh, surface.material.roughness );
|
||||
const float G = gaSchlickGGX(cosLi, cosLo, surface.material.roughness);
|
||||
const vec3 diffuse = mix( vec3(1.0) - F, vec3(0.0), surface.material.metallic ) * surface.material.albedo.rgb;
|
||||
const vec3 specular = (F * D * G) / max(EPSILON, 4.0 * cosLi * cosLo);
|
||||
#endif
|
||||
// lightmapped, compute only specular
|
||||
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
surface.light.a += light.power * La * Ls;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
surface.fragment.rgb += surface.light.rgb;
|
||||
|
||||
#if TONE_MAP
|
||||
toneMap(surface.fragment.rgb, ubo.settings.bloom.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(surface.fragment.rgb, 1.0 / ubo.settings.bloom.gamma);
|
||||
#endif
|
||||
|
||||
imageStore(voxelRadiance[CASCADE], ivec3(tUvw), vec4(surface.fragment.rgb, surface.material.albedo.a));
|
||||
}
|
||||
}
|
||||
67
belly/bin/data/shaders/display/vxgi/mip.gaussian.comp.glsl
Normal file
67
belly/bin/data/shaders/display/vxgi/mip.gaussian.comp.glsl
Normal file
@ -0,0 +1,67 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
||||
|
||||
layout (constant_id = 0) const uint CASCADES = 16;
|
||||
layout (constant_id = 1) const uint MIPS = 16;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint cascade;
|
||||
uint mip;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 1, rg16f) uniform volatile coherent image3D voxelRadiance[CASCADES * MIPS];
|
||||
|
||||
const float gaussianWeights[] = {
|
||||
//Top slice
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
|
||||
//Center slice
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 4.0f,
|
||||
1 / 16.0f,
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 32.0f,
|
||||
|
||||
//Bottom slice
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
};
|
||||
|
||||
void main() {
|
||||
const ivec3 inUVW = ivec3(gl_GlobalInvocationID.xyz) * 2;
|
||||
const ivec3 outUVW = ivec3(gl_GlobalInvocationID.xyz);
|
||||
const uint CASCADE_IN = PushConstant.cascade * CASCADES + PushConstant.mip;
|
||||
const uint CASCADE_OUT = PushConstant.cascade * CASCADES + (PushConstant.mip + 1);
|
||||
|
||||
vec4 color = vec4(0);
|
||||
for ( int z = -1; z <= 1; ++z ) {
|
||||
for ( int y = -1; y <= 1; ++y ) {
|
||||
for ( int x = -1; x <= 1; ++x ) {
|
||||
color += imageLoad( voxelRadiance[CASCADE_IN], inUVW + ivec3(x,y,z) ) * gaussianWeights[x + 1 + (y + 1) * 3 + (z + 1) * 9];
|
||||
}
|
||||
}
|
||||
}
|
||||
imageStore(voxelRadiance[CASCADE_OUT], ivec3(outUVW), vec4(color));
|
||||
}
|
||||
5
belly/bin/data/shaders/graph/baking/frag.glsl
Normal file
5
belly/bin/data/shaders/graph/baking/frag.glsl
Normal file
@ -0,0 +1,5 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
#define RT 0
|
||||
#include "./frag.h"
|
||||
204
belly/bin/data/shaders/graph/baking/frag.h
Normal file
204
belly/bin/data/shaders/graph/baking/frag.h
Normal file
@ -0,0 +1,204 @@
|
||||
//#extension GL_EXT_nonuniform_qualifier : enable
|
||||
#if RT
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_EXT_ray_query : enable
|
||||
#endif
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 512;
|
||||
layout (constant_id = 1) const uint CUBEMAPS = 128;
|
||||
layout (constant_id = 2) const uint LAYERS = 32;
|
||||
|
||||
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 6) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
|
||||
#define SHADOW_SAMPLES 16
|
||||
#define FRAGMENT 1
|
||||
#define BAKING 1
|
||||
#define PBR 1
|
||||
#define MAX_LIGHTS min(ubo.lights, lights.length())
|
||||
#define MAX_SHADOWS MAX_LIGHTS
|
||||
#define VIEW_MATRIX camera.viewport[0].view
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout (binding = 7) uniform Camera {
|
||||
Viewport viewport[6];
|
||||
} camera;
|
||||
|
||||
layout (binding = 8) uniform UBO {
|
||||
uint lights;
|
||||
uint currentID;
|
||||
uint padding1;
|
||||
uint padding2;
|
||||
} ubo;
|
||||
|
||||
layout (std140, binding = 9) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 10) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
layout (std140, binding = 11) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
layout (std140, binding = 12) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 13) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 14) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout (binding = 15, rgba8) uniform volatile coherent image3D outAlbedos;
|
||||
|
||||
#if RT
|
||||
layout (binding = 16) uniform accelerationStructureEXT tlas;
|
||||
#endif
|
||||
|
||||
#include "../../common/functions.h"
|
||||
#if RT
|
||||
float shadowFactor( const Light light, float def ) {
|
||||
Ray ray;
|
||||
ray.origin = surface.position.world;
|
||||
ray.direction = light.position - ray.origin;
|
||||
|
||||
float tMin = 0.001;
|
||||
float tMax = length(ray.direction) + tMin;
|
||||
|
||||
ray.direction = normalize(ray.direction);
|
||||
|
||||
uint rayFlags = gl_RayFlagsOpaqueEXT | gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsSkipClosestHitShaderEXT;
|
||||
uint cullMask = 0xFF;
|
||||
|
||||
rayQueryEXT rayQuery;
|
||||
rayQueryInitializeEXT(rayQuery, tlas, rayFlags, cullMask, ray.origin, tMin, ray.direction, tMax);
|
||||
|
||||
while(rayQueryProceedEXT(rayQuery)) {}
|
||||
|
||||
return rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionNoneEXT ? 1.0 : 0.0;
|
||||
}
|
||||
#else
|
||||
#include "../../common/shadows.h"
|
||||
#endif
|
||||
|
||||
#include "../../common/light.h"
|
||||
|
||||
layout (location = 0) flat in uvec4 inId;
|
||||
layout (location = 1) flat in vec4 inPOS0;
|
||||
layout (location = 2) in vec4 inPOS1;
|
||||
layout (location = 3) in vec3 inPosition;
|
||||
layout (location = 4) in vec2 inUv;
|
||||
layout (location = 5) in vec4 inColor;
|
||||
layout (location = 6) in vec2 inSt;
|
||||
layout (location = 7) in vec3 inNormal;
|
||||
layout (location = 8) in vec3 inTangent;
|
||||
|
||||
layout (location = 0) out vec4 outAlbedo;
|
||||
|
||||
void main() {
|
||||
const uint triangleID = uint(inId.x); // gl_PrimitiveID
|
||||
const uint drawID = uint(inId.y);
|
||||
const uint instanceID = uint(inId.z);
|
||||
|
||||
if ( instanceID != ubo.currentID ) discard;
|
||||
|
||||
surface.uv.xy = wrap(inUv.xy);
|
||||
surface.uv.z = mipLevel(dFdx(inUv), dFdy(inUv));
|
||||
|
||||
surface.position.world = inPosition;
|
||||
surface.normal.world = inNormal;
|
||||
|
||||
const DrawCommand drawCommand = drawCommands[drawID];
|
||||
const Instance instance = instances[instanceID];
|
||||
const Material material = materials[instance.materialID];
|
||||
|
||||
const uint mapID = instance.auxID;
|
||||
|
||||
vec4 A = material.colorBase;
|
||||
surface.material.metallic = material.factorMetallic;
|
||||
surface.material.roughness = material.factorRoughness;
|
||||
surface.material.occlusion = 1.0f - material.factorOcclusion;
|
||||
|
||||
#if 0
|
||||
vec3 N = inNormal;
|
||||
vec3 T = inTangent;
|
||||
T = normalize(T - dot(T, N) * N);
|
||||
vec3 B = cross(T, N);
|
||||
mat3 TBN = mat3(T, B, N);
|
||||
// mat3 TBN = mat3(N, B, T);
|
||||
if ( T != vec3(0) && validTextureIndex( material.indexNormal ) ) {
|
||||
surface.normal.world = TBN * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - 1.0 );
|
||||
} else {
|
||||
surface.normal.world = N;
|
||||
}
|
||||
#endif
|
||||
|
||||
surface.light = material.colorEmissive;
|
||||
surface.material.albedo = vec4(1);
|
||||
{
|
||||
surface.normal.eye = surface.normal.eye;
|
||||
surface.position.eye = surface.position.eye;
|
||||
// pbr();
|
||||
|
||||
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
|
||||
for ( uint i = 0; i < min(ubo.lights, lights.length()); ++i ) {
|
||||
const Light light = lights[i];
|
||||
|
||||
if ( light.type <= 0 ) continue;
|
||||
|
||||
const mat4 mat = light.view; // inverse(light.view);
|
||||
const vec3 position = surface.position.world;
|
||||
// const vec3 position = vec3( mat * vec4(surface.position.world, 1.0) );
|
||||
const vec3 normal = surface.normal.world;
|
||||
// const vec3 normal = vec3( mat * vec4(surface.normal.world, 0.0) );
|
||||
|
||||
if ( light.power <= LIGHT_POWER_CUTOFF ) continue;
|
||||
const vec3 Lp = light.position;
|
||||
const vec3 Liu = light.position - surface.position.world;
|
||||
const float La = 1.0 / (1 + PI * pow(length(Liu), 2.0));
|
||||
const float Ls = shadowFactor( light, 0.0 );
|
||||
if ( light.power * La * Ls <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const vec3 Lo = normalize( -position );
|
||||
const float cosLo = max(0.0, abs(dot(normal, Lo)));
|
||||
|
||||
const vec3 Li = normalize(Liu);
|
||||
const vec3 Lr = light.color.rgb * light.power * La * Ls;
|
||||
// const float cosLi = max(0.0, dot(normal, Li));
|
||||
const float cosLi = abs(dot(normal, Li));
|
||||
#if LAMBERT
|
||||
const vec3 diffuse = surface.material.albedo.rgb;
|
||||
const vec3 specular = vec3(0);
|
||||
#elif PBR
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
// const float cosLh = max(0.0, dot(normal, Lh));
|
||||
const float cosLh = abs(dot(normal, Lh));
|
||||
|
||||
const vec3 F = fresnelSchlick( F0, max( 0.0, dot(Lh, Lo) ) );
|
||||
const float D = 1; // ndfGGX( cosLh, surface.material.roughness );
|
||||
const float G = gaSchlickGGX(cosLi, cosLo, surface.material.roughness);
|
||||
const vec3 diffuse = mix( vec3(1.0) - F, vec3(0.0), surface.material.metallic ) * surface.material.albedo.rgb;
|
||||
const vec3 specular = (F * D * G) / max(EPSILON, 4.0 * cosLi * cosLo);
|
||||
#endif
|
||||
|
||||
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
surface.light.a += light.power * La * Ls;
|
||||
}
|
||||
}
|
||||
#define EXPOSURE 0
|
||||
#define GAMMA 0
|
||||
|
||||
// surface.light.rgb = vec3(1.0) - exp(-surface.light.rgb * EXPOSURE);
|
||||
// surface.light.rgb = pow(surface.light.rgb, vec3(1.0 / GAMMA));
|
||||
|
||||
outAlbedo = vec4(surface.light.rgb, 1);
|
||||
|
||||
{
|
||||
const vec2 st = inSt.xy * imageSize(outAlbedos).xy;
|
||||
const ivec3 uvw = ivec3(int(st.x), int(st.y), int(mapID));
|
||||
imageStore(outAlbedos, uvw, vec4(surface.light.rgb, 1) );
|
||||
}
|
||||
}
|
||||
5
belly/bin/data/shaders/graph/baking/rt.frag.glsl
Normal file
5
belly/bin/data/shaders/graph/baking/rt.frag.glsl
Normal file
@ -0,0 +1,5 @@
|
||||
#version 460
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
#define RT 1
|
||||
#include "./frag.h"
|
||||
8
belly/bin/data/shaders/graph/baking/vert.glsl
Normal file
8
belly/bin/data/shaders/graph/baking/vert.glsl
Normal file
@ -0,0 +1,8 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define INSTANCED 1
|
||||
#define SKINNED 0
|
||||
#define BAKING 1
|
||||
|
||||
#include "../base/vert.h"
|
||||
126
belly/bin/data/shaders/graph/base/frag.glsl
Normal file
126
belly/bin/data/shaders/graph/base/frag.glsl
Normal file
@ -0,0 +1,126 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
//#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
||||
#define FRAGMENT 1
|
||||
#define CAN_DISCARD 1
|
||||
|
||||
#define MAX_TEXTURES textures.length()
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 1;
|
||||
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
#if BARYCENTRIC && !BARYCENTRIC_CALCULATE
|
||||
#define BARYCENTRIC_STABILIZE 1
|
||||
// #define BARY_COORD gl_BaryCoordEXT
|
||||
// #extension GL_EXT_fragment_shader_barycentric : enable
|
||||
#define BARY_COORD gl_BaryCoordSmoothAMD
|
||||
#extension GL_AMD_shader_explicit_vertex_parameter : enable
|
||||
#endif
|
||||
|
||||
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (std140, binding = 6) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 7) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
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[];
|
||||
};
|
||||
|
||||
#include "../../common/functions.h"
|
||||
|
||||
layout (location = 0) flat in uvec4 inId;
|
||||
layout (location = 1) flat in vec4 inPOS0;
|
||||
#if BARYCENTRIC_STABILIZE
|
||||
layout (location = 2) __explicitInterpAMD in vec4 inPOS1;
|
||||
#else
|
||||
layout (location = 2) in vec4 inPOS1;
|
||||
#endif
|
||||
layout (location = 3) in vec3 inPosition;
|
||||
layout (location = 4) in vec2 inUv;
|
||||
layout (location = 5) in vec4 inColor;
|
||||
layout (location = 6) in vec2 inSt;
|
||||
layout (location = 7) in vec3 inNormal;
|
||||
layout (location = 8) in vec3 inTangent;
|
||||
|
||||
layout (location = 0) out uvec2 outId;
|
||||
#if BARYCENTRIC
|
||||
layout (location = 1) out vec2 outBary;
|
||||
#else
|
||||
layout (location = 1) out vec4 outUv;
|
||||
layout (location = 2) out vec4 outNormal;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
const uint triangleID = gl_PrimitiveID; // uint(inId.x);
|
||||
const uint drawID = uint(inId.y);
|
||||
const uint instanceID = uint(inId.z);
|
||||
|
||||
#if CAN_DISCARD
|
||||
const DrawCommand drawCommand = drawCommands[drawID];
|
||||
const Instance instance = instances[instanceID];
|
||||
const Material material = materials[instance.materialID];
|
||||
|
||||
surface.uv.xy = wrap(inUv.xy);
|
||||
surface.uv.z = mipLevel(dFdx(inUv), dFdy(inUv));
|
||||
|
||||
surface.st.xy = wrap(inSt.xy);
|
||||
surface.st.z = mipLevel(dFdx(inSt), dFdy(inSt));
|
||||
|
||||
vec4 A = inColor * material.colorBase;
|
||||
// sample albedo
|
||||
if ( validTextureIndex( material.indexAlbedo ) ) {
|
||||
A = sampleTexture( material.indexAlbedo );
|
||||
}
|
||||
// alpha mode OPAQUE
|
||||
if ( material.modeAlpha == 0 ) {
|
||||
A.a = 1;
|
||||
// alpha mode BLEND
|
||||
} else if ( material.modeAlpha == 1 ) {
|
||||
|
||||
// alpha mode MASK
|
||||
} else if ( material.modeAlpha == 2 ) {
|
||||
if ( A.a < abs(material.factorAlphaCutoff) ) discard;
|
||||
A.a = 1;
|
||||
}
|
||||
if ( A.a < 0.0001 ) discard;
|
||||
|
||||
#if !BARYCENTRIC
|
||||
outUv = vec4(surface.uv, surface.st);
|
||||
outNormal = vec4( encodeNormals(inNormal), encodeNormals(inTangent) );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
outId = uvec2(triangleID + 1, instanceID + 1);
|
||||
|
||||
#if BARYCENTRIC && !BARYCENTRIC_CALCULATE
|
||||
vec3 bary = vec3(gl_BaryCoordSmoothAMD.xy, 1 - gl_BaryCoordSmoothAMD.x - gl_BaryCoordSmoothAMD.y);
|
||||
bary = bary.yzx;
|
||||
#if BARYCENTRIC_STABILIZE
|
||||
vec4 v0 = interpolateAtVertexAMD(inPOS1, 0);
|
||||
vec4 v1 = interpolateAtVertexAMD(inPOS1, 1);
|
||||
vec4 v2 = interpolateAtVertexAMD(inPOS1, 2);
|
||||
if (v0 == inPOS0) outBary = encodeBarycentrics(bary.yzx);
|
||||
else if (v1 == inPOS0) outBary = encodeBarycentrics(bary.zxy);
|
||||
else if (v2 == inPOS0) outBary = encodeBarycentrics(bary.xyz);
|
||||
#else
|
||||
outBary = encodeBarycentrics(bary.xyz);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
6
belly/bin/data/shaders/graph/base/instanced.vert.glsl
Normal file
6
belly/bin/data/shaders/graph/base/instanced.vert.glsl
Normal file
@ -0,0 +1,6 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define INSTANCED 1
|
||||
#define SKINNED 0
|
||||
#include "./vert.h"
|
||||
@ -0,0 +1,6 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define INSTANCED 1
|
||||
#define SKINNED 1
|
||||
#include "./vert.h"
|
||||
6
belly/bin/data/shaders/graph/base/skinned.vert.glsl
Normal file
6
belly/bin/data/shaders/graph/base/skinned.vert.glsl
Normal file
@ -0,0 +1,6 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define INSTANCED 0
|
||||
#define SKINNED 1
|
||||
#include "./vert.h"
|
||||
6
belly/bin/data/shaders/graph/base/vert.glsl
Normal file
6
belly/bin/data/shaders/graph/base/vert.glsl
Normal file
@ -0,0 +1,6 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define INSTANCED 0
|
||||
#define SKINNED 0
|
||||
#include "./vert.h"
|
||||
100
belly/bin/data/shaders/graph/base/vert.h
Normal file
100
belly/bin/data/shaders/graph/base/vert.h
Normal file
@ -0,0 +1,100 @@
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
#extension GL_ARB_shader_draw_parameters : enable
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
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 = 7) in uvec4 inJoints;
|
||||
layout (location = 8) in vec4 inWeights;
|
||||
#endif
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
#if !BAKING
|
||||
layout (binding = 0) uniform Camera {
|
||||
Viewport viewport[PASSES];
|
||||
} camera;
|
||||
#endif
|
||||
layout (std140, binding = 1) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 2) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
|
||||
#if SKINNED
|
||||
layout (std140, binding = 3) readonly buffer Joints {
|
||||
mat4 joints[];
|
||||
};
|
||||
#endif
|
||||
|
||||
layout (location = 0) out uvec4 outId;
|
||||
layout (location = 1) flat out vec4 outPOS0;
|
||||
layout (location = 2) out vec4 outPOS1;
|
||||
layout (location = 3) out vec3 outPosition;
|
||||
layout (location = 4) out vec2 outUv;
|
||||
layout (location = 5) out vec4 outColor;
|
||||
layout (location = 6) out vec2 outSt;
|
||||
layout (location = 7) out vec3 outNormal;
|
||||
layout (location = 8) out vec3 outTangent;
|
||||
|
||||
vec4 snap(vec4 vertex, vec2 resolution) {
|
||||
vec4 snappedPos = vertex;
|
||||
snappedPos.xyz = vertex.xyz / vertex.w;
|
||||
snappedPos.xy = floor(resolution * snappedPos.xy) / resolution;
|
||||
snappedPos.xyz *= vertex.w;
|
||||
return snappedPos;
|
||||
}
|
||||
|
||||
void main() {
|
||||
const uint drawID = gl_DrawIDARB;
|
||||
const uint triangleID = gl_VertexIndex / 3;
|
||||
const DrawCommand drawCommand = drawCommands[drawID];
|
||||
const uint instanceID = drawCommand.instanceID; // gl_InstanceIndex;
|
||||
const Instance instance = instances[instanceID];
|
||||
const uint jointID = instance.jointID;
|
||||
|
||||
#if BAKING
|
||||
const mat4 view = mat4(1);
|
||||
const mat4 projection = mat4(1);
|
||||
#else
|
||||
const mat4 view = camera.viewport[PushConstant.pass].view;
|
||||
const mat4 projection = camera.viewport[PushConstant.pass].projection;
|
||||
#endif
|
||||
#if SKINNED
|
||||
const mat4 skinned = joints.length() <= 0 || jointID < 0 ? mat4(1.0) : inWeights.x * joints[jointID + int(inJoints.x)] + inWeights.y * joints[jointID + int(inJoints.y)] + inWeights.z * joints[jointID + int(inJoints.z)] + inWeights.w * joints[jointID + int(inJoints.w)];
|
||||
#else
|
||||
const mat4 skinned = mat4(1.0);
|
||||
#endif
|
||||
// const mat4 model = instances.length() <= 0 ? skinned : (instance.model * skinned);
|
||||
const mat4 model = instance.model * skinned;
|
||||
|
||||
|
||||
#if BAKING
|
||||
gl_Position = vec4(inSt * 2.0 - 1.0, 0.0, 1.0);
|
||||
#else
|
||||
gl_Position = projection * view * model * vec4(inPos.xyz, 1.0);
|
||||
#endif
|
||||
outPOS0 = gl_Position;
|
||||
outPOS1 = gl_Position;
|
||||
|
||||
outId = uvec4(triangleID, drawID, instanceID, PushConstant.pass);
|
||||
|
||||
outPosition = vec3(model * vec4(inPos.xyz, 1.0));
|
||||
outUv = inUv;
|
||||
outSt = inSt;
|
||||
outColor = inColor * instance.color;
|
||||
outNormal = normalize(vec3(model * vec4(inNormal.xyz, 0.0)));
|
||||
outTangent = normalize(vec3(view * model * vec4(inTangent.xyz, 0.0)));
|
||||
}
|
||||
369
belly/bin/data/shaders/graph/cull/comp.glsl
Normal file
369
belly/bin/data/shaders/graph/cull/comp.glsl
Normal file
@ -0,0 +1,369 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
//#extension GL_EXT_nonuniform_qualifier : enable
|
||||
#extension GL_EXT_samplerless_texture_functions : enable
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
#define COMPUTE 1
|
||||
#define QUERY_MIPMAPS 1
|
||||
#define DEPTH_BIAS 0.00005
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
float mipLevels( vec2 size ) {
|
||||
return floor(log2(max(size.x, size.y)));
|
||||
}
|
||||
float mipLevels( ivec2 size ) {
|
||||
return floor(log2(max(size.x, size.y)));
|
||||
}
|
||||
|
||||
vec4 aabbToSphere( Bounds bounds ) {
|
||||
vec4 sphere;
|
||||
sphere.xyz = (bounds.max + bounds.min) * 0.5;
|
||||
sphere.w = length((bounds.max - bounds.min) * 0.5);
|
||||
return sphere;
|
||||
}
|
||||
|
||||
// 2D Polyhedral Bounds of a Clipped, Perspective-Projected 3D Sphere. Michael Mara, Morgan McGuire. 2013
|
||||
bool projectSphere(vec3 C, float r, float znear, float P00, float P11, out vec4 aabb)
|
||||
{
|
||||
if (C.z < r + znear)
|
||||
return false;
|
||||
|
||||
vec2 cx = -C.xz;
|
||||
vec2 vx = vec2(sqrt(dot(cx, cx) - r * r), r);
|
||||
vec2 minx = mat2(vx.x, vx.y, -vx.y, vx.x) * cx;
|
||||
vec2 maxx = mat2(vx.x, -vx.y, vx.y, vx.x) * cx;
|
||||
|
||||
vec2 cy = -C.yz;
|
||||
vec2 vy = vec2(sqrt(dot(cy, cy) - r * r), r);
|
||||
vec2 miny = mat2(vy.x, vy.y, -vy.y, vy.x) * cy;
|
||||
vec2 maxy = mat2(vy.x, -vy.y, vy.y, vy.x) * cy;
|
||||
|
||||
aabb = vec4(minx.x / minx.y * P00, miny.x / miny.y * P11, maxx.x / maxx.y * P00, maxy.x / maxy.y * P11);
|
||||
aabb = aabb.xwzy * vec4(0.5f, -0.5f, 0.5f, -0.5f) + vec4(0.5f); // clip space -> uv space
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint passes;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 0) uniform Camera {
|
||||
Viewport viewport[PASSES];
|
||||
} camera;
|
||||
|
||||
layout (std140, binding = 1) buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
|
||||
layout (std140, binding = 2) buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
|
||||
layout (binding = 3) uniform sampler2D samplerDepth;
|
||||
|
||||
struct Frustum {
|
||||
vec4 planes[6];
|
||||
};
|
||||
|
||||
vec4 normalizePlane( vec4 p ) {
|
||||
return p / length(p.xyz);
|
||||
}
|
||||
|
||||
bool frustumCull( uint id ) {
|
||||
if ( PushConstant.passes == 0 ) return true;
|
||||
|
||||
const DrawCommand drawCommand = drawCommands[id];
|
||||
const Instance instance = instances[drawCommand.instanceID];
|
||||
|
||||
bool visible = false;
|
||||
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
|
||||
#if 0
|
||||
vec4 sphere = aabbToSphere( instance.bounds );
|
||||
vec3 center = vec3( camera.viewport[pass].view * instance.model * vec4( ) );
|
||||
#else
|
||||
mat4 mat = camera.viewport[pass].projection * camera.viewport[pass].view * instance.model;
|
||||
#if 1
|
||||
vec4 planes[6]; {
|
||||
for (int i = 0; i < 3; ++i)
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
planes[i*2+j].x = mat[0][3] + (j == 0 ? mat[0][i] : -mat[0][i]);
|
||||
planes[i*2+j].y = mat[1][3] + (j == 0 ? mat[1][i] : -mat[1][i]);
|
||||
planes[i*2+j].z = mat[2][3] + (j == 0 ? mat[2][i] : -mat[2][i]);
|
||||
planes[i*2+j].w = mat[3][3] + (j == 0 ? mat[3][i] : -mat[3][i]);
|
||||
planes[i*2+j] = normalizePlane( planes[i*2+j] );
|
||||
}
|
||||
}
|
||||
for ( uint p = 0; p < 6; ++p ) {
|
||||
float d = max(instance.bounds.min.x * planes[p].x, instance.bounds.max.x * planes[p].x)
|
||||
+ max(instance.bounds.min.y * planes[p].y, instance.bounds.max.y * planes[p].y)
|
||||
+ max(instance.bounds.min.z * planes[p].z, instance.bounds.max.z * planes[p].z);
|
||||
if ( d > -planes[p].w ) return true;
|
||||
}
|
||||
#else
|
||||
vec4 corners[8] = {
|
||||
vec4( instance.bounds.min.x, instance.bounds.min.y, instance.bounds.min.z, 1.0 ),
|
||||
vec4( instance.bounds.max.x, instance.bounds.min.y, instance.bounds.min.z, 1.0 ),
|
||||
vec4( instance.bounds.max.x, instance.bounds.max.y, instance.bounds.min.z, 1.0 ),
|
||||
vec4( instance.bounds.min.x, instance.bounds.max.y, instance.bounds.min.z, 1.0 ),
|
||||
|
||||
vec4( instance.bounds.min.x, instance.bounds.min.y, instance.bounds.max.z, 1.0 ),
|
||||
vec4( instance.bounds.max.x, instance.bounds.min.y, instance.bounds.max.z, 1.0 ),
|
||||
vec4( instance.bounds.max.x, instance.bounds.max.y, instance.bounds.max.z, 1.0 ),
|
||||
vec4( instance.bounds.min.x, instance.bounds.max.y, instance.bounds.max.z, 1.0 ),
|
||||
};
|
||||
vec4 planes[6]; {
|
||||
#pragma unroll 3
|
||||
for (int i = 0; i < 3; ++i)
|
||||
#pragma unroll 2
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
planes[i*2+j].x = mat[0][3] + (j == 0 ? mat[0][i] : -mat[0][i]);
|
||||
planes[i*2+j].y = mat[1][3] + (j == 0 ? mat[1][i] : -mat[1][i]);
|
||||
planes[i*2+j].z = mat[2][3] + (j == 0 ? mat[2][i] : -mat[2][i]);
|
||||
planes[i*2+j].w = mat[3][3] + (j == 0 ? mat[3][i] : -mat[3][i]);
|
||||
planes[i*2+j] = normalizePlane( planes[i*2+j] );
|
||||
}
|
||||
}
|
||||
#pragma unroll 8
|
||||
for ( uint p = 0; p < 8; ++p ) corners[p] = mat * corners[p];
|
||||
#pragma unroll 6
|
||||
for ( uint p = 0; p < 6; ++p ) {
|
||||
#pragma unroll 8
|
||||
for ( uint q = 0; q < 8; ++q ) {
|
||||
if ( dot( corners[q], planes[p] ) > 0 ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
bool occlusionCull( uint id ) {
|
||||
if ( PushConstant.passes == 0 ) return true;
|
||||
|
||||
const DrawCommand drawCommand = drawCommands[id];
|
||||
const Instance instance = instances[drawCommand.instanceID];
|
||||
|
||||
bool visible = true;
|
||||
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
|
||||
#if 1
|
||||
vec4 aabb;
|
||||
vec4 sphere = aabbToSphere( instance.bounds );
|
||||
vec3 center = (camera.viewport[pass].view * instance.model * vec4(sphere.xyz, 1)).xyz;
|
||||
float radius = (instance.model * vec4(sphere.w, 0, 0, 0)).x;
|
||||
// center.y *= -1;
|
||||
mat4 proj = camera.viewport[pass].projection;
|
||||
float znear = proj[3][2];
|
||||
float P00 = proj[0][0];
|
||||
float P11 = proj[1][1];
|
||||
if (projectSphere(center, radius, znear, P00, P11, aabb)) {
|
||||
ivec2 pyramidSize = textureSize( samplerDepth, 0 );
|
||||
float mips = mipLevels( pyramidSize );
|
||||
|
||||
float width = (aabb.z - aabb.x) * pyramidSize.x;
|
||||
float height = (aabb.w - aabb.y) * pyramidSize.y;
|
||||
|
||||
//find the mipmap level that will match the screen size of the sphere
|
||||
float level = floor(log2(max(width, height)));
|
||||
// if ( level == mips )
|
||||
--level;
|
||||
level = clamp( level, 0, mips );
|
||||
|
||||
//sample the depth pyramid at that specific level
|
||||
float depth = textureLod(samplerDepth, (aabb.xy + aabb.zw) * 0.5, level).x;
|
||||
|
||||
float depthSphere = znear / (center.z - radius);
|
||||
|
||||
instances[drawCommand.instanceID].bounds.padding1 = depth;
|
||||
instances[drawCommand.instanceID].bounds.padding2 = proj[3][2];
|
||||
|
||||
//if the depth of the sphere is in front of the depth pyramid value, then the object is visible
|
||||
visible = visible && depthSphere >= depth - DEPTH_BIAS;
|
||||
}
|
||||
|
||||
#else
|
||||
mat4 mat = camera.viewport[pass].projection * camera.viewport[pass].view * instance.model;
|
||||
vec3 boundsSize = instance.bounds.max - instance.bounds.min;
|
||||
vec3 points[8] = {
|
||||
instance.bounds.min.xyz,
|
||||
instance.bounds.min.xyz + vec3(boundsSize.x,0,0),
|
||||
instance.bounds.min.xyz + vec3(0, boundsSize.y,0),
|
||||
instance.bounds.min.xyz + vec3(0, 0, boundsSize.z),
|
||||
instance.bounds.min.xyz + vec3(boundsSize.xy,0),
|
||||
instance.bounds.min.xyz + vec3(0, boundsSize.yz),
|
||||
instance.bounds.min.xyz + vec3(boundsSize.x, 0, boundsSize.z),
|
||||
instance.bounds.min.xyz + boundsSize.xyz,
|
||||
};
|
||||
vec2 minXY = vec2(1);
|
||||
vec2 maxXY = vec2(0);
|
||||
|
||||
float minZ = 1;
|
||||
float maxZ = 0;
|
||||
|
||||
#pragma unroll 8
|
||||
for ( uint i = 0; i < 8; ++i ) {
|
||||
vec4 clip = mat * vec4( points[i], 1 );
|
||||
clip.xyz /= clip.w;
|
||||
clip.xy = clip.xy * 0.5 + 0.5;
|
||||
|
||||
minXY.x = min(minXY.x, clip.x);
|
||||
minXY.y = min(minXY.y, clip.y);
|
||||
|
||||
maxXY.x = max(maxXY.x, clip.x);
|
||||
maxXY.y = max(maxXY.y, clip.y);
|
||||
|
||||
#if INVERSE
|
||||
clip.z = 1.0 - clip.z;
|
||||
maxZ = max(maxZ, clip.z);
|
||||
#else
|
||||
minZ = min(minZ, clip.z);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( maxXY.x <= 0 || maxXY.y <= 0 ) return false;
|
||||
if ( minXY.x >= 1 || minXY.y >= 1 ) return false;
|
||||
|
||||
ivec2 depthSize = textureSize( samplerDepth, 0 );
|
||||
float mips = mipLevels( depthSize );
|
||||
|
||||
vec4 uv = vec4(minXY, maxXY);
|
||||
|
||||
ivec2 clipSize = ivec2(maxXY - minXY) * depthSize;
|
||||
float mip = mipLevels( clipSize );
|
||||
mip = clamp( mip, 0, mips );
|
||||
if ( mip == 0 ) {
|
||||
mip = 1;
|
||||
} else {
|
||||
float lower = max(mip - 1, 0);
|
||||
float scale = exp2(-lower);
|
||||
vec2 a = floor(uv.xy * scale);
|
||||
vec2 b = ceil(uv.zw * scale);
|
||||
vec2 dims = b - a;
|
||||
|
||||
// Use the lower level if we only touch <= 2 texels in both dimensions
|
||||
if (dims.x <= 2 && dims.y <= 2) mip = lower;
|
||||
}
|
||||
|
||||
float depths[4] = {
|
||||
textureLod( samplerDepth, uv.xy, mip ).r,
|
||||
textureLod( samplerDepth, uv.zy, mip ).r,
|
||||
textureLod( samplerDepth, uv.xw, mip ).r,
|
||||
textureLod( samplerDepth, uv.zw, mip ).r,
|
||||
};
|
||||
#if INVERSE
|
||||
float minDepth = 1.0 - min(min(min(depths[0], depths[1]), depths[2]), depths[3]);
|
||||
#else
|
||||
float maxDepth = max(max(max(depths[0], depths[1]), depths[2]), depths[3]);
|
||||
#endif
|
||||
|
||||
instances[drawCommand.instanceID].bounds.padding1 = minZ;
|
||||
instances[drawCommand.instanceID].bounds.padding2 = maxDepth;
|
||||
|
||||
return minZ <= maxDepth;
|
||||
#endif
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
void main() {
|
||||
const uint gID = gl_GlobalInvocationID.x;
|
||||
if ( !(0 <= gID && gID < drawCommands.length()) ) return;
|
||||
|
||||
bool visible = frustumCull( gID );
|
||||
// if ( visible ) visible = occlusionCull( gID );
|
||||
// bool visible = occlusionCull( gID );
|
||||
drawCommands[gID].instances = visible ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Frustum frustum;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
frustum.planes[i*2+j].x = mat[0][3] + (j == 0 ? mat[0][i] : -mat[0][i]);
|
||||
frustum.planes[i*2+j].y = mat[1][3] + (j == 0 ? mat[1][i] : -mat[1][i]);
|
||||
frustum.planes[i*2+j].z = mat[2][3] + (j == 0 ? mat[2][i] : -mat[2][i]);
|
||||
frustum.planes[i*2+j].w = mat[3][3] + (j == 0 ? mat[3][i] : -mat[3][i]);
|
||||
frustum.planes[i*2+j]*= length(frustum.planes[i*2+j].xyz);
|
||||
}
|
||||
for ( uint i = 0; i < 6; ++i ) {
|
||||
vec4 plane = frustum.planes[i];
|
||||
float d = dot(instance.bounds.center, plane.xyz);
|
||||
float r = dot(instance.bounds.extent, abs(plane.xyz));
|
||||
bool inside = d + r > -plane.w;
|
||||
if ( !inside ) return 0;
|
||||
}
|
||||
return true;
|
||||
*/
|
||||
/*
|
||||
vec4 plane;
|
||||
vec4 center = vec4( (max + min) * 0.5, 1 );
|
||||
vec4 extent = vec4( (max - min) * 0.5, 1 );
|
||||
center = mat * center;
|
||||
extent = mat * extent;
|
||||
center.xyz /= center.w;
|
||||
extent.xyz /= extent.w;
|
||||
for (int i = 0; i < 4; ++i ) plane[i] = mat[i][3] + mat[i][0]; // left
|
||||
visible = dot(center.xyz + extent.xyz * sign(plane.xyz), plane.xyz ) > -plane.w;
|
||||
if ( visible ) return true;
|
||||
|
||||
for (int i = 0; i < 4; ++i ) plane[i] = mat[i][3] - mat[i][0]; // right
|
||||
visible = dot(center.xyz + extent.xyz * sign(plane.xyz), plane.xyz ) > -plane.w;
|
||||
if ( visible ) return true;
|
||||
|
||||
for (int i = 0; i < 4; ++i ) plane[i] = mat[i][3] + mat[i][1]; // bottom
|
||||
visible = dot(center.xyz + extent.xyz * sign(plane.xyz), plane.xyz ) > -plane.w;
|
||||
if ( visible ) return true;
|
||||
|
||||
for (int i = 0; i < 4; ++i ) plane[i] = mat[i][3] - mat[i][1]; // top
|
||||
visible = dot(center.xyz + extent.xyz * sign(plane.xyz), plane.xyz ) > -plane.w;
|
||||
if ( visible ) return true;
|
||||
|
||||
for (int i = 0; i < 4; ++i ) plane[i] = mat[i][3] + mat[i][2]; // near
|
||||
visible = dot(center.xyz + extent.xyz * sign(plane.xyz), plane.xyz ) > -plane.w;
|
||||
if ( visible ) return true;
|
||||
|
||||
for (int i = 0; i < 4; ++i ) plane[i] = mat[i][3] - mat[i][2]; // far
|
||||
visible = dot(center.xyz + extent.xyz * sign(plane.xyz), plane.xyz ) > -plane.w;
|
||||
if ( visible ) return true;
|
||||
|
||||
*/
|
||||
/*
|
||||
for ( uint p = 0; p < 8; ++p ) {
|
||||
vec4 t = corners[p];
|
||||
float w = abs(t.w);
|
||||
visible = -w <= t.x && t.x <= w && -w <= t.y && t.y <= w && 0 <= t.z && t.z <= w; // && -w <= t.z && t.z <= w;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
mat4 convert( mat4 proj ) {
|
||||
float f = -proj[1][1];
|
||||
float raidou = f / proj[0][0];
|
||||
float zNear = proj[3][2];
|
||||
float zFar = 32;
|
||||
|
||||
float range = zNear - zFar;
|
||||
|
||||
float Sx = f * raidou;
|
||||
float Sy = f;
|
||||
float Sz = (-zNear - zFar) / range;
|
||||
float Pz = 2 * zFar * zNear / range;
|
||||
|
||||
mat4 new = mat4(1.0);
|
||||
new[0][0] = Sx;
|
||||
new[1][1] = -Sy;
|
||||
new[2][2] = Sz;
|
||||
new[3][2] = Pz;
|
||||
new[2][3] = 1;
|
||||
return new;
|
||||
}
|
||||
*/
|
||||
73
belly/bin/data/shaders/graph/depth/frag.glsl
Normal file
73
belly/bin/data/shaders/graph/depth/frag.glsl
Normal file
@ -0,0 +1,73 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
#define FRAGMENT 1
|
||||
#define MAX_TEXTURES textures.length()
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 1;
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (std140, binding = 6) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 7) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
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[];
|
||||
};
|
||||
|
||||
#include "../../common/functions.h"
|
||||
|
||||
layout (location = 0) flat in uvec4 inId;
|
||||
layout (location = 1) flat in vec4 inPOS0;
|
||||
layout (location = 2) in vec4 inPOS1;
|
||||
layout (location = 3) in vec3 inPosition;
|
||||
layout (location = 4) in vec2 inUv;
|
||||
layout (location = 5) in vec4 inColor;
|
||||
layout (location = 6) in vec2 inSt;
|
||||
layout (location = 7) in vec3 inNormal;
|
||||
layout (location = 8) in vec3 inTangent;
|
||||
|
||||
void main() {
|
||||
const uint triangleID = uint(inId.x); // gl_PrimitiveID
|
||||
const uint drawID = uint(inId.y);
|
||||
const uint instanceID = uint(inId.z);
|
||||
|
||||
const DrawCommand drawCommand = drawCommands[drawID];
|
||||
const Instance instance = instances[instanceID];
|
||||
const Material material = materials[instance.materialID];
|
||||
|
||||
surface.uv.xy = wrap(inUv.xy);
|
||||
surface.uv.z = mipLevel(dFdx(inUv), dFdy(inUv));
|
||||
|
||||
vec4 A = inColor * material.colorBase;
|
||||
// sample albedo
|
||||
if ( validTextureIndex( material.indexAlbedo ) ) {
|
||||
A = sampleTexture( material.indexAlbedo );
|
||||
}
|
||||
// alpha mode OPAQUE
|
||||
if ( material.modeAlpha == 0 ) {
|
||||
A.a = 1;
|
||||
// alpha mode BLEND
|
||||
} else if ( material.modeAlpha == 1 ) {
|
||||
|
||||
// alpha mode MASK
|
||||
} else if ( material.modeAlpha == 2 ) {
|
||||
if ( A.a < abs(material.factorAlphaCutoff) ) discard;
|
||||
A.a = 1;
|
||||
}
|
||||
if ( A.a < 1 ) discard;
|
||||
}
|
||||
142
belly/bin/data/shaders/graph/voxelize/frag.glsl
Normal file
142
belly/bin/data/shaders/graph/voxelize/frag.glsl
Normal file
@ -0,0 +1,142 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
// to-do: convert to use functions.h surface population functions
|
||||
|
||||
#define FRAGMENT 1
|
||||
#define DEFERRED_SAMPLING 0
|
||||
#define CUBEMAPS 1
|
||||
|
||||
#define BLEND 1
|
||||
#define DEPTH_TEST 0
|
||||
#define USE_LIGHTMAP 1
|
||||
layout (constant_id = 0) const uint TEXTURES = 512;
|
||||
layout (constant_id = 1) const uint CASCADES = 16;
|
||||
|
||||
#define MAX_TEXTURES textures.length()
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (std140, binding = 6) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 7) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
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 = 12, rg16ui) uniform volatile coherent uimage3D voxelId[CASCADES];
|
||||
layout (binding = 13, rg16f) uniform volatile coherent image3D voxelNormal[CASCADES];
|
||||
#if VXGI_HDR
|
||||
layout (binding = 14, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES];
|
||||
#else
|
||||
layout (binding = 14, rgba8) uniform volatile coherent image3D voxelRadiance[CASCADES];
|
||||
#endif
|
||||
#if DEPTH_TEST
|
||||
layout (binding = 15, r16f) uniform volatile coherent image3D voxelDepth[CASCADES];
|
||||
#endif
|
||||
|
||||
layout (location = 0) flat in uvec4 inId;
|
||||
layout (location = 1) flat in vec4 inPOS0;
|
||||
layout (location = 2) in vec4 inPOS1;
|
||||
layout (location = 3) in vec3 inPosition;
|
||||
layout (location = 4) in vec2 inUv;
|
||||
layout (location = 5) in vec4 inColor;
|
||||
layout (location = 6) in vec2 inSt;
|
||||
layout (location = 7) in vec3 inNormal;
|
||||
layout (location = 8) in vec3 inTangent;
|
||||
|
||||
#include "../../common/functions.h"
|
||||
|
||||
void main() {
|
||||
const uint CASCADE = inId.w;
|
||||
if ( CASCADES <= CASCADE ) discard;
|
||||
const vec3 P = inPosition.xzy * 0.5 + 0.5;
|
||||
if ( abs(P.x) > 1 || abs(P.y) > 1 || abs(P.z) > 1 ) discard;
|
||||
|
||||
const uint triangleID = uint(inId.x); // gl_PrimitiveID
|
||||
const uint drawID = uint(inId.y);
|
||||
const uint instanceID = uint(inId.z);
|
||||
|
||||
surface.uv.xy = wrap(inUv.xy);
|
||||
surface.uv.z = mipLevel(dFdx(inUv), dFdy(inUv));
|
||||
surface.st.xy = inSt;
|
||||
surface.st.z = mipLevel(dFdx(inSt), dFdy(inSt));
|
||||
|
||||
const DrawCommand drawCommand = drawCommands[drawID];
|
||||
const Instance instance = instances[instanceID];
|
||||
const Material material = materials[instance.materialID];
|
||||
surface.instance = instance;
|
||||
|
||||
vec4 A = material.colorBase;
|
||||
float M = material.factorMetallic;
|
||||
float R = material.factorRoughness;
|
||||
float AO = material.factorOcclusion;
|
||||
|
||||
// sample albedo
|
||||
if ( validTextureIndex( material.indexAlbedo ) ) {
|
||||
A = sampleTexture( material.indexAlbedo );
|
||||
}
|
||||
// alpha mode OPAQUE
|
||||
if ( material.modeAlpha == 0 ) {
|
||||
A.a = 1;
|
||||
// alpha mode BLEND
|
||||
} else if ( material.modeAlpha == 1 ) {
|
||||
|
||||
// alpha mode MASK
|
||||
} else if ( material.modeAlpha == 2 ) {
|
||||
if ( A.a < abs(material.factorAlphaCutoff) ) discard;
|
||||
A.a = 1;
|
||||
}
|
||||
if ( A.a == 0 ) discard;
|
||||
|
||||
#if USE_LIGHTMAP
|
||||
if ( validTextureIndex( instance.lightmapID ) ) {
|
||||
A.rgb *= sampleTexture( instance.lightmapID, inSt ).rgb;
|
||||
}
|
||||
#endif
|
||||
|
||||
// sample normal
|
||||
vec3 N = inNormal;
|
||||
vec3 T = inTangent;
|
||||
T = normalize(T - dot(T, N) * N);
|
||||
vec3 B = cross(T, N);
|
||||
mat3 TBN = mat3(T, B, N);
|
||||
// mat3 TBN = mat3(N, B, T);
|
||||
if ( T != vec3(0) && validTextureIndex( material.indexNormal ) ) {
|
||||
N = TBN * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - 1.0 );
|
||||
}
|
||||
|
||||
const ivec3 uvw = ivec3(P * imageSize(voxelRadiance[CASCADE]));
|
||||
|
||||
#if DEPTH_TEST
|
||||
const float outDepth = length(inPosition.xzy);
|
||||
const float inDepth = imageLoad(voxelDepth[CASCADE], uvw).r;
|
||||
if ( inDepth != 0 && inDepth < outDepth ) discard;
|
||||
imageStore(voxelDepth[CASCADE], uvw, vec4(inDepth, 0, 0, 0));
|
||||
#endif
|
||||
|
||||
imageStore(voxelId[CASCADE], uvw, uvec4(uvec2(drawID + 1, instanceID + 1), 0, 0));
|
||||
imageStore(voxelNormal[CASCADE], uvw, vec4(encodeNormals( normalize( N ) ), 0, 0));
|
||||
#if BLEND
|
||||
// GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
|
||||
const vec4 src = A * inColor;
|
||||
const vec4 dst = imageLoad(voxelRadiance[CASCADE], uvw);
|
||||
imageStore(voxelRadiance[CASCADE], uvw, blend( src, dst, src.a ) );
|
||||
#else
|
||||
imageStore(voxelRadiance[CASCADE], uvw, A );
|
||||
#endif
|
||||
}
|
||||
93
belly/bin/data/shaders/graph/voxelize/geom.glsl
Normal file
93
belly/bin/data/shaders/graph/voxelize/geom.glsl
Normal file
@ -0,0 +1,93 @@
|
||||
#version 450
|
||||
#pragma shader_stage(geometry)
|
||||
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices = 3) out;
|
||||
|
||||
layout (location = 0) flat in uvec4 inId[];
|
||||
layout (location = 1) flat in vec4 inPOS0[];
|
||||
layout (location = 2) in vec4 inPOS1[];
|
||||
layout (location = 3) in vec3 inPosition[];
|
||||
layout (location = 4) in vec2 inUv[];
|
||||
layout (location = 5) in vec4 inColor[];
|
||||
layout (location = 6) in vec2 inSt[];
|
||||
layout (location = 7) in vec3 inNormal[];
|
||||
layout (location = 8) in vec3 inTangent[];
|
||||
|
||||
layout (location = 0) flat out uvec4 outId;
|
||||
layout (location = 1) flat out vec4 outPOS0;
|
||||
layout (location = 2) out vec4 outPOS1;
|
||||
layout (location = 3) out vec3 outPosition;
|
||||
layout (location = 4) out vec2 outUv;
|
||||
layout (location = 5) out vec4 outColor;
|
||||
layout (location = 6) out vec2 outSt;
|
||||
layout (location = 7) out vec3 outNormal;
|
||||
layout (location = 8) out vec3 outTangent;
|
||||
|
||||
layout (binding = 4) uniform UBO {
|
||||
mat4 voxel;
|
||||
|
||||
float cascadePower;
|
||||
float granularity;
|
||||
float voxelizeScale;
|
||||
float occlusionFalloff;
|
||||
|
||||
uint shadows;
|
||||
uint padding1;
|
||||
uint padding2;
|
||||
uint padding3;
|
||||
} ubo;
|
||||
|
||||
float cascadePower( uint x ) {
|
||||
return pow(1 + x, ubo.cascadePower);
|
||||
// return max( 1, x * ubo.cascadePower );
|
||||
}
|
||||
|
||||
#define USE_CROSS 0
|
||||
void main(){
|
||||
const float HALF_PIXEL = ubo.voxelizeScale;
|
||||
const vec3 C = ( inPosition[0] + inPosition[1] + inPosition[2] ) / 3.0;
|
||||
|
||||
#if USE_CROSS
|
||||
const vec3 N = abs(cross(inPosition[2] - inPosition[0], inPosition[1] - inPosition[0]));
|
||||
#else
|
||||
const vec3 N = abs(inNormal[0] + inNormal[1] + inNormal[2]);
|
||||
uint A = N.y > N.x ? 1 : 0;
|
||||
A = N.z > N[A] ? 2 : A;
|
||||
#endif
|
||||
|
||||
const uint CASCADE = inId[0].w;
|
||||
vec3 P[3] = {
|
||||
vec3( ubo.voxel * vec4( inPosition[0], 1 ) ) / cascadePower(CASCADE),
|
||||
vec3( ubo.voxel * vec4( inPosition[1], 1 ) ) / cascadePower(CASCADE),
|
||||
vec3( ubo.voxel * vec4( inPosition[2], 1 ) ) / cascadePower(CASCADE),
|
||||
};
|
||||
|
||||
#pragma unroll 3
|
||||
for( uint i = 0; i < 3; ++i ){
|
||||
const vec3 D = normalize( inPosition[i] - C ) * HALF_PIXEL;
|
||||
|
||||
outPosition = P[i] + D;
|
||||
outPOS0 = inPOS0[i];
|
||||
outPOS1 = inPOS1[i];
|
||||
outUv = inUv[i];
|
||||
outSt = inSt[i];
|
||||
outColor = inColor[i];
|
||||
outNormal = inNormal[i];
|
||||
outTangent = inTangent[i];
|
||||
outId = inId[i];
|
||||
|
||||
const vec3 P = outPosition; // + D;
|
||||
#if USE_CROSS
|
||||
if ( N.z > N.x && N.z > N.y ) gl_Position = vec4(P.x, P.y, 0, 1);
|
||||
else if ( N.x > N.y && N.x > N.z ) gl_Position = vec4(P.y, P.z, 0, 1);
|
||||
else gl_Position = vec4(P.x, P.z, 0, 1);
|
||||
#else
|
||||
if ( A == 0 ) gl_Position = vec4(P.zy, 0, 1 );
|
||||
else if ( A == 1 ) gl_Position = vec4(P.xz, 0, 1 );
|
||||
else if ( A == 2 ) gl_Position = vec4(P.xy, 0, 1 );
|
||||
#endif
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
5
belly/bin/data/shaders/gui/base/frag.glsl
Normal file
5
belly/bin/data/shaders/gui/base/frag.glsl
Normal file
@ -0,0 +1,5 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
#define GLYPH 0
|
||||
#include "../gui/frag.h"
|
||||
5
belly/bin/data/shaders/gui/base/vert.glsl
Normal file
5
belly/bin/data/shaders/gui/base/vert.glsl
Normal file
@ -0,0 +1,5 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define GLYPH 0
|
||||
#include "../gui/vert.h"
|
||||
45
belly/bin/data/shaders/gui/gui/frag.h
Normal file
45
belly/bin/data/shaders/gui/gui/frag.h
Normal file
@ -0,0 +1,45 @@
|
||||
#define TEXTURES 1
|
||||
#define CUBEMAPS 1
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
#include "../../common/functions.h"
|
||||
#include "./gui.h"
|
||||
|
||||
layout (binding = 1) uniform sampler2D samplerTexture;
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in flat Gui inGui;
|
||||
layout (location = 7) in flat Glyph inGlyph;
|
||||
|
||||
layout (location = 0) out vec4 outAlbedo;
|
||||
|
||||
void main() {
|
||||
if ( inUv.x < inGui.offset.x || inUv.y < inGui.offset.y || inUv.x > inGui.offset.z || inUv.y > inGui.offset.w ) discard;
|
||||
|
||||
const vec2 uv = inUv.xy;
|
||||
const float mip = mipLevel(dFdx(inUv), dFdy(inUv));
|
||||
vec4 C = inGui.color;
|
||||
#if GLYPH
|
||||
if ( enabled(inGui.mode, 1) ) {
|
||||
outAlbedo = inGui.color;
|
||||
return;
|
||||
}
|
||||
const float sampled = texture(samplerTexture, inUv).r;
|
||||
if ( enabled(inGui.mode, 2) ) {
|
||||
const float smoothing = ( inGlyph.spread > 0 && inGlyph.scale > 0 ) ? 0.25 / (inGlyph.spread * inGlyph.scale) : 0.25 / (4 * 1.5);
|
||||
const float outlining = smoothstep(0.5 - smoothing, 0.5 + smoothing, sampled);
|
||||
const float alpha = smoothstep(inGlyph.weight - smoothing, inGlyph.weight + smoothing, sampled);
|
||||
if ( alpha < 0.001 || alpha > 1 ) discard;
|
||||
C = mix(inGlyph.stroke, inGui.color, outlining);
|
||||
C.a = inGui.color.a * alpha;
|
||||
} else {
|
||||
if ( sampled < 0.001 || sampled > 1 ) discard;
|
||||
C *= sampled;
|
||||
}
|
||||
#else
|
||||
if ( enabled(inGui.mode, 0) ) C = inGui.color;
|
||||
else C *= textureLod( samplerTexture, uv, mip );
|
||||
#endif
|
||||
outAlbedo = C;
|
||||
}
|
||||
18
belly/bin/data/shaders/gui/gui/gui.h
Normal file
18
belly/bin/data/shaders/gui/gui/gui.h
Normal file
@ -0,0 +1,18 @@
|
||||
struct Gui {
|
||||
vec4 offset;
|
||||
vec4 color;
|
||||
|
||||
int mode;
|
||||
float depth;
|
||||
float padding1;
|
||||
float padding2;
|
||||
};
|
||||
|
||||
struct Glyph {
|
||||
vec4 stroke;
|
||||
|
||||
int spread;
|
||||
float weight;
|
||||
float scale;
|
||||
float padding;
|
||||
};
|
||||
37
belly/bin/data/shaders/gui/gui/vert.h
Normal file
37
belly/bin/data/shaders/gui/gui/vert.h
Normal file
@ -0,0 +1,37 @@
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
|
||||
#include "./gui.h"
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
mat4 model[PASSES];
|
||||
};
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
Gui gui;
|
||||
#if GLYPH
|
||||
Glyph glyph;
|
||||
#endif
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out flat Gui outGui;
|
||||
#if GLYPH
|
||||
layout (location = 7) out flat Glyph outGlyph;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outGui = ubo.gui;
|
||||
#if GLYPH
|
||||
outGlyph = ubo.glyph;
|
||||
#endif
|
||||
|
||||
gl_Position = ubo.matrices.model[PushConstant.pass] * vec4(inPos.xy, ubo.gui.depth, 1.0);
|
||||
}
|
||||
5
belly/bin/data/shaders/gui/text/frag.glsl
Normal file
5
belly/bin/data/shaders/gui/text/frag.glsl
Normal file
@ -0,0 +1,5 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
#define GLYPH 1
|
||||
#include "../gui/frag.h"
|
||||
5
belly/bin/data/shaders/gui/text/vert.glsl
Normal file
5
belly/bin/data/shaders/gui/text/vert.glsl
Normal file
@ -0,0 +1,5 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define GLYPH 1
|
||||
#include "../gui/vert.h"
|
||||
401
belly/bin/data/shaders/raytrace/shader.ray-gen.glsl
Normal file
401
belly/bin/data/shaders/raytrace/shader.ray-gen.glsl
Normal file
@ -0,0 +1,401 @@
|
||||
#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 = 8;
|
||||
layout (constant_id = 3) const uint CASCADES = 1;
|
||||
|
||||
// shader type settings
|
||||
#define RT 1
|
||||
#define DEFERRED_SAMPLING 1
|
||||
#define BUFFER_REFERENCE 1
|
||||
#define UINT64_ENABLED 1
|
||||
#define PBR 1
|
||||
// shader function settings
|
||||
#define FOG 1
|
||||
|
||||
//force it off
|
||||
#define BARYCENTRIC 0
|
||||
#define BARYCENTRIC_CALCULATE 0
|
||||
|
||||
#include "../common/macros.h"
|
||||
#include "../common/structs.h"
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 0) uniform accelerationStructureEXT tlas;
|
||||
|
||||
layout (binding = 1, rgba32f) uniform volatile coherent image2D outImage;
|
||||
|
||||
layout (binding = 2) uniform UBO {
|
||||
EyeMatrices eyes[2];
|
||||
|
||||
Settings settings;
|
||||
} ubo;
|
||||
|
||||
layout (std140, binding = 3) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
layout (std140, binding = 4) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
layout (std140, binding = 5) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 6) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 7) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout (binding = 8) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 9) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 10) uniform sampler3D samplerNoise;
|
||||
#if VXGI
|
||||
layout (binding = 11) uniform usampler3D voxelId[CASCADES];
|
||||
layout (binding = 12) uniform sampler3D voxelNormal[CASCADES];
|
||||
layout (binding = 13) uniform sampler3D voxelRadiance[CASCADES];
|
||||
#endif
|
||||
|
||||
layout (location = 0) rayPayloadEXT RayTracePayload payload;
|
||||
|
||||
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/light.h"
|
||||
#include "../common/fog.h"
|
||||
#if VXGI
|
||||
#include "../common/vxgi.h"
|
||||
#endif
|
||||
|
||||
void trace( Ray ray, float tMin, float tMax ) {
|
||||
uint rayFlags = gl_RayFlagsOpaqueEXT;
|
||||
uint cullMask = 0xFF;
|
||||
|
||||
payload.hit = false;
|
||||
surface.position.eye.z = tMax;
|
||||
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 = ubo.settings.rt.defaultRayBounds.y;
|
||||
|
||||
payload.hit = false;
|
||||
surface.position.eye.z = tMax;
|
||||
traceRayEXT(tlas, rayFlags, cullMask, 0, 0, 0, ray.origin, tMin, ray.direction, tMax, 0);
|
||||
}
|
||||
|
||||
void trace( Ray ray ) {
|
||||
trace( ray, ubo.settings.rt.defaultRayBounds.x, ubo.settings.rt.defaultRayBounds.y );
|
||||
}
|
||||
|
||||
float shadowFactor( const Light light, float def ) {
|
||||
Ray ray;
|
||||
ray.origin = surface.position.world;
|
||||
ray.direction = light.position - ray.origin;
|
||||
|
||||
float tMin = ubo.settings.rt.defaultRayBounds.x;
|
||||
float tMax = length(ray.direction) - 0.0001;
|
||||
|
||||
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, tMin, ray.direction, tMax, 0);
|
||||
|
||||
return payload.hit ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
void directLighting() {
|
||||
#if VXGI
|
||||
indirectLighting();
|
||||
#endif
|
||||
|
||||
surface.light.rgb += surface.material.albedo.rgb * ubo.settings.lighting.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 ) {
|
||||
Ray fogRay = ray;
|
||||
float eyeDepth = 0;
|
||||
vec4 outFrag = vec4(0);
|
||||
|
||||
// initial condition
|
||||
{
|
||||
trace( ray );
|
||||
|
||||
if ( payload.hit ) {
|
||||
populateSurface( payload );
|
||||
directLighting();
|
||||
} else if ( 0 <= ubo.settings.lighting.indexSkybox && ubo.settings.lighting.indexSkybox < CUBEMAPS ) {
|
||||
surface.fragment = texture( samplerCubemaps[ubo.settings.lighting.indexSkybox], ray.direction );
|
||||
surface.fragment.a = 4096;
|
||||
surface.position.eye.z /= 8;
|
||||
} else {
|
||||
surface.fragment = vec4(ubo.settings.lighting.ambient.rgb, 0.5);
|
||||
}
|
||||
#if FOG
|
||||
fog( ray, surface.fragment.rgb, surface.fragment.a );
|
||||
#endif
|
||||
outFrag = surface.fragment;
|
||||
eyeDepth = surface.position.eye.z;
|
||||
}
|
||||
|
||||
|
||||
// "transparency"
|
||||
if ( payload.hit && surface.material.albedo.a < 0.999 ) {
|
||||
const vec4 TRANSPARENCY_COLOR = vec4(1.0 - surface.material.albedo.a);
|
||||
|
||||
if ( surface.material.albedo.a < 0.001 ) outFrag = vec4(0);
|
||||
|
||||
RayTracePayload surfacePayload = payload;
|
||||
Ray transparency;
|
||||
transparency.direction = ray.direction;
|
||||
transparency.origin = surface.position.world;
|
||||
fogRay = transparency;
|
||||
|
||||
trace( transparency, ubo.settings.rt.alphaTestOffset );
|
||||
if ( payload.hit ) {
|
||||
populateSurface( payload );
|
||||
directLighting();
|
||||
} else if ( 0 <= ubo.settings.lighting.indexSkybox && ubo.settings.lighting.indexSkybox < CUBEMAPS ) {
|
||||
surface.fragment = texture( samplerCubemaps[ubo.settings.lighting.indexSkybox], ray.direction );
|
||||
surface.fragment.a = 4096;
|
||||
surface.position.eye.z /= 8;
|
||||
}
|
||||
#if FOG
|
||||
fog( transparency, surface.fragment.rgb, surface.fragment.a );
|
||||
#endif
|
||||
outFrag += TRANSPARENCY_COLOR * surface.fragment;
|
||||
eyeDepth = surface.position.eye.z;
|
||||
|
||||
payload = surfacePayload;
|
||||
populateSurface( payload );
|
||||
}
|
||||
#if FOG
|
||||
{
|
||||
// surface.position.eye.z = eyeDepth;
|
||||
// fog( fogRay, outFrag.rgb, outFrag.a );
|
||||
// fog( ray, surface.fragment.rgb, surface.fragment.a );
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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 );
|
||||
|
||||
if ( payload.hit ) {
|
||||
populateSurface( payload );
|
||||
directLighting();
|
||||
} else if ( 0 <= ubo.settings.lighting.indexSkybox && ubo.settings.lighting.indexSkybox < CUBEMAPS ) {
|
||||
surface.fragment = texture( samplerCubemaps[ubo.settings.lighting.indexSkybox], reflection.direction );
|
||||
surface.fragment.a = 4096;
|
||||
}
|
||||
#if FOG
|
||||
fog( reflection, surface.fragment.rgb, surface.fragment.a );
|
||||
#endif
|
||||
outFrag += REFLECTED_ALBEDO * surface.fragment;
|
||||
|
||||
payload = surfacePayload;
|
||||
populateSurface( payload );
|
||||
}
|
||||
}
|
||||
|
||||
return outFrag;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// if ( ubo.settings.mode.frameNumber > 16 ) return;
|
||||
// prngSeed = tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, ubo.settings.mode.frameNumber);
|
||||
prngSeed = tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, int(clockARB()));
|
||||
surface.pass = PushConstant.pass;
|
||||
surface.subID = 0;
|
||||
vec4 outFrag = vec4(0);
|
||||
|
||||
const uint SAMPLES = min(ubo.settings.rt.samples, 4);
|
||||
const uint NUM_PATHS = min(ubo.settings.rt.paths, 8);
|
||||
#if 1
|
||||
const uint FRAME_ACCUMULATION_VALUE = ubo.settings.rt.frameAccumulationMinimum > 0 ? min(ubo.settings.rt.frameAccumulationMinimum, ubo.settings.mode.frameNumber + 1) : ubo.settings.mode.frameNumber + 1;
|
||||
#else
|
||||
const uint FRAME_ACCUMULATION_VALUE = min(32, ubo.settings.mode.frameNumber + 1);
|
||||
#endif
|
||||
const float BLEND_FACTOR = 1.0f / float(FRAME_ACCUMULATION_VALUE);
|
||||
uint FRAME_NUMBER = ubo.settings.mode.frameNumber;
|
||||
|
||||
#if 0
|
||||
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 1
|
||||
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 = 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;
|
||||
|
||||
surface.ray.direction = normalize( far3 - near3 );
|
||||
surface.ray.origin = ubo.eyes[surface.pass].eyePos.xyz;
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
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 ) break;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
{
|
||||
outFrag /= SAMPLES;
|
||||
}
|
||||
#elif 0
|
||||
{
|
||||
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 = 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;
|
||||
|
||||
surface.ray.direction = normalize( far3 - near3 );
|
||||
surface.ray.origin = ubo.eyes[surface.pass].eyePos.xyz;
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
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 ) break;
|
||||
|
||||
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;
|
||||
}
|
||||
{
|
||||
surface.fragment = outFrag;
|
||||
}
|
||||
#else
|
||||
{
|
||||
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 = 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;
|
||||
|
||||
surface.ray.direction = normalize( far3 - near3 );
|
||||
surface.ray.origin = ubo.eyes[surface.pass].eyePos.xyz;
|
||||
#endif
|
||||
}
|
||||
{
|
||||
surface.fragment = traceStep( surface.ray );
|
||||
}
|
||||
#endif
|
||||
{
|
||||
#if BLOOM
|
||||
float brightness = dot(surface.fragment.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
vec4 outFragBright = brightness > ubo.threshold ? vec4(surface.fragment.rgb, 1.0) : vec4(0, 0, 0, 1);
|
||||
// imageStore(outImage, ivec2(gl_LaunchIDEXT.xy), outFragBright);
|
||||
#endif
|
||||
#if FOG
|
||||
fog( surface.ray, surface.fragment.rgb, surface.fragment.a );
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
outFrag = surface.fragment;
|
||||
outFrag.a = 1;
|
||||
}
|
||||
|
||||
if ( ubo.settings.mode.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);
|
||||
}
|
||||
}
|
||||
28
belly/bin/data/shaders/raytrace/shader.ray-hit-any.glsl
Normal file
28
belly/bin/data/shaders/raytrace/shader.ray-hit-any.glsl
Normal file
@ -0,0 +1,28 @@
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
#extension GL_EXT_buffer_reference : enable
|
||||
#extension GL_EXT_buffer_reference2 : enable
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
#pragma shader_stage(anyhit)
|
||||
layout (constant_id = 0) const uint PASSES = 2;
|
||||
layout (constant_id = 1) const uint TEXTURES = 512;
|
||||
layout (constant_id = 2) const uint CUBEMAPS = 128;
|
||||
|
||||
#define RT 1
|
||||
#define COMPUTE 1
|
||||
|
||||
#include "../common/macros.h"
|
||||
#include "../common/structs.h"
|
||||
|
||||
layout(location = 0) rayPayloadInEXT RayTracePayload payload;
|
||||
|
||||
hitAttributeEXT vec2 attribs;
|
||||
|
||||
void main() {
|
||||
payload.hit = true;
|
||||
payload.instanceID = gl_InstanceCustomIndexEXT;
|
||||
payload.primitiveID = gl_PrimitiveID;
|
||||
payload.attributes = attribs;
|
||||
|
||||
}
|
||||
25
belly/bin/data/shaders/raytrace/shader.ray-hit-closest.glsl
Normal file
25
belly/bin/data/shaders/raytrace/shader.ray-hit-closest.glsl
Normal file
@ -0,0 +1,25 @@
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_EXT_nonuniform_qualifier : 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 RT 1
|
||||
#define COMPUTE 1
|
||||
|
||||
#include "../common/macros.h"
|
||||
#include "../common/structs.h"
|
||||
|
||||
layout(location = 0) rayPayloadInEXT RayTracePayload payload;
|
||||
|
||||
hitAttributeEXT vec2 attribs;
|
||||
|
||||
void main() {
|
||||
payload.hit = true;
|
||||
payload.instanceID = gl_InstanceCustomIndexEXT;
|
||||
payload.primitiveID = gl_PrimitiveID;
|
||||
payload.attributes = attribs;
|
||||
}
|
||||
15
belly/bin/data/shaders/raytrace/shader.ray-miss.glsl
Normal file
15
belly/bin/data/shaders/raytrace/shader.ray-miss.glsl
Normal file
@ -0,0 +1,15 @@
|
||||
#version 460
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#pragma shader_stage(miss)
|
||||
|
||||
#define RT 1
|
||||
#define COMPUTE 1
|
||||
|
||||
#include "../common/macros.h"
|
||||
#include "../common/structs.h"
|
||||
|
||||
layout(location = 0) rayPayloadInEXT RayTracePayload payload;
|
||||
|
||||
void main() {
|
||||
payload.hit = false;
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"engine": {
|
||||
"scenes": {
|
||||
"start": "StartMenu",
|
||||
"start": "SourceEngine",
|
||||
"matrix": { "reverseInfinite": true },
|
||||
"meshes": { "interleaved": false },
|
||||
"lights": { "enabled": true,
|
||||
@ -31,10 +31,10 @@
|
||||
"vxgi": {
|
||||
"limiter": 0.5,
|
||||
// "limiter": 0.125,
|
||||
"size": 128,
|
||||
"size": 192,
|
||||
"dispatch": 8,
|
||||
"cascades": 3,
|
||||
"cascadePower": 3,
|
||||
"cascadePower": 1.5,
|
||||
"granularity": 12,
|
||||
"voxelizeScale": 1,
|
||||
"occlusionFalloff": 2,
|
||||
@ -57,37 +57,23 @@
|
||||
}
|
||||
},
|
||||
"graph": {
|
||||
"initial buffer elements": 131072
|
||||
"initial buffer elements": 1024
|
||||
},
|
||||
"ext": {
|
||||
"vulkan": {
|
||||
"version": 1.3,
|
||||
"validation": { "enabled": false,
|
||||
"filters": [
|
||||
"0x35d7ea98", // VUID-vkUpdateDescriptorSets-None-03047 ()
|
||||
// "0x4dae5635" // UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout
|
||||
|
||||
"0x4dae5635", // UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout (false positive for cubemaps)
|
||||
"0x609a13b", // UNASSIGNED-CoreValidation-Shader-OutputNotConsumed (from depth-only calls)
|
||||
"0x23e43bb7", // UNASSIGNED-CoreValidation-Shader-InputNotProduced (from depth-only calls)
|
||||
|
||||
"0x71500fba", // VUID-vkDestroyDevice-device-00378 (don't care about a clean cleanup)
|
||||
"0x7d560045", // VUID-vkCmdPipelineBarrier-dstStageMask-06462 (false positive, pipeline barrier for BLAS)
|
||||
|
||||
"0xde55a405", // VUID-VkDescriptorImageInfo-imageLayout-00344 (bitches because )
|
||||
"0x9410d614", // VUID-vkCmdDrawIndexedIndirect-None-02699 (same as above)
|
||||
|
||||
"0x97c889fd", // VUID-VkBufferDeviceAddressInfo-buffer-02601 (false positive, lies about not setting flags when I explicitly set flags for scratch)
|
||||
"0xea5edaf3" // VUID-vkCmdBuildAccelerationStructuresKHR-pInfos-03674 (same as above)
|
||||
|
||||
// "0x9cacd67a" // UNASSIGNED-CoreValidation-DrawState-QueryNotReset (false positive)
|
||||
|
||||
// "0xe91b58a0" // VUID-vkCmdDrawIndexed-None-02686 (?)
|
||||
|
||||
// "0x124ffb34", // VUID-VkImageMemoryBarrier-oldLayout-01197 (hacky bloom-shit)
|
||||
// "0x8ab1932c", // VUID-VkImageViewCreateInfo-imageViewType-04973 (hacky bloom-shit)
|
||||
|
||||
// "0x8e1000ad", // VUID-vkCmdDrawIndexedIndirect-None-04008 (bitches without nullDescriptor)
|
||||
// "0x9dd97212", // VUID-vkCmdDrawIndexedIndirect-None-02721 (bitches without nullDescriptor)
|
||||
// "0x36481fcb", // VUID-vkCmdBindVertexBuffers-pBuffers-04001 (bitches without nullDescriptor)
|
||||
"0x609a13b" // UNASSIGNED-CoreValidation-Shader-OutputNotConsumed (from depth-only calls)
|
||||
,"0x141cb623" // UNASSIGNED-Threading-MultipleThreads ("false-positive" multithreading)
|
||||
,"0xe5d1743c" // VUID-vkCmdDispatch-None-02699 (problem when using VXGI)
|
||||
,"0x71500fba" // VUID-vkDestroyDevice-device-00378 (don't care about a clean cleanup)
|
||||
,"0x35d7ea98" // VUID-vkUpdateDescriptorSets-None-03047 (bitches without VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT or VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT)
|
||||
,"0x8e1000ad" // VUID-vkCmdDrawIndexedIndirect-None-04008 (bitches without nullDescriptor)
|
||||
,"0x9dd97212" // VUID-vkCmdDrawIndexedIndirect-None-02721 (bitches without nullDescriptor)
|
||||
,"0x36481fcb" // VUID-vkCmdBindVertexBuffers-pBuffers-04001 (bitches without nullDescriptor)
|
||||
]
|
||||
},
|
||||
"framebuffer": {
|
||||
@ -98,20 +84,23 @@
|
||||
// "size": [ 960, 540 ]
|
||||
// "size": [ 640, 480 ]
|
||||
},
|
||||
"gpu": 1,
|
||||
"gpu": 7817,
|
||||
"experimental": {
|
||||
"rebuild on tick begin": false,
|
||||
"batch queue submissions": true,
|
||||
"dedicated thread": true
|
||||
"dedicated thread": false,
|
||||
"memory budget": false
|
||||
},
|
||||
"invariant": {
|
||||
"default stage buffers": true
|
||||
},
|
||||
"invariant": {},
|
||||
"pipelines": {
|
||||
"deferred": true,
|
||||
"vsync": false,
|
||||
"hdr": false,
|
||||
"vsync": true,
|
||||
"hdr": true,
|
||||
"vxgi": false,
|
||||
"culling": false,
|
||||
"bloom": false,
|
||||
"culling": true,
|
||||
"bloom": true,
|
||||
"rt": false,
|
||||
"postProcess": false,
|
||||
"fsr": false
|
||||
@ -122,62 +111,117 @@
|
||||
"normal": "R16G16B16A16_SFLOAT",
|
||||
"position": "R16G16B16A16_SFLOAT"
|
||||
},
|
||||
"features": [
|
||||
"shaderDrawParameters",
|
||||
"multiDrawIndirect",
|
||||
"fillModeNonSolid",
|
||||
"wideLines",
|
||||
"independentBlend",
|
||||
"deviceCoherentMemory",
|
||||
"robustBufferAccess",
|
||||
"samplerAnisotropy",
|
||||
"sampleRateShading",
|
||||
"nullDescriptor",
|
||||
"fragmentStoresAndAtomics",
|
||||
"geometryShader",
|
||||
"multiViewport",
|
||||
"shaderInt16",
|
||||
"shaderFloat16",
|
||||
"shaderInt64",
|
||||
"shaderFloat64",
|
||||
"shaderSubgroupClock",
|
||||
"shaderSampledImageArrayDynamicIndexing",
|
||||
"shaderStorageImageArrayDynamicIndexing",
|
||||
"shaderStorageImageMultisample",
|
||||
// 1.2 features
|
||||
"descriptorIndexing",
|
||||
"versions": {
|
||||
"1.0": {
|
||||
"extensions": {
|
||||
"instance": [],
|
||||
"device": [
|
||||
"VK_KHR_swapchain"
|
||||
]
|
||||
},
|
||||
"features": [
|
||||
"shaderDrawParameters",
|
||||
"multiDrawIndirect",
|
||||
"fillModeNonSolid",
|
||||
"wideLines",
|
||||
"independentBlend",
|
||||
"deviceCoherentMemory",
|
||||
"robustBufferAccess",
|
||||
"samplerAnisotropy",
|
||||
"sampleRateShading"
|
||||
],
|
||||
"featureChain": []
|
||||
},
|
||||
"1.1": {
|
||||
"extensions": {
|
||||
"instance": [
|
||||
"VK_KHR_get_physical_device_properties2"
|
||||
,"VK_KHR_get_surface_capabilities2"
|
||||
],
|
||||
"device": [
|
||||
"VK_EXT_memory_budget"
|
||||
,"VK_EXT_descriptor_indexing"
|
||||
,"VK_KHR_buffer_device_address"
|
||||
]
|
||||
},
|
||||
"features": [
|
||||
"nullDescriptor"
|
||||
,"fragmentStoresAndAtomics"
|
||||
,"geometryShader"
|
||||
,"multiViewport"
|
||||
,"shaderInt16"
|
||||
,"shaderFloat16"
|
||||
,"shaderInt64"
|
||||
,"shaderFloat64"
|
||||
,"shaderSubgroupClock"
|
||||
,"shaderSampledImageArrayDynamicIndexing"
|
||||
,"shaderStorageImageArrayDynamicIndexing"
|
||||
,"shaderStorageImageMultisample"
|
||||
|
||||
,"shaderSampledImageArrayNonUniformIndexing"
|
||||
,"shaderStorageImageArrayNonUniformIndexing"
|
||||
|
||||
"shaderOutputViewportIndex",
|
||||
"shaderOutputLayer",
|
||||
,"descriptorIndexing"
|
||||
,"bufferDeviceAddress"
|
||||
],
|
||||
"featureChain": [
|
||||
"physicalDevice2"
|
||||
,"shaderDrawParameters"
|
||||
,"robustness"
|
||||
,"shaderClock"
|
||||
|
||||
"shaderSampledImageArrayNonUniformIndexing",
|
||||
"shaderStorageImageArrayNonUniformIndexing",
|
||||
"runtimeDescriptorArray",
|
||||
"descriptorBindingVariableDescriptorCount",
|
||||
,"descriptorIndexing"
|
||||
,"bufferDeviceAddress"
|
||||
]
|
||||
},
|
||||
"1.2": {
|
||||
"extensions": {
|
||||
"instance": [
|
||||
"VK_KHR_get_physical_device_properties2",
|
||||
"VK_KHR_get_surface_capabilities2"
|
||||
],
|
||||
"device": [
|
||||
"VK_KHR_deferred_host_operations"
|
||||
,"VK_EXT_shader_viewport_index_layer"
|
||||
,"VK_KHR_spirv_1_4"
|
||||
,"VK_KHR_shader_float_controls"
|
||||
,"VK_KHR_shader_clock"
|
||||
,"VK_EXT_subgroup_size_control"
|
||||
,"VK_KHR_acceleration_structure"
|
||||
,"VK_KHR_ray_tracing_pipeline"
|
||||
,"VK_KHR_ray_query"
|
||||
|
||||
"hostQueryReset",
|
||||
"bufferDeviceAddress"
|
||||
],
|
||||
"extensions": {
|
||||
"instance": [
|
||||
"VK_KHR_get_physical_device_properties2",
|
||||
"VK_KHR_get_surface_capabilities2"
|
||||
],
|
||||
"device": [
|
||||
"VK_KHR_swapchain",
|
||||
"VK_EXT_shader_viewport_index_layer",
|
||||
"VK_KHR_acceleration_structure",
|
||||
"VK_KHR_ray_tracing_pipeline",
|
||||
"VK_KHR_buffer_device_address",
|
||||
"VK_KHR_deferred_host_operations",
|
||||
"VK_EXT_descriptor_indexing",
|
||||
"VK_KHR_spirv_1_4",
|
||||
"VK_KHR_shader_float_controls",
|
||||
"VK_KHR_shader_clock",
|
||||
"VK_KHR_ray_query",
|
||||
"VK_EXT_subgroup_size_control",
|
||||
"VK_AMD_shader_explicit_vertex_parameter" // "VK_KHR_fragment_shader_barycentric"
|
||||
]
|
||||
// ,"VK_AMD_shader_explicit_vertex_parameter"
|
||||
// ,"VK_KHR_fragment_shader_barycentric"
|
||||
]
|
||||
},
|
||||
"features": [
|
||||
"hostQueryReset",
|
||||
|
||||
"runtimeDescriptorArray",
|
||||
"descriptorBindingVariableDescriptorCount",
|
||||
|
||||
"shaderOutputViewportIndex",
|
||||
"shaderOutputLayer"
|
||||
],
|
||||
"featureChain": [
|
||||
"physicalDeviceVulkan12"
|
||||
// for ray-tracing
|
||||
,"fragmentShaderBarycentric"
|
||||
,"rayTracingPipeline"
|
||||
,"rayQuery"
|
||||
,"accelerationStructure"
|
||||
,"subgroupSizeControl"
|
||||
]
|
||||
},
|
||||
"1.3": {
|
||||
"extensions": {
|
||||
"instance": [],
|
||||
"device": []
|
||||
},
|
||||
"features": [],
|
||||
"featureChain": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"opengl": {
|
||||
@ -226,7 +270,7 @@
|
||||
},
|
||||
"reactphysics": {
|
||||
"timescale": 0.01666666666,
|
||||
"interpolate": false,
|
||||
"interpolate": true,
|
||||
"gravity": {
|
||||
"mode": "universal",
|
||||
"constant": 6.67408e-11
|
||||
@ -276,7 +320,7 @@
|
||||
"render modes": { "gui": true, "deferred": true },
|
||||
"limiters": {
|
||||
"deltaTime": 5,
|
||||
"framerate": "auto"
|
||||
"framerate": 0 // "auto"
|
||||
},
|
||||
"threads": {
|
||||
"workers" : "auto",
|
||||
@ -306,18 +350,21 @@
|
||||
},
|
||||
"hooks": {
|
||||
"defer lazy calls": true
|
||||
},
|
||||
"scene": {
|
||||
"print task calls": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"window" : {
|
||||
"terminal" : {
|
||||
"ncurses" : false,
|
||||
"visible" : false
|
||||
"visible" : true
|
||||
},
|
||||
"keyboard" : {
|
||||
"repeat" : false
|
||||
},
|
||||
"cursor" : {
|
||||
"mouse" : {
|
||||
"visible" : true,
|
||||
"center" : false,
|
||||
"sensitivity": [ 0.75, 0.75 ],
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Burger",
|
||||
"ignore": true,
|
||||
"ignore": false,
|
||||
"import": "/model.json",
|
||||
"assets": [
|
||||
// "/burger/burger.glb"
|
||||
|
||||
@ -28,8 +28,8 @@ if not timer:running() then timer:start() end
|
||||
|
||||
local playSound = function( key )
|
||||
local url = "/ui/" .. key .. ".ogg"
|
||||
local assetLoader = scene:getComponent("Asset")
|
||||
assetLoader:cache(ent:formatHookName("asset:Load.%UID%"), string.resolveURI(url))
|
||||
-- local assetLoader = scene:getComponent("Asset")
|
||||
-- assetLoader:cache(ent:formatHookName("asset:Load.%UID%"), string.resolveURI(url))
|
||||
end
|
||||
local destination = function( obj, x, y, z )
|
||||
local static = Static.get(obj)
|
||||
|
||||
@ -48,8 +48,8 @@ destination(children.quit, -1.5, nil, 0)
|
||||
|
||||
local playSound = function( key )
|
||||
local url = "/ui/" .. key .. ".ogg"
|
||||
local assetLoader = scene:getComponent("Asset")
|
||||
assetLoader:cache(soundEmitter:formatHookName("asset:Load.%UID%"), string.resolveURI(url), "")
|
||||
-- local assetLoader = scene:getComponent("Asset")
|
||||
-- assetLoader:cache(soundEmitter:formatHookName("asset:Load.%UID%"), string.resolveURI(url), "")
|
||||
end
|
||||
|
||||
ent:addHook("menu:Close.%UID%", function( json )
|
||||
|
||||
@ -24,12 +24,12 @@
|
||||
"power": 100,
|
||||
"fov": 90,
|
||||
"bias": {
|
||||
"constant": 1.25,
|
||||
"slope": 1.75,
|
||||
"shader": 0.00000005 // 0.000005 //0.000000005
|
||||
"constant": 1,
|
||||
"slope": 1,
|
||||
"shader": 0.00005 // 0.000005 //0.000000005
|
||||
},
|
||||
"radius": [0.25, 0],
|
||||
"resolution": 256,
|
||||
"radius": [0.5, 0],
|
||||
"resolution": 1024,
|
||||
"shadows": true,
|
||||
"dynamic": true
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Player: Model",
|
||||
"ignore": true,
|
||||
"ignore": false,
|
||||
"import": "/model.json",
|
||||
"assets": [
|
||||
"/player/bear.glb"
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
[ 0, 0, 0, 0 ]
|
||||
],
|
||||
"shader": {
|
||||
"mode": 1,
|
||||
"mode": 0,
|
||||
"scalar": 16,
|
||||
"parameters": [ 0, 0, 0, "time" ]
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"metadata": {
|
||||
"graph": {
|
||||
// "renderer": { "separate": true },
|
||||
"baking": { "enabled": false },
|
||||
"baking": { "enabled": true },
|
||||
"tags": {
|
||||
// exact matches
|
||||
"worldspawn": {
|
||||
@ -19,6 +19,7 @@
|
||||
},
|
||||
"info_player_spawn": { "action": "attach", "filename": "./player.json", "transform": { "orientation": [ 0, 1, 0, 0 ] } },
|
||||
"light_environment": { "transform": { "orientation": [0,0,0,1] }, "light": {
|
||||
"color": [0.1, 0.1, 0.1],
|
||||
"power": 100000,
|
||||
"global": true,
|
||||
"bias": {
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
"import": "./base_sourceengine.json",
|
||||
"assets": [
|
||||
// { "filename": "./models/mds_mcdonalds.glb" }
|
||||
{ "filename": "./models/mds_mcdonalds/graph.json" }
|
||||
// { "filename": "/burger.json", "delay": 1 }
|
||||
{ "filename": "./models/mds_mcdonalds/graph.json" },
|
||||
{ "filename": "/burger.json", "delay": 1 }
|
||||
],
|
||||
"metadata": {
|
||||
"graph": {
|
||||
|
||||
@ -2,16 +2,16 @@
|
||||
"import": "/scene.json",
|
||||
"assets": [
|
||||
"./sourceengine.json"
|
||||
// "./loading.json"
|
||||
// { "filename": "./loading.json", "delay": 0.5 }
|
||||
],
|
||||
"metadata": {
|
||||
"light": {
|
||||
"ambient": [ 0, 0, 0 ],
|
||||
// "ambient": [ 0, 0, 0 ],
|
||||
// "ambient": [ 0.05, 0.05, 0.05 ],
|
||||
// "ambient": [ 0.15, 0.15, 0.15 ],
|
||||
// "ambient": [ 0.5, 0.5, 0.5 ],
|
||||
// "ambient": [ 0.8, 0.8, 0.8 ],
|
||||
// "ambient": [ 0.1, 0.1, 0.2 ],
|
||||
"ambient": [ 0.1, 0.1, 0.2 ],
|
||||
|
||||
"exposure": 0.125,
|
||||
"gamma": 2.2, // 2.2,
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
// { "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/msci/graph.json" }
|
||||
|
||||
// { "filename": "./models/medsci.glb" }
|
||||
// { "filename": "./models/medsci/graph.json" }
|
||||
|
||||
13
bin/data/shaders - 1.1/base/line/frag.glsl
Normal file
13
bin/data/shaders - 1.1/base/line/frag.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
layout (location = 0) in vec3 inPosition;
|
||||
layout (location = 1) in vec3 inColor;
|
||||
|
||||
layout (location = 0) out uvec2 outId;
|
||||
layout (location = 1) out vec2 outNormals;
|
||||
layout (location = 2) out vec4 outAlbedo;
|
||||
|
||||
void main() {
|
||||
outAlbedo = vec4(inColor, 1);
|
||||
}
|
||||
29
bin/data/shaders - 1.1/base/line/vert.glsl
Normal file
29
bin/data/shaders - 1.1/base/line/vert.glsl
Normal file
@ -0,0 +1,29 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec3 inColor;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 0) uniform Camera {
|
||||
Viewport viewport[PASSES];
|
||||
} camera;
|
||||
|
||||
layout (location = 0) out vec3 outPosition;
|
||||
layout (location = 1) out vec3 outColor;
|
||||
|
||||
void main() {
|
||||
outPosition = vec3(camera.viewport[PushConstant.pass].view * vec4(inPos.xyz, 1.0));
|
||||
outColor = inColor;
|
||||
|
||||
gl_Position = camera.viewport[PushConstant.pass].projection * camera.viewport[PushConstant.pass].view * vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
56
bin/data/shaders - 1.1/common/fog.h
Normal file
56
bin/data/shaders - 1.1/common/fog.h
Normal file
@ -0,0 +1,56 @@
|
||||
// Perlin Fog
|
||||
void fog( in Ray ray, inout vec3 i, float scale ) {
|
||||
if ( ubo.settings.fog.stepScale <= 0 || ubo.settings.fog.range.x == 0 || ubo.settings.fog.range.y == 0 ) return;
|
||||
#if FOG_RAY_MARCH
|
||||
const float range = ubo.settings.fog.range.y;
|
||||
const vec3 boundsMin = vec3(-range,-range,-range) + ray.origin;
|
||||
const vec3 boundsMax = vec3(range,range,range) + ray.origin;
|
||||
const int numSteps = int(length(boundsMax - boundsMin) * ubo.settings.fog.stepScale );
|
||||
|
||||
const vec2 rayBoxInfo = rayBoxDst( boundsMin, boundsMax, ray );
|
||||
const float dstToBox = rayBoxInfo.x;
|
||||
const float dstInsideBox = rayBoxInfo.y;
|
||||
const float depth = surface.position.eye.z;
|
||||
|
||||
const float aperture = 0; // PI * 0.5;
|
||||
const float coneCoefficient = 2.0 * tan(aperture * 0.5);
|
||||
|
||||
// march
|
||||
if ( 0 <= dstInsideBox && dstToBox <= depth ) {
|
||||
float stepSize = dstInsideBox / numSteps;
|
||||
float dstLimit = min( depth - dstToBox, dstInsideBox );
|
||||
float totalDensity = 0;
|
||||
float transmittance = 1;
|
||||
float lightFactor = scale;
|
||||
float coneDiameter = coneCoefficient * ray.distance;
|
||||
float level = aperture > 0 ? log2( coneDiameter ) : 0;
|
||||
float density = 0;
|
||||
vec3 uvw;
|
||||
ray.distance = dstToBox;
|
||||
while ( ray.distance < dstLimit ) {
|
||||
ray.distance += stepSize;
|
||||
ray.position = ray.origin + ray.direction * ray.distance;
|
||||
coneDiameter = coneCoefficient * ray.distance;
|
||||
level = aperture > 0 ? log2( coneDiameter ) : 0;
|
||||
uvw = ray.position * ubo.settings.fog.densityScale * 0.001 + ubo.settings.fog.offset * 0.01;
|
||||
density = max(0, textureLod(samplerNoise, uvw, level).r - ubo.settings.fog.densityThreshold) * ubo.settings.fog.densityMultiplier;
|
||||
if ( density > 0 ) {
|
||||
density = exp(-density * stepSize * ubo.settings.fog.absorbtion);
|
||||
transmittance *= density;
|
||||
lightFactor *= density;
|
||||
if ( transmittance < 0.1 ) break;
|
||||
}
|
||||
}
|
||||
i.rgb = mix(ubo.settings.fog.color.rgb, i.rgb, transmittance );
|
||||
}
|
||||
#endif
|
||||
#if FOG_BASIC
|
||||
const vec3 color = ubo.settings.fog.color.rgb;
|
||||
const float inner = ubo.settings.fog.range.x;
|
||||
const float outer = ubo.settings.fog.range.y * scale;
|
||||
const float distance = length(-surface.position.eye);
|
||||
const float factor = clamp( (distance - inner) / (outer - inner), 0.0, 1.0 );
|
||||
|
||||
i.rgb = mix(i.rgb, color, factor);
|
||||
#endif
|
||||
}
|
||||
419
bin/data/shaders - 1.1/common/functions.h
Normal file
419
bin/data/shaders - 1.1/common/functions.h
Normal file
@ -0,0 +1,419 @@
|
||||
// Helper Functions
|
||||
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); }
|
||||
//
|
||||
float mipLevel( in vec2 dx_vtc, in vec2 dy_vtc ) {
|
||||
const float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
|
||||
return 0.5 * log2(delta_max_sqr);
|
||||
// return max(0.0, 0.5 * log2(delta_max_sqr) - 1.0);
|
||||
|
||||
// return 0.5 * log2(max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)));
|
||||
}
|
||||
float mipLevels( vec2 size ) {
|
||||
return floor(log2(max(size.x, size.y)));
|
||||
}
|
||||
float mipLevels( ivec2 size ) {
|
||||
return floor(log2(max(size.x, size.y)));
|
||||
}
|
||||
//
|
||||
void toneMap( inout vec3 color, float exposure ) {
|
||||
color.rgb = vec3(1.0) - exp(-color.rgb * exposure);
|
||||
}
|
||||
void gammaCorrect( inout vec3 color, float gamma ) {
|
||||
color.rgb = pow(color.rgb, vec3(1.0 / gamma));
|
||||
}
|
||||
void toneMap( inout vec4 color, float exposure ) { toneMap(color.rgb, exposure); }
|
||||
void gammaCorrect( inout vec4 color, float gamma ) { gammaCorrect(color.rgb, gamma); }
|
||||
//
|
||||
uint tea(uint val0, uint val1) {
|
||||
uint v0 = val0;
|
||||
uint v1 = val1;
|
||||
uint s0 = 0;
|
||||
|
||||
#pragma unroll 16
|
||||
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); }
|
||||
//
|
||||
float ndfGGX(float cosLh, float roughness) {
|
||||
const float alpha = roughness * roughness;
|
||||
const float alphaSq = alpha * alpha;
|
||||
const float denom = (cosLh * cosLh) * (alphaSq - 1.0) + 1.0;
|
||||
return alphaSq / (PI * denom * denom);
|
||||
}
|
||||
float gaSchlickG1(float cosTheta, float k) { return cosTheta / (cosTheta * (1.0 - k) + k); }
|
||||
float gaSchlickGGX(float cosLi, float cosLo, float roughness) {
|
||||
const float r = roughness + 1.0;
|
||||
const float k = (r * r) / 8.0;
|
||||
return gaSchlickG1(cosLi, k) * gaSchlickG1(cosLo, k);
|
||||
}
|
||||
vec3 fresnelSchlick(vec3 F0, float cosTheta) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); }
|
||||
//
|
||||
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;
|
||||
}
|
||||
//
|
||||
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)); }
|
||||
float wrap( float i ) { return fract(i); }
|
||||
vec2 wrap( vec2 uv ) { return vec2( wrap( uv.x ), wrap( uv.y ) ); }
|
||||
vec3 orthogonal(vec3 u){
|
||||
u = normalize(u);
|
||||
const vec3 v = vec3(0.99146, 0.11664, 0.05832); // Pick any normalized vector.
|
||||
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);
|
||||
}
|
||||
float gauss( float x, float sigma ) {
|
||||
return (1.0 / (2.0 * 3.14157 * sigma) * exp(-(x*x) / (2.0 * sigma)));
|
||||
}
|
||||
bool enabled( uint flag, uint bit ) {
|
||||
return (flag & (1 << bit)) != 0;
|
||||
}
|
||||
vec3 decodeNormals( vec2 enc ) {
|
||||
const vec2 ang = enc*2-1;
|
||||
const vec2 scth = vec2( sin(ang.x * PI), cos(ang.x * PI) );
|
||||
const vec2 scphi = vec2(sqrt(1.0 - ang.y*ang.y), ang.y);
|
||||
return normalize( vec3(scth.y*scphi.x, scth.x*scphi.x, scphi.y) );
|
||||
}
|
||||
vec2 encodeNormals( vec3 n ) {
|
||||
// float p = sqrt(n.z*8+8);
|
||||
// return n.xy/p + 0.5;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
bool validTextureIndex( int textureIndex ) {
|
||||
return 0 <= textureIndex && textureIndex < MAX_TEXTURES;
|
||||
}
|
||||
#if MAX_CUBEMAPS
|
||||
bool validCubemapIndex( int textureIndex ) {
|
||||
return 0 <= textureIndex && textureIndex < MAX_CUBEMAPS;
|
||||
}
|
||||
#endif
|
||||
#if !BLOOM && (DEFERRED || FRAGMENT || COMPUTE || RT)
|
||||
bool validTextureIndex( uint id ) {
|
||||
return 0 <= id && id < MAX_TEXTURES;
|
||||
}
|
||||
bool validTextureIndex( uint start, int offset ) {
|
||||
return 0 <= offset && start + offset < MAX_TEXTURES;
|
||||
}
|
||||
uint textureIndex( uint start, int offset ) {
|
||||
return start + offset;
|
||||
}
|
||||
vec4 sampleTexture( uint id, vec2 uv ) {
|
||||
const Texture t = textures[id];
|
||||
return texture( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ) );
|
||||
}
|
||||
vec4 sampleTexture( uint id, vec2 uv, float mip ) {
|
||||
#if QUERY_MIPMAP
|
||||
return sampleTexture( id, uv );
|
||||
#else
|
||||
const Texture t = textures[id];
|
||||
return textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
|
||||
#endif
|
||||
}
|
||||
vec4 sampleTexture( uint id, vec3 uvm ) { return sampleTexture( id, uvm.xy, uvm.z ); }
|
||||
vec4 sampleTexture( uint id ) { return sampleTexture( id, surface.uv.xy, surface.uv.z ); }
|
||||
vec4 sampleTexture( uint id, float mip ) { return sampleTexture( id, surface.uv.xy, mip ); }
|
||||
#endif
|
||||
vec2 rayBoxDst( vec3 boundsMin, vec3 boundsMax, in Ray ray ) {
|
||||
const vec3 t0 = (boundsMin - ray.origin) / ray.direction;
|
||||
const vec3 t1 = (boundsMax - ray.origin) / ray.direction;
|
||||
const vec3 tmin = min(t0, t1);
|
||||
const vec3 tmax = max(t0, t1);
|
||||
const float tStart = max(0, max( max(tmin.x, tmin.y), tmin.z ));
|
||||
const float tEnd = max(0, min( tmax.x, min(tmax.y, tmax.z) ) - tStart);
|
||||
return vec2(tStart, tEnd);
|
||||
}
|
||||
#if VXGI
|
||||
float cascadePower( uint x ) {
|
||||
return pow(1 + x, ubo.settings.vxgi.cascadePower);
|
||||
// return max( 1, x * ubo.settings.vxgi.cascadePower );
|
||||
}
|
||||
#endif
|
||||
#if FRAGMENT
|
||||
void whitenoise(inout vec3 color, const vec4 parameters) {
|
||||
const float flicker = parameters.x;
|
||||
const float pieces = parameters.y;
|
||||
const float blend = parameters.z;
|
||||
const float time = parameters.w;
|
||||
if ( blend < 0.0001 ) return;
|
||||
const float freq = sin(pow(mod(time, flicker) + flicker, 1.9));
|
||||
const float whiteNoise = rand2( floor(gl_FragCoord.xy / pieces) + mod(time, freq) );
|
||||
color = mix( color, vec3(whiteNoise), blend );
|
||||
}
|
||||
vec4 resolve( subpassInputMS t, const uint samples ) {
|
||||
vec4 resolved = vec4(0);
|
||||
for ( int i = 0; i < samples; ++i ) resolved += subpassLoad(t, i);
|
||||
resolved /= vec4(samples);
|
||||
return resolved;
|
||||
}
|
||||
uvec4 resolve( usubpassInputMS t, const uint samples ) {
|
||||
uvec4 resolved = uvec4(0);
|
||||
for ( int i = 0; i < samples; ++i ) resolved += subpassLoad(t, i);
|
||||
resolved /= uvec4(samples);
|
||||
return resolved;
|
||||
}
|
||||
#endif
|
||||
vec4 resolve( sampler2DMS t, ivec2 uv ) {
|
||||
vec4 resolved = vec4(0);
|
||||
int samples = textureSamples(t);
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
resolved += texelFetch(t, uv, i);
|
||||
}
|
||||
resolved /= float(samples);
|
||||
return resolved;
|
||||
}
|
||||
//
|
||||
|
||||
vec2 encodeBarycentrics( vec3 barycentric ) {
|
||||
return barycentric.yz;
|
||||
}
|
||||
vec3 decodeBarycentrics( vec2 attributes ) {
|
||||
return vec3(
|
||||
1.0 - attributes.x - attributes.y,
|
||||
attributes.x,
|
||||
attributes.y
|
||||
);
|
||||
}
|
||||
#if DEFERRED_SAMPLING
|
||||
void populateSurfaceMaterial() {
|
||||
const Material material = materials[surface.instance.materialID];
|
||||
surface.material.albedo = material.colorBase;
|
||||
surface.material.metallic = material.factorMetallic;
|
||||
surface.material.roughness = material.factorRoughness;
|
||||
surface.material.occlusion = material.factorOcclusion;
|
||||
surface.light = material.colorEmissive;
|
||||
|
||||
if ( validTextureIndex( material.indexAlbedo ) ) {
|
||||
surface.material.albedo *= sampleTexture( material.indexAlbedo );
|
||||
}
|
||||
// OPAQUE
|
||||
if ( material.modeAlpha == 0 ) {
|
||||
surface.material.albedo.a = 1;
|
||||
// BLEND
|
||||
} else if ( material.modeAlpha == 1 ) {
|
||||
|
||||
// MASK
|
||||
} else if ( material.modeAlpha == 2 ) {
|
||||
|
||||
}
|
||||
// Lightmap
|
||||
if ( (/*surface.subID++ > 0 ||*/ bool(ubo.settings.lighting.useLightmaps)) && validTextureIndex( surface.instance.lightmapID ) ) {
|
||||
vec4 light = sampleTexture( surface.instance.lightmapID, surface.st );
|
||||
/*surface.material.lightmapped = light.a > 0.000000001;
|
||||
if ( surface.material.lightmapped )*/ surface.light += surface.material.albedo * light;
|
||||
} else {
|
||||
surface.material.lightmapped = false;
|
||||
}
|
||||
// Emissive textures
|
||||
if ( validTextureIndex( material.indexEmissive ) ) {
|
||||
surface.light += sampleTexture( material.indexEmissive );
|
||||
}
|
||||
// Occlusion map
|
||||
if ( validTextureIndex( material.indexOcclusion ) ) {
|
||||
surface.material.occlusion = sampleTexture( material.indexOcclusion ).r;
|
||||
}
|
||||
// Metallic/Roughness map
|
||||
if ( validTextureIndex( material.indexMetallicRoughness ) ) {
|
||||
vec4 samp = sampleTexture( material.indexMetallicRoughness );
|
||||
surface.material.metallic = samp.r;
|
||||
surface.material.roughness = samp.g;
|
||||
}
|
||||
// Normals
|
||||
if ( validTextureIndex( material.indexNormal ) && surface.tangent.world != vec3(0) ) {
|
||||
surface.normal.world = surface.tbn * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - vec3(1.0));
|
||||
}
|
||||
{
|
||||
surface.normal.eye = normalize(vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) ));
|
||||
}
|
||||
|
||||
surface.light *= surface.material.albedo;
|
||||
}
|
||||
|
||||
bool isValidAddress( uint64_t address ) {
|
||||
#if UINT64_ENABLED
|
||||
return bool(address);
|
||||
#else
|
||||
return bool(address.x) && bool(address.y);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BUFFER_REFERENCE
|
||||
void populateSurface( InstanceAddresses instanceAddresses, uvec3 indices ) {
|
||||
Triangle triangle;
|
||||
Vertex points[3];
|
||||
|
||||
if ( isValidAddress(instanceAddresses.vertex) ) {
|
||||
Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex));
|
||||
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_] = vertices.v[/*triangle.*/indices[_]];
|
||||
} else {
|
||||
if ( isValidAddress(instanceAddresses.position) ) {
|
||||
VPos buf = VPos(nonuniformEXT(instanceAddresses.position));
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].position = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( isValidAddress(instanceAddresses.uv) ) {
|
||||
VUv buf = VUv(nonuniformEXT(instanceAddresses.uv));
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].uv = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( isValidAddress(instanceAddresses.st) ) {
|
||||
VSt buf = VSt(nonuniformEXT(instanceAddresses.st));
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].st = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( isValidAddress(instanceAddresses.normal) ) {
|
||||
VNormal buf = VNormal(nonuniformEXT(instanceAddresses.normal));
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].normal = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
if ( isValidAddress(instanceAddresses.tangent) ) {
|
||||
VTangent buf = VTangent(nonuniformEXT(instanceAddresses.tangent));
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/points[_].tangent = buf.v[/*triangle.*/indices[_]];
|
||||
}
|
||||
}
|
||||
|
||||
#if BARYCENTRIC_CALCULATE
|
||||
{
|
||||
const vec3 p = vec3(inverse( surface.instance.model ) * vec4(surface.position.world, 1));
|
||||
|
||||
const vec3 a = points[0].position;
|
||||
const vec3 b = points[1].position;
|
||||
const vec3 c = points[2].position;
|
||||
|
||||
const vec3 v0 = b - a;
|
||||
const vec3 v1 = c - a;
|
||||
const vec3 v2 = p - a;
|
||||
const float d00 = dot(v0, v0);
|
||||
const float d01 = dot(v0, v1);
|
||||
const float d11 = dot(v1, v1);
|
||||
const float d20 = dot(v2, v0);
|
||||
const float d21 = dot(v2, v1);
|
||||
const float denom = d00 * d11 - d01 * d01;
|
||||
|
||||
const float v = (d11 * d20 - d01 * d21) / denom;
|
||||
const float w = (d00 * d21 - d01 * d20) / denom;
|
||||
const float u = 1.0f - v - w;
|
||||
|
||||
surface.barycentric = vec3( u, v, w );
|
||||
}
|
||||
#endif
|
||||
|
||||
triangle.geomNormal = normalize(cross(points[1].position - points[0].position, points[2].position - points[0].position));
|
||||
triangle.point.normal = /*triangle.*/points[0].normal * surface.barycentric[0] + /*triangle.*/points[1].normal * surface.barycentric[1] + /*triangle.*/points[2].normal * surface.barycentric[2];
|
||||
|
||||
triangle.point.position = /*triangle.*/points[0].position * surface.barycentric[0] + /*triangle.*/points[1].position * surface.barycentric[1] + /*triangle.*/points[2].position * surface.barycentric[2];
|
||||
triangle.point.uv = /*triangle.*/points[0].uv * surface.barycentric[0] + /*triangle.*/points[1].uv * surface.barycentric[1] + /*triangle.*/points[2].uv * surface.barycentric[2];
|
||||
triangle.point.st = /*triangle.*/points[0].st * surface.barycentric[0] + /*triangle.*/points[1].st * surface.barycentric[1] + /*triangle.*/points[2].st * surface.barycentric[2];
|
||||
triangle.point.tangent = /*triangle.*/points[0].tangent * surface.barycentric[0] + /*triangle.*/points[1].tangent * surface.barycentric[1] + /*triangle.*/points[2].tangent * surface.barycentric[2];
|
||||
|
||||
|
||||
if ( triangle.point.tangent != vec3(0) ) {
|
||||
surface.tangent.world = normalize(vec3( surface.instance.model * vec4(triangle.point.tangent, 0.0) ));
|
||||
vec3 bitangent = normalize(vec3( surface.instance.model * vec4(cross( triangle.point.normal, triangle.point.tangent ), 0.0) ));
|
||||
surface.tbn = mat3(surface.tangent.world, bitangent, triangle.point.normal);
|
||||
}
|
||||
|
||||
// bind position
|
||||
#if 1 || BARYCENTRIC_CALCULATE
|
||||
{
|
||||
surface.position.world = vec3( surface.instance.model * vec4(triangle.point.position, 1.0 ) );
|
||||
surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.position.world, 1.0) );
|
||||
}
|
||||
#endif
|
||||
// bind normals
|
||||
{
|
||||
surface.normal.world = normalize(vec3( surface.instance.model * vec4(triangle.point.normal, 0.0 ) ));
|
||||
// surface.normal.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0.0) );
|
||||
}
|
||||
// bind UVs
|
||||
{
|
||||
surface.uv.xy = triangle.point.uv;
|
||||
surface.uv.z = 0;
|
||||
surface.st.xy = triangle.point.st;
|
||||
surface.st.z = 0;
|
||||
}
|
||||
|
||||
populateSurfaceMaterial();
|
||||
}
|
||||
void populateSurface( uint instanceID, uint primitiveID ) {
|
||||
surface.fragment = vec4(0);
|
||||
surface.light = vec4(0);
|
||||
surface.instance = instances[instanceID];
|
||||
|
||||
const InstanceAddresses instanceAddresses = instanceAddresses[instanceID];
|
||||
if ( !isValidAddress(instanceAddresses.index) ) return;
|
||||
const DrawCommand drawCommand = Indirects(nonuniformEXT(instanceAddresses.indirect)).dc[instanceAddresses.drawID];
|
||||
const uint triangleID = primitiveID + (drawCommand.indexID / 3);
|
||||
uvec3 indices = Indices(nonuniformEXT(instanceAddresses.index)).i[triangleID];
|
||||
#pragma unroll 3
|
||||
for ( uint _ = 0; _ < 3; ++_ ) /*triangle.*/indices[_] += drawCommand.vertexID;
|
||||
|
||||
populateSurface( instanceAddresses, indices );
|
||||
}
|
||||
void populateSurface( RayTracePayload payload ) {
|
||||
surface.fragment = vec4(0);
|
||||
surface.light = vec4(0);
|
||||
surface.instance = instances[payload.instanceID];
|
||||
|
||||
if ( !payload.hit ) return;
|
||||
surface.barycentric = decodeBarycentrics(payload.attributes);
|
||||
populateSurface( payload.instanceID, payload.primitiveID );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
66
bin/data/shaders - 1.1/common/lambert.h
Normal file
66
bin/data/shaders - 1.1/common/lambert.h
Normal file
@ -0,0 +1,66 @@
|
||||
float shadowFactor( const Light light, float def );
|
||||
void lambert() {
|
||||
// outcoming light from surface to eye
|
||||
const vec3 Lo = normalize( -surface.position.eye );
|
||||
// angle of outcoming light
|
||||
const float cosLo = max(0.0, dot(surface.normal.eye, Lo));
|
||||
|
||||
for ( uint i = 0, shadows = 0; i < MAX_LIGHTS; ++i ) {
|
||||
#if BAKING
|
||||
// skip if surface is a dynamic light, we aren't baking dynamic lights
|
||||
if ( lights[i].type < 0 ) continue;
|
||||
#else
|
||||
// skip if surface is already baked, and this isn't a dynamic light
|
||||
if ( surface.material.lightmapped && lights[i].type >= 0 ) continue;
|
||||
#endif
|
||||
if ( lights[i].power <= LIGHT_POWER_CUTOFF ) continue;
|
||||
if ( surface.material.lightmapped && lights[i].type >= 0 ) continue;
|
||||
|
||||
vec3 Li = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
|
||||
// magnitude of incoming light vector (for inverse-square attenuation)
|
||||
const float Lmagnitude = dot(Li, Li);
|
||||
// distance incoming light travels (reuse from above)
|
||||
const float Ldistance = sqrt(Lmagnitude);
|
||||
// "free" normalization, since we need to compute the above values anyways
|
||||
Li = Li / Ldistance;
|
||||
// attenuation factor
|
||||
// const float Lattenuation = 1.0 / (1 + (PI * Lmagnitude));
|
||||
const float Lattenuation = 1.0 / (1 + Lmagnitude);
|
||||
// skip if attenuation factor is too low
|
||||
// if ( Lattenuation <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// ray cast if our surface is occluded from the light
|
||||
const float Lshadow = 1; // ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
|
||||
// skip if our shadow factor is too low
|
||||
if ( Lshadow <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// light radiance
|
||||
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
|
||||
// skip if our radiance is too low
|
||||
// if ( Lr <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// halfway vector
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
// angle of incoming light
|
||||
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
|
||||
// angle of halfway light vector
|
||||
const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
|
||||
/*
|
||||
const vec3 Liu = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
|
||||
const vec3 Li = normalize(Liu);
|
||||
// const float Lattenuation = 1.0 / (PI * pow(length(Liu), 2.0));
|
||||
// const float Lattenuation = 1.0 / (1 + (PI * pow(length(Liu), 2.0)));
|
||||
const float Lattenuation = 1.0 / (1 + pow(length(Liu), 2.0));
|
||||
const float Lshadow = ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
|
||||
if ( lights[i].power * Lattenuation * Lshadow <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
|
||||
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
|
||||
// const vec3 Lh = normalize(Li + Lo);
|
||||
// const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
|
||||
*/
|
||||
|
||||
const vec3 diffuse = surface.material.albedo.rgb;
|
||||
const vec3 specular = vec3(0);
|
||||
|
||||
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
surface.light.a += lights[i].power * Lattenuation * Lshadow;
|
||||
}
|
||||
}
|
||||
11
bin/data/shaders - 1.1/common/light.h
Normal file
11
bin/data/shaders - 1.1/common/light.h
Normal file
@ -0,0 +1,11 @@
|
||||
float shadowFactor( const Light light, float def );
|
||||
|
||||
#if PBR
|
||||
#include "../common/pbr.h"
|
||||
#endif
|
||||
#if LAMBERT
|
||||
#include "../common/lambert.h"
|
||||
#endif
|
||||
#if PHONG
|
||||
#include "../common/phong.h"
|
||||
#endif
|
||||
102
bin/data/shaders - 1.1/common/macros.h
Normal file
102
bin/data/shaders - 1.1/common/macros.h
Normal file
@ -0,0 +1,102 @@
|
||||
#ifndef NO_NONUNIFORM_EXT
|
||||
#define NO_NONUNIFORM_EXT 0
|
||||
// enable if shaderNonUniform is not supported
|
||||
// Nvidia hardware does not require nonuniformEXT, but AMD does
|
||||
#endif
|
||||
|
||||
// implicit variables
|
||||
#ifndef MULTISAMPLING
|
||||
#define MULTISAMPLING 1
|
||||
#endif
|
||||
#ifndef MAX_MSAA_SAMPLES
|
||||
#define MAX_MSAA_SAMPLES 16
|
||||
#endif
|
||||
#ifndef MAX_TEXTURES
|
||||
#define MAX_TEXTURES TEXTURES
|
||||
#endif
|
||||
#ifndef MAX_LIGHTS
|
||||
#define MAX_LIGHTS ubo.settings.lengths.lights
|
||||
#endif
|
||||
#ifndef MAX_SHADOWS
|
||||
#define MAX_SHADOWS ubo.settings.lighting.maxShadows
|
||||
#endif
|
||||
#ifndef VIEW_MATRIX
|
||||
#define VIEW_MATRIX ubo.eyes[surface.pass].view
|
||||
#endif
|
||||
|
||||
// implicit shader settings
|
||||
#ifndef CAN_DISCARD
|
||||
#define CAN_DISCARD 1
|
||||
#endif
|
||||
#ifndef USE_LIGHTMAP
|
||||
#define USE_LIGHTMAP 1
|
||||
#endif
|
||||
#if VXGI
|
||||
#define VXGI_NDC 1
|
||||
#define VXGI_SHADOWS 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifndef FOG
|
||||
#define FOG 1
|
||||
#endif
|
||||
#ifndef FOG_RAY_MARCH
|
||||
#define FOG_RAY_MARCH 1
|
||||
#endif
|
||||
#ifndef WHITENOISE
|
||||
#define WHITENOISE 1
|
||||
#endif
|
||||
#ifndef GAMMA_CORRECT
|
||||
#define GAMMA_CORRECT 1
|
||||
#endif
|
||||
#ifndef TONE_MAP
|
||||
#define TONE_MAP 1
|
||||
#endif
|
||||
#ifndef PHONG
|
||||
#define PHONG 0
|
||||
#endif
|
||||
#ifndef LAMBERT
|
||||
#define LAMBERT 0
|
||||
#endif
|
||||
#ifndef PBR
|
||||
#define PBR 1
|
||||
#endif
|
||||
*/
|
||||
|
||||
#if NO_NONUNIFORM_EXT
|
||||
#define nonuniformEXT(X) X
|
||||
#else
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
#endif
|
||||
|
||||
#if !UINT64_ENABLED
|
||||
#define uint64_t uvec2
|
||||
#endif
|
||||
|
||||
// easy and accessible in one place
|
||||
#ifndef BARYCENTRIC
|
||||
#define BARYCENTRIC 0
|
||||
#endif
|
||||
#if BARYCENTRIC
|
||||
#ifndef BARYCENTRIC_CALCULATE
|
||||
#define BARYCENTRIC_CALCULATE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BUFFER_REFERENCE
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
#extension GL_EXT_buffer_reference : enable
|
||||
#extension GL_EXT_buffer_reference2 : enable
|
||||
#if UINT64_ENABLED
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable
|
||||
#else
|
||||
#extension GL_EXT_buffer_reference_uvec2 : enable
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
const float EPSILON = 0.00001;
|
||||
const float SQRT2 = 1.41421356237;
|
||||
|
||||
const float LIGHT_POWER_CUTOFF = 0.0005;
|
||||
const float LIGHTMAP_GAMMA = 1.0;
|
||||
121
bin/data/shaders - 1.1/common/pbr.h
Normal file
121
bin/data/shaders - 1.1/common/pbr.h
Normal file
@ -0,0 +1,121 @@
|
||||
// PBR
|
||||
void pbr() {
|
||||
// per-surface, not per-light, compute once
|
||||
|
||||
// Freslen reflectance for a dieletric
|
||||
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
|
||||
// outcoming light from surface to eye
|
||||
const vec3 Lo = normalize( -surface.position.eye );
|
||||
// angle of outcoming light
|
||||
const float cosLo = max(0.0, dot(surface.normal.eye, Lo));
|
||||
|
||||
const float Rs = 4.0;
|
||||
|
||||
for ( uint i = 0, shadows = 0; i < MAX_LIGHTS; ++i ) {
|
||||
#if BAKING
|
||||
// skip if surface is a dynamic light, we aren't baking dynamic lights
|
||||
if ( lights[i].type < 0 ) continue;
|
||||
#else
|
||||
// skip if surface is already baked, and this isn't a dynamic light
|
||||
if ( surface.material.lightmapped && lights[i].type >= 0 ) continue;
|
||||
#endif
|
||||
/*
|
||||
// skip if light power is too low
|
||||
if ( lights[i].power <= LIGHT_POWER_CUTOFF ) continue;
|
||||
if ( surface.material.lightmapped && lights[i].type >= 0 ) continue;
|
||||
|
||||
const vec3 Liu = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
|
||||
const vec3 Li = normalize(Liu);
|
||||
const float Lshadow = ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
|
||||
// const float Lattenuation = 1.0 / (PI * pow(length(Liu), 2.0));
|
||||
// const float Lattenuation = 1.0 / (1 + (PI * pow(length(Liu), 2.0)));
|
||||
const float Lattenuation = 1.0 / (1 + pow(length(Liu), 2.0));
|
||||
if ( lights[i].power * Lattenuation * Lshadow <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
|
||||
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
|
||||
*/
|
||||
// incoming light to surface (non-const to normalize it later)
|
||||
// vec3 Li = lights[i].position - surface.position.world;
|
||||
vec3 Li = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
|
||||
// magnitude of incoming light vector (for inverse-square attenuation)
|
||||
const float Lmagnitude = dot(Li, Li);
|
||||
// distance incoming light travels (reuse from above)
|
||||
const float Ldistance = sqrt(Lmagnitude);
|
||||
// "free" normalization, since we need to compute the above values anyways
|
||||
Li = Li / Ldistance;
|
||||
// attenuation factor
|
||||
// const float Lattenuation = 1.0 / (1 + (PI * Lmagnitude));
|
||||
const float Lattenuation = 1.0 / (1 + Lmagnitude);
|
||||
// skip if attenuation factor is too low
|
||||
// if ( Lattenuation <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// ray cast if our surface is occluded from the light
|
||||
const float Lshadow = ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
|
||||
// skip if our shadow factor is too low
|
||||
if ( Lshadow <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// light radiance
|
||||
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
|
||||
// skip if our radiance is too low
|
||||
// if ( Lr <= LIGHT_POWER_CUTOFF ) continue;
|
||||
// halfway vector
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
// angle of incoming light
|
||||
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
|
||||
// angle of halfway light vector
|
||||
const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
|
||||
|
||||
// Fresnel term for direct lighting
|
||||
const vec3 F = fresnelSchlick(F0, max(0.0, dot(Lh, Lo)));
|
||||
// Distribution for specular lighting
|
||||
const float D = ndfGGX( cosLh, surface.material.roughness * Rs);
|
||||
// Geometric attenuation for specular lighting
|
||||
const float G = gaSchlickGGX(cosLi, cosLo, surface.material.roughness * Rs);
|
||||
|
||||
// final lighting
|
||||
const vec3 diffuse = mix(vec3(1.0) - F, vec3(0), surface.material.metallic) * surface.material.albedo.rgb;
|
||||
const vec3 specular = ( shadows < MAX_SHADOWS ) ? ((F * D * G) / max(EPSILON, 4.0 * cosLi * cosLo)) : vec3(0);
|
||||
|
||||
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
surface.light.a += lights[i].power * Lattenuation * Lshadow;
|
||||
}
|
||||
#if 0
|
||||
const float Rs = 4.0; // specular lighting looks gross without this
|
||||
uint shadows = 0;
|
||||
for ( uint i = 0; i < ubo.settings.lengths.lights; ++i ) {
|
||||
const Light light = lights[i];
|
||||
if ( light.power <= LIGHT_POWER_CUTOFF ) continue;
|
||||
if ( surface.material.lightmapped && light.type >= 0 ) continue;
|
||||
|
||||
const vec3 Liu = vec3(ubo.eyes[surface.pass].view * vec4(light.position, 1)) - surface.position.eye;
|
||||
const float Ld = length(Liu);
|
||||
const float La = 1.0 / (1 + (PI * pow(Ld, 2.0)));
|
||||
if ( La <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const vec3 Li = normalize(Liu);
|
||||
const float Ls = ( shadows++ < ubo.settings.lighting.maxShadows ) ? shadowFactor( light, 0.0 ) : 1;
|
||||
if ( light.power * La * Ls <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
|
||||
const vec3 Lr = light.color.rgb * light.power * La * Ls;
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
|
||||
|
||||
const vec3 F = fresnelSchlick( F0, max( 0.0, dot(Lh, Lo) ) );
|
||||
const float D = ndfGGX( cosLh, surface.material.roughness * Rs );
|
||||
const float G = gaSchlickGGX(cosLi, cosLo, surface.material.roughness);
|
||||
const vec3 diffuse = mix( vec3(1.0) - F, vec3(0.0), surface.material.metallic ) * surface.material.albedo.rgb;
|
||||
const vec3 specular = (F * D * G) / max(EPSILON, 4.0 * cosLi * cosLo);
|
||||
/*
|
||||
// lightmapped, compute only specular
|
||||
if ( light.type >= 0 && validTextureIndex( surface.instance.lightmapID ) ) surface.light.rgb += (specular) * Lr * cosLi;
|
||||
// point light, compute only diffuse
|
||||
// else if ( abs(light.type) == 1 ) surface.light.rgb += (diffuse) * Lr * cosLi;
|
||||
else surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
*/
|
||||
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
surface.light.a += light.power * La * Ls;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
171
bin/data/shaders - 1.1/common/shadows.h
Normal file
171
bin/data/shaders - 1.1/common/shadows.h
Normal file
@ -0,0 +1,171 @@
|
||||
const vec2 poissonDisk[16] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 ),
|
||||
vec2( -0.91588581, 0.45771432 ),
|
||||
vec2( -0.81544232, -0.87912464 ),
|
||||
vec2( -0.38277543, 0.27676845 ),
|
||||
vec2( 0.97484398, 0.75648379 ),
|
||||
vec2( 0.44323325, -0.97511554 ),
|
||||
vec2( 0.53742981, -0.47373420 ),
|
||||
vec2( -0.26496911, -0.41893023 ),
|
||||
vec2( 0.79197514, 0.19090188 ),
|
||||
vec2( -0.24188840, 0.99706507 ),
|
||||
vec2( -0.81409955, 0.91437590 ),
|
||||
vec2( 0.19984126, 0.78641367 ),
|
||||
vec2( 0.14383161, -0.14100790 )
|
||||
);
|
||||
|
||||
#ifndef SHADOW_SAMPLES
|
||||
#define SHADOW_SAMPLES ubo.settings.lighting.shadowSamples
|
||||
#endif
|
||||
#if VXGI
|
||||
float voxelShadowFactor( const Light, float def );
|
||||
#endif
|
||||
|
||||
#if CUBEMAPS
|
||||
float omniShadowMap( const Light light, float def ) {
|
||||
return 1.0;
|
||||
}
|
||||
#else
|
||||
float omniShadowMap( const Light light, float def ) {
|
||||
float factor = 1.0;
|
||||
|
||||
const mat4 views[6] = {
|
||||
mat4( 0, 0, 1, 0, 0, 1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 1 ),
|
||||
mat4( 0, 0,-1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 ),
|
||||
mat4( 1, 0, 0, 0, 0, 0, 1, 0, 0,-1, 0, 0, 0, 0, 0, 1 ),
|
||||
mat4( 1, 0, 0, 0, 0, 0,-1, 0, 0, 1, 0, 0, 0, 0, 0, 1 ),
|
||||
mat4( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ),
|
||||
mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0,-1, 0, 0, 0, 0, 1 ),
|
||||
};
|
||||
|
||||
const vec3 D = normalize(surface.position.world - light.position);
|
||||
const vec3 N = abs(D);
|
||||
uint A = N.y > N.x ? 1 : 0;
|
||||
A = N.z > N[A] ? 2 : A;
|
||||
uint index = A * 2;
|
||||
if ( D[A] < 0.0 ) ++index;
|
||||
|
||||
vec4 positionClip = light.projection * views[index] * vec4(surface.position.world - light.position, 1.0);
|
||||
positionClip.xy /= positionClip.w;
|
||||
|
||||
if ( positionClip.x < -1 || positionClip.x >= 1 ) return 0.0;
|
||||
if ( positionClip.y < -1 || positionClip.y >= 1 ) return 0.0;
|
||||
if ( positionClip.z < -1 || positionClip.z >= 1 ) return 0.0;
|
||||
|
||||
const float eyeDepthScale = 1.0;
|
||||
const float sampledDepthScale = light.view[1][1]; // light view matricies will incorporate scaling factors for some retarded reason, so we need to rescale it by grabbing from here, hopefully it remains coherent between all light matrices to ever exist in engine
|
||||
|
||||
const float bias = light.depthBias;
|
||||
const float eyeDepth = abs(positionClip.z / positionClip.w) * eyeDepthScale;
|
||||
|
||||
const vec3 sampleOffsetDirections[20] = {
|
||||
vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
|
||||
vec3( 1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
|
||||
vec3( 1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
|
||||
vec3( 1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
|
||||
vec3( 0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
|
||||
};
|
||||
|
||||
float sampled = 0;
|
||||
const int samples = int(SHADOW_SAMPLES);
|
||||
// cubemap point light
|
||||
if ( light.typeMap == 1 ) {
|
||||
if ( samples < 1 ) {
|
||||
sampled = texture(samplerCubemaps[nonuniformEXT(light.indexMap)], D).r * sampledDepthScale;
|
||||
} else {
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
const int idx = int( float(samples) * random(floor(surface.position.world.xyz * 1000.0), i)) % samples;
|
||||
vec2 poisson = poissonDisk[idx] / 700.0;
|
||||
vec3 P = vec3( poisson.xy, (poisson.x + poisson.y) * 0.5 );
|
||||
sampled = texture(samplerCubemaps[nonuniformEXT(light.indexMap)], D + P ).r * sampledDepthScale;
|
||||
if ( eyeDepth < sampled - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
// separated point lights
|
||||
} else if ( light.typeMap == 2 ) {
|
||||
const vec2 uv = positionClip.xy * 0.5 + 0.5;
|
||||
if ( samples < 1 ) {
|
||||
sampled = texture(samplerTextures[nonuniformEXT(light.indexMap + index)], uv).r * sampledDepthScale;
|
||||
} else {
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
const int idx = int( float(samples) * random(floor(surface.position.world.xyz * 1000.0), i)) % samples;
|
||||
sampled = texture(samplerTextures[nonuniformEXT(light.indexMap + index)], uv + poissonDisk[idx] / 700.0 ).r * sampledDepthScale;
|
||||
if ( eyeDepth < sampled - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
}
|
||||
return eyeDepth < sampled - bias ? 0.0 : factor;
|
||||
}
|
||||
#endif
|
||||
#if RT
|
||||
float shadowFactorRT( const Light light, float def ) {
|
||||
Ray ray;
|
||||
ray.origin = surface.position.world;
|
||||
ray.direction = light.position - ray.origin;
|
||||
|
||||
float tMin = ubo.settings.rt.defaultRayBounds.x;
|
||||
float tMax = length(ray.direction) - ubo.settings.rt.defaultRayBounds.x;
|
||||
|
||||
ray.direction = normalize(ray.direction);
|
||||
|
||||
uint rayFlags = gl_RayFlagsOpaqueEXT | gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsSkipClosestHitShaderEXT;
|
||||
uint cullMask = 0xFF;
|
||||
|
||||
rayQueryEXT rayQuery;
|
||||
rayQueryInitializeEXT(rayQuery, tlas, rayFlags, cullMask, ray.origin, tMin, ray.direction, tMax);
|
||||
|
||||
while(rayQueryProceedEXT(rayQuery));
|
||||
|
||||
return rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionNoneEXT ? 1.0 : 0.0;
|
||||
}
|
||||
#endif
|
||||
float shadowFactor( const Light light, float def ) {
|
||||
#if RT
|
||||
return shadowFactorRT( light, def );
|
||||
#endif
|
||||
if ( light.typeMap != 0 ) return omniShadowMap( light, def );
|
||||
|
||||
if ( !validTextureIndex(light.indexMap) )
|
||||
#if VXGI
|
||||
return voxelShadowFactor( light, def );
|
||||
#else
|
||||
return 1.0;
|
||||
#endif
|
||||
|
||||
vec4 positionClip = light.projection * light.view * vec4(surface.position.world, 1.0);
|
||||
positionClip.xyz /= positionClip.w;
|
||||
|
||||
if ( positionClip.x < -1 || positionClip.x >= 1 ) return def; //0.0;
|
||||
if ( positionClip.y < -1 || positionClip.y >= 1 ) return def; //0.0;
|
||||
if ( positionClip.z <= 0 || positionClip.z >= 1 ) return def; //0.0;
|
||||
|
||||
float factor = 1.0;
|
||||
|
||||
// spot light
|
||||
if ( abs(light.type) == 2 || abs(light.type) == 3 ) {
|
||||
const float dist = length( positionClip.xy );
|
||||
if ( dist > 0.5 ) return def; //0.0;
|
||||
|
||||
// spot light with attenuation
|
||||
if ( abs(light.type) == 3 ) {
|
||||
factor = 1.0 - (pow(dist * 2,2.0));
|
||||
}
|
||||
}
|
||||
|
||||
const vec2 uv = positionClip.xy * 0.5 + 0.5;
|
||||
const float bias = light.depthBias;
|
||||
const float eyeDepth = positionClip.z;
|
||||
const int samples = int(SHADOW_SAMPLES);
|
||||
if ( samples < 1 ) return eyeDepth < texture(samplerTextures[nonuniformEXT(light.indexMap)], uv).r - bias ? 0.0 : factor;
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
const int index = int( float(samples) * random(floor(surface.position.world.xyz * 1000.0), i)) % samples;
|
||||
const float lightDepth = texture(samplerTextures[nonuniformEXT(light.indexMap)], uv + poissonDisk[index] / 700.0 ).r;
|
||||
if ( eyeDepth < lightDepth - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
308
bin/data/shaders - 1.1/common/structs.h
Normal file
308
bin/data/shaders - 1.1/common/structs.h
Normal file
@ -0,0 +1,308 @@
|
||||
struct EyeMatrices {
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
|
||||
mat4 model;
|
||||
mat4 previous;
|
||||
|
||||
mat4 iView;
|
||||
mat4 iProjection;
|
||||
|
||||
vec4 eyePos;
|
||||
};
|
||||
|
||||
struct Viewport {
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
|
||||
struct Cursor {
|
||||
vec2 position;
|
||||
vec2 radius;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
struct Ray {
|
||||
vec3 origin;
|
||||
vec3 direction;
|
||||
|
||||
vec3 position;
|
||||
float distance;
|
||||
};
|
||||
|
||||
struct Space {
|
||||
vec3 eye;
|
||||
vec3 world;
|
||||
};
|
||||
|
||||
struct Light {
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
|
||||
vec3 position;
|
||||
float radius;
|
||||
|
||||
vec3 color;
|
||||
float power;
|
||||
|
||||
int type;
|
||||
int typeMap;
|
||||
int indexMap;
|
||||
float depthBias;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
vec4 colorBase;
|
||||
vec4 colorEmissive;
|
||||
|
||||
float factorMetallic;
|
||||
float factorRoughness;
|
||||
float factorOcclusion;
|
||||
float factorAlphaCutoff;
|
||||
|
||||
int indexAlbedo;
|
||||
int indexNormal;
|
||||
int indexEmissive;
|
||||
int indexOcclusion;
|
||||
|
||||
int indexMetallicRoughness;
|
||||
int padding1;
|
||||
int padding2;
|
||||
int modeAlpha;
|
||||
};
|
||||
|
||||
struct Texture {
|
||||
int index;
|
||||
int samp;
|
||||
int remap;
|
||||
float blend;
|
||||
|
||||
vec4 lerp;
|
||||
};
|
||||
|
||||
struct DrawCommand {
|
||||
uint indices; // triangle count
|
||||
uint instances; // instance count
|
||||
uint indexID; // starting triangle position
|
||||
int vertexID; // starting vertex position
|
||||
|
||||
uint instanceID; // starting instance position
|
||||
float padding1; //
|
||||
float padding2; // material to use for this draw call
|
||||
uint vertices; // number of vertices used
|
||||
};
|
||||
|
||||
struct Bounds {
|
||||
vec3 min;
|
||||
float padding1;
|
||||
vec3 max;
|
||||
float padding2;
|
||||
};
|
||||
|
||||
struct Instance {
|
||||
mat4 model;
|
||||
mat4 previous;
|
||||
|
||||
vec4 color;
|
||||
|
||||
uint materialID;
|
||||
uint primitiveID;
|
||||
uint meshID;
|
||||
uint objectID;
|
||||
|
||||
int jointID;
|
||||
int lightmapID;
|
||||
uint imageID;
|
||||
uint auxID;
|
||||
|
||||
Bounds bounds;
|
||||
// InstanceAddresses addresses;
|
||||
};
|
||||
|
||||
struct InstanceAddresses {
|
||||
uint64_t vertex;
|
||||
uint64_t index;
|
||||
|
||||
uint64_t indirect;
|
||||
uint drawID;
|
||||
uint padding0;
|
||||
|
||||
uint64_t position;
|
||||
uint64_t uv;
|
||||
|
||||
uint64_t color;
|
||||
uint64_t st;
|
||||
|
||||
uint64_t normal;
|
||||
uint64_t tangent;
|
||||
|
||||
uint64_t joints;
|
||||
uint64_t weights;
|
||||
|
||||
uint64_t id;
|
||||
uint64_t padding1;
|
||||
};
|
||||
|
||||
struct SurfaceMaterial {
|
||||
vec4 albedo;
|
||||
vec4 indirect;
|
||||
|
||||
float metallic;
|
||||
float roughness;
|
||||
float occlusion;
|
||||
bool lightmapped;
|
||||
};
|
||||
|
||||
struct Surface {
|
||||
uint pass;
|
||||
uint subID;
|
||||
|
||||
vec3 uv;
|
||||
vec3 st;
|
||||
Space position;
|
||||
Space normal;
|
||||
Space tangent;
|
||||
mat3 tbn;
|
||||
vec3 barycentric;
|
||||
vec2 motion;
|
||||
|
||||
Ray ray;
|
||||
|
||||
SurfaceMaterial material;
|
||||
Instance instance;
|
||||
|
||||
vec4 light;
|
||||
vec4 fragment;
|
||||
} surface;
|
||||
|
||||
// MSAA info
|
||||
#if MULTISAMPLING
|
||||
struct MSAA {
|
||||
int currentID;
|
||||
uvec2 IDs[MAX_MSAA_SAMPLES];
|
||||
vec4 fragment;
|
||||
vec4 fragments[MAX_MSAA_SAMPLES];
|
||||
} msaa;
|
||||
#endif
|
||||
// UBO settings
|
||||
struct SettingsLengths {
|
||||
uint lights;
|
||||
uint materials;
|
||||
uint textures;
|
||||
uint drawCommands;
|
||||
};
|
||||
struct SettingsMode {
|
||||
vec4 parameters;
|
||||
uint type;
|
||||
uint scalar;
|
||||
uint msaa;
|
||||
uint frameNumber;
|
||||
};
|
||||
struct SettingsLighting {
|
||||
vec3 ambient;
|
||||
uint indexSkybox;
|
||||
|
||||
uint maxShadows;
|
||||
uint shadowSamples;
|
||||
uint useLightmaps;
|
||||
};
|
||||
struct SettingsFog {
|
||||
vec3 color;
|
||||
float stepScale;
|
||||
|
||||
vec3 offset;
|
||||
float densityScale;
|
||||
|
||||
vec2 range;
|
||||
float densityThreshold;
|
||||
float densityMultiplier;
|
||||
|
||||
float absorbtion;
|
||||
float padding1;
|
||||
float padding2;
|
||||
float padding3;
|
||||
};
|
||||
struct SettingsBloom {
|
||||
float exposure;
|
||||
float gamma;
|
||||
float threshold;
|
||||
uint padding;
|
||||
};
|
||||
struct SettingsVxgi {
|
||||
mat4 matrix;
|
||||
|
||||
float cascadePower;
|
||||
float granularity;
|
||||
float voxelizeScale;
|
||||
float occlusionFalloff;
|
||||
|
||||
float traceStartOffsetFactor;
|
||||
uint shadows;
|
||||
uint padding2;
|
||||
uint padding3;
|
||||
};
|
||||
struct SettingsRayTrace {
|
||||
vec2 defaultRayBounds;
|
||||
float alphaTestOffset;
|
||||
float padding1;
|
||||
|
||||
uint samples;
|
||||
uint paths;
|
||||
uint frameAccumulationMinimum;
|
||||
uint padding2;
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
SettingsLengths lengths;
|
||||
SettingsMode mode;
|
||||
SettingsLighting lighting;
|
||||
SettingsFog fog;
|
||||
SettingsBloom bloom;
|
||||
SettingsVxgi vxgi;
|
||||
SettingsRayTrace rt;
|
||||
};
|
||||
struct Voxel {
|
||||
uvec2 id;
|
||||
vec3 position;
|
||||
vec3 normal;
|
||||
vec2 uv;
|
||||
vec4 color;
|
||||
};
|
||||
struct VoxelInfo {
|
||||
vec3 min;
|
||||
vec3 max;
|
||||
|
||||
float mipmapLevels;
|
||||
float radianceSize;
|
||||
float radianceSizeRecip;
|
||||
} voxelInfo;
|
||||
|
||||
// Raytrace stuff
|
||||
|
||||
struct Vertex {
|
||||
vec3 position;
|
||||
vec2 uv;
|
||||
uint color;
|
||||
vec2 st;
|
||||
vec3 normal;
|
||||
vec3 tangent;
|
||||
uvec2 joints;
|
||||
vec4 weights;
|
||||
uint id;
|
||||
};
|
||||
|
||||
struct Triangle {
|
||||
Vertex point;
|
||||
|
||||
vec3 geomNormal;
|
||||
|
||||
uint instanceID;
|
||||
};
|
||||
|
||||
struct RayTracePayload {
|
||||
bool hit;
|
||||
uint instanceID;
|
||||
uint primitiveID;
|
||||
vec2 attributes;
|
||||
// Triangle triangle;
|
||||
};
|
||||
189
bin/data/shaders - 1.1/common/vxgi.h
Normal file
189
bin/data/shaders - 1.1/common/vxgi.h
Normal file
@ -0,0 +1,189 @@
|
||||
// GI
|
||||
uint cascadeIndex( vec3 v ) {
|
||||
float x = max3( abs( v ) );
|
||||
for ( uint cascade = 0; cascade < CASCADES; ++cascade )
|
||||
if ( x / cascadePower(cascade) < 1 - voxelInfo.radianceSizeRecip ) return cascade;
|
||||
return CASCADES - 1;
|
||||
}
|
||||
|
||||
vec4 voxelTrace( inout Ray ray, float aperture, float maxDistance ) {
|
||||
ray.origin += ray.direction * voxelInfo.radianceSizeRecip * 2 * SQRT2;
|
||||
#if VXGI_NDC
|
||||
ray.origin = vec3( ubo.settings.vxgi.matrix * vec4( ray.origin, 1.0 ) );
|
||||
ray.direction = vec3( ubo.settings.vxgi.matrix * vec4( ray.direction, 0.0 ) );
|
||||
uint cascade = cascadeIndex(ray.origin);
|
||||
#else
|
||||
uint cascade = cascadeIndex( vec3( ubo.settings.vxgi.matrix * vec4( ray.origin, 1.0 ) ) );
|
||||
#endif
|
||||
const float granularityRecip = ubo.settings.vxgi.granularity; //2.0; // 0.25f * (CASCADES - cascade);
|
||||
const float granularity = 1.0f / granularityRecip;
|
||||
const float occlusionFalloff = ubo.settings.vxgi.occlusionFalloff; //128.0f;
|
||||
const vec3 voxelBounds = voxelInfo.max - voxelInfo.min;
|
||||
const vec3 voxelBoundsRecip = 1.0f / voxelBounds;
|
||||
const float coneCoefficient = 2.0 * tan(aperture * 0.5);
|
||||
const uint maxSteps = uint(voxelInfo.radianceSize * cascadePower(CASCADES-1) * granularityRecip);
|
||||
// box
|
||||
const vec2 rayBoxInfoA = rayBoxDst( voxelInfo.min * cascadePower(cascade), voxelInfo.max * cascadePower(cascade), ray );
|
||||
const vec2 rayBoxInfoB = rayBoxDst( voxelInfo.min * cascadePower(CASCADES-1), voxelInfo.max * cascadePower(CASCADES-1), ray );
|
||||
|
||||
const float tStart = rayBoxInfoA.x;
|
||||
const float tEnd = maxDistance > 0 ? min(maxDistance, rayBoxInfoB.y) : rayBoxInfoB.y;
|
||||
const float tDelta = voxelInfo.radianceSizeRecip * granularityRecip;
|
||||
// marcher
|
||||
ray.distance = tStart + tDelta * ubo.settings.vxgi.traceStartOffsetFactor;
|
||||
ray.position = vec3(0);
|
||||
|
||||
vec4 radiance = vec4(0);
|
||||
vec3 uvw = vec3(0);
|
||||
float coneDiameter = coneCoefficient * ray.distance;
|
||||
float level = aperture > 0 ? log2( coneDiameter ) : 0;
|
||||
vec4 color = vec4(0);
|
||||
float occlusion = 0.0;
|
||||
uint stepCounter = 0;
|
||||
while ( color.a < 1.0 && occlusion < 1.0 && ray.distance < tEnd && stepCounter++ < maxSteps ) {
|
||||
ray.distance += tDelta * cascadePower(cascade) * max(1, coneDiameter);
|
||||
ray.position = ray.origin + ray.direction * ray.distance;
|
||||
|
||||
#if VXGI_NDC
|
||||
uvw = ray.position;
|
||||
#else
|
||||
uvw = vec3( ubo.settings.vxgi.matrix * vec4( ray.position, 1.0 ) );
|
||||
#endif
|
||||
cascade = cascadeIndex( uvw );
|
||||
uvw = (uvw / cascadePower(cascade)) * 0.5 + 0.5;
|
||||
if ( cascade >= CASCADES || uvw.x < 0.0 || uvw.y < 0.0 || uvw.z < 0.0 || uvw.x >= 1.0 || uvw.y >= 1.0 || uvw.z >= 1.0 ) break;
|
||||
coneDiameter = coneCoefficient * ray.distance;
|
||||
level = aperture > 0 ? log2( coneDiameter ) : 0;
|
||||
if ( level >= voxelInfo.mipmapLevels ) break;
|
||||
radiance = textureLod(voxelRadiance[nonuniformEXT(cascade)], uvw.xzy, level);
|
||||
color += (1.0 - color.a) * radiance;
|
||||
occlusion += ((1.0f - occlusion) * radiance.a) / (1.0f + occlusionFalloff * coneDiameter);
|
||||
}
|
||||
return maxDistance > 0 ? color : vec4(color.rgb, occlusion);
|
||||
// return vec4(color.rgb, occlusion);
|
||||
}
|
||||
vec4 voxelConeTrace( inout Ray ray, float aperture ) {
|
||||
return voxelTrace( ray, aperture, 0 );
|
||||
}
|
||||
vec4 voxelTrace( inout Ray ray, float maxDistance ) {
|
||||
return voxelTrace( ray, 0, maxDistance );
|
||||
}
|
||||
uint voxelShadowsCount = 0;
|
||||
float voxelShadowFactor( const Light light, float def ) {
|
||||
if ( ubo.settings.vxgi.shadows < ++voxelShadowsCount ) return 1.0;
|
||||
|
||||
const float SHADOW_APERTURE = 0.2;
|
||||
const float DEPTH_BIAS = 0.0;
|
||||
|
||||
Ray ray;
|
||||
ray.direction = normalize( light.position - surface.position.world );
|
||||
ray.origin = surface.position.world + ray.direction * 0.5;
|
||||
float z = distance( surface.position.world, light.position ) - DEPTH_BIAS;
|
||||
return 1.0 - voxelTrace( ray, SHADOW_APERTURE, z ).a;
|
||||
}
|
||||
void indirectLighting() {
|
||||
voxelInfo.radianceSize = textureSize( voxelRadiance[0], 0 ).x;
|
||||
voxelInfo.radianceSizeRecip = 1.0 / voxelInfo.radianceSize;
|
||||
voxelInfo.mipmapLevels = log2(voxelInfo.radianceSize) + 1;
|
||||
#if VXGI_NDC
|
||||
voxelInfo.min = vec3( -1 );
|
||||
voxelInfo.max = vec3( 1 );
|
||||
#else
|
||||
const mat4 inverseOrtho = inverse( ubo.settings.vxgi.matrix );
|
||||
voxelInfo.min = vec3( inverseOrtho * vec4( -1, -1, -1, 1 ) );
|
||||
voxelInfo.max = vec3( inverseOrtho * vec4( 1, 1, 1, 1 ) );
|
||||
#endif
|
||||
|
||||
const vec3 P = surface.position.world;
|
||||
const vec3 N = surface.normal.world;
|
||||
|
||||
#if 1
|
||||
const vec3 right = normalize(orthogonal(N));
|
||||
const vec3 up = normalize(cross(right, N));
|
||||
|
||||
const uint CONES_COUNT = 6;
|
||||
const vec3 CONES[] = {
|
||||
N,
|
||||
normalize(N + 0.0f * right + 0.866025f * up),
|
||||
normalize(N + 0.823639f * right + 0.267617f * up),
|
||||
normalize(N + 0.509037f * right + -0.7006629f * up),
|
||||
normalize(N + -0.50937f * right + -0.7006629f * up),
|
||||
normalize(N + -0.823639f * right + 0.267617f * up),
|
||||
};
|
||||
#else
|
||||
const vec3 ortho = normalize(orthogonal(N));
|
||||
const vec3 ortho2 = normalize(cross(ortho, N));
|
||||
|
||||
const vec3 corner = 0.5f * (ortho + ortho2);
|
||||
const vec3 corner2 = 0.5f * (ortho - ortho2);
|
||||
|
||||
const uint CONES_COUNT = 9;
|
||||
const vec3 CONES[] = {
|
||||
N,
|
||||
normalize(mix(N, ortho, 0.5)),
|
||||
normalize(mix(N, -ortho, 0.5)),
|
||||
normalize(mix(N, ortho2, 0.5)),
|
||||
normalize(mix(N, -ortho2, 0.5)),
|
||||
normalize(mix(N, corner, 0.5)),
|
||||
normalize(mix(N, -corner, 0.5)),
|
||||
normalize(mix(N, corner2, 0.5)),
|
||||
normalize(mix(N, -corner2, 0.5)),
|
||||
};
|
||||
#endif
|
||||
|
||||
const float DIFFUSE_CONE_APERTURE = 2.0 * 0.57735f;
|
||||
const float DIFFUSE_INDIRECT_FACTOR = 0; // 1.0f / float(CONES_COUNT) * 0.125f;
|
||||
|
||||
const float SPECULAR_CONE_APERTURE = clamp(tan(PI * 0.5f * surface.material.roughness), 0.0174533f, PI); // tan( R * PI * 0.5f * 0.1f );
|
||||
const float SPECULAR_INDIRECT_FACTOR = (1.0 - surface.material.metallic); // * 0.25; // 1.0f;
|
||||
|
||||
vec4 indirectDiffuse = vec4(0);
|
||||
vec4 indirectSpecular = vec4(0);
|
||||
|
||||
// outFragColor.rgb = voxelConeTrace( surface.ray, 0 ).rgb; return;
|
||||
if ( DIFFUSE_INDIRECT_FACTOR > 0.0f ) {
|
||||
float weight = PI * 0.25f;
|
||||
for ( uint i = 0; i < CONES_COUNT; ++i ) {
|
||||
Ray ray;
|
||||
ray.direction = CONES[i].xyz;
|
||||
ray.origin = P; // + ray.direction;
|
||||
indirectDiffuse += voxelConeTrace( ray, DIFFUSE_CONE_APERTURE ) * weight;
|
||||
weight = PI * 0.15f;
|
||||
}
|
||||
// indirectDiffuse.rgb *= surface.material.albedo.rgb;
|
||||
surface.material.occlusion += 1.0 - clamp(indirectDiffuse.a, 0.0, 1.0);
|
||||
// outFragColor.rgb = indirectDiffuse.rgb; return;
|
||||
// outFragColor.rgb = vec3(surface.material.occlusion); return;
|
||||
}
|
||||
if ( SPECULAR_INDIRECT_FACTOR > 0.0f ) {
|
||||
const vec3 R = reflect( normalize(P - surface.ray.origin), N );
|
||||
Ray ray;
|
||||
ray.direction = R;
|
||||
ray.origin = P; // + ray.direction;
|
||||
indirectSpecular = voxelConeTrace( ray, SPECULAR_CONE_APERTURE );
|
||||
// indirectSpecular.rgb *= surface.material.albedo.rgb;
|
||||
// outFragColor.rgb = indirectSpecular.rgb; return;
|
||||
}
|
||||
|
||||
/*
|
||||
if ( true ) {
|
||||
gammaCorrect(indirectDiffuse.rgb, 1.0 / ubo.settings.bloom.gamma);
|
||||
}
|
||||
*/
|
||||
indirectDiffuse *= DIFFUSE_INDIRECT_FACTOR;
|
||||
indirectSpecular *= SPECULAR_INDIRECT_FACTOR;
|
||||
|
||||
|
||||
surface.material.indirect = indirectDiffuse + indirectSpecular;
|
||||
// outFragColor.rgb = surface.material.indirect.rgb; return;
|
||||
|
||||
// deferred sampling doesn't have a blended albedo buffer
|
||||
// in place we'll just cone trace behind the window
|
||||
if ( surface.material.albedo.a < 1.0 ) {
|
||||
Ray ray;
|
||||
ray.direction = surface.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;
|
||||
}
|
||||
}
|
||||
67
bin/data/shaders - 1.1/display/bloom/comp.glsl
Normal file
67
bin/data/shaders - 1.1/display/bloom/comp.glsl
Normal file
@ -0,0 +1,67 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define COMPUTE 1
|
||||
#define TEXTURES 0
|
||||
#define CUBEMAPS 0
|
||||
#define BLOOM 1
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint eye;
|
||||
uint mode;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
float scale;
|
||||
float strength;
|
||||
float threshold;
|
||||
float sigma;
|
||||
|
||||
float gamma;
|
||||
float exposure;
|
||||
uint samples;
|
||||
uint padding;
|
||||
} ubo;
|
||||
|
||||
layout (binding = 1, rgba16f) uniform volatile coherent image2D imageColor;
|
||||
layout (binding = 2, rgba16f) uniform volatile coherent image2D imageBloom;
|
||||
layout (binding = 3, rgba16f) uniform volatile coherent image2D imagePingPong;
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
#include "../../common/functions.h"
|
||||
|
||||
void main() {
|
||||
const uint mode = PushConstant.mode;
|
||||
const ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||
const ivec2 size = imageSize( imageColor );
|
||||
if ( texel.x >= size.x || texel.y >= size.y ) return;
|
||||
|
||||
if ( mode == 0 ) { // fill bloom
|
||||
vec3 result = imageLoad( imageColor, texel ).rgb;
|
||||
float brightness = dot(result, vec3(0.2126, 0.7152, 0.0722));
|
||||
if ( brightness < ubo.threshold ) result = vec3(0, 0, 0);
|
||||
imageStore( imageBloom, texel, vec4( result, 1.0 ) );
|
||||
} else if ( mode == 1 ) { // bloom horizontal
|
||||
vec3 result = imageLoad( imageBloom, texel ).rgb * gauss( 0, ubo.sigma ) * ubo.strength;
|
||||
for( int i = 1; i < ubo.samples; ++i ) {
|
||||
result += imageLoad( imageBloom, texel + ivec2(i * ubo.scale, 0.0)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
result += imageLoad( imageBloom, texel - ivec2(i * ubo.scale, 0.0)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
}
|
||||
// write to PingPong
|
||||
imageStore( imagePingPong, texel, vec4( result, 1.0 ) );
|
||||
} else if ( mode == 2 ) { // bloom vertical
|
||||
vec3 result = imageLoad( imagePingPong, texel ).rgb * gauss( 0, ubo.sigma ) * ubo.strength;
|
||||
for( int i = 1; i < ubo.samples; ++i ) {
|
||||
result += imageLoad( imagePingPong, texel + ivec2(0.0, i * ubo.scale)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
result += imageLoad( imagePingPong, texel - ivec2(0.0, i * ubo.scale)).rgb * gauss( i * ubo.scale / ubo.samples, ubo.sigma ) * ubo.strength;
|
||||
}
|
||||
// write to Bloom
|
||||
imageStore( imageBloom, texel, vec4( result, 1.0 ) );
|
||||
} else if ( mode == 3 ) { // combine
|
||||
vec3 result = imageLoad( imageColor, texel ).rgb + imageLoad( imageBloom, texel ).rgb;
|
||||
imageStore( imageColor, texel, vec4( result, 1.0 ) );
|
||||
}
|
||||
}
|
||||
13
bin/data/shaders - 1.1/display/deferred/comp/comp.glsl
Normal file
13
bin/data/shaders - 1.1/display/deferred/comp/comp.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 0
|
||||
#define VXGI 0
|
||||
#define MULTISAMPLING 0
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
278
bin/data/shaders - 1.1/display/deferred/comp/comp.h
Normal file
278
bin/data/shaders - 1.1/display/deferred/comp/comp.h
Normal file
@ -0,0 +1,278 @@
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
||||
#if RT
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_EXT_ray_query : enable
|
||||
#endif
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
|
||||
#define COMPUTE 1
|
||||
#define DEFERRED 1
|
||||
#define DEFERRED_SAMPLING 1
|
||||
|
||||
#define PBR 1
|
||||
#define LAMBERT 0
|
||||
#if RT || BARYCENTRIC
|
||||
#define BUFFER_REFERENCE 0
|
||||
#define UINT64_ENABLED 0
|
||||
#endif
|
||||
#define FOG 1
|
||||
#define FOG_RAY_MARCH 1
|
||||
|
||||
#include "../../../common/macros.h"
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 512;
|
||||
layout (constant_id = 1) const uint CUBEMAPS = 128;
|
||||
#if VXGI
|
||||
layout (constant_id = 2) const uint CASCADES = 16;
|
||||
#endif
|
||||
|
||||
#if !MULTISAMPLING
|
||||
layout(binding = 0) uniform utexture2D samplerId;
|
||||
#if BARYCENTRIC
|
||||
#if !BARYCENTRIC_CALCULATE
|
||||
layout(binding = 1) uniform texture2D samplerBary;
|
||||
#endif
|
||||
#else
|
||||
layout(binding = 1) uniform texture2D samplerUv;
|
||||
layout(binding = 2) uniform texture2D samplerNormal;
|
||||
#endif
|
||||
layout(binding = 3) uniform texture2D samplerDepth;
|
||||
#else
|
||||
layout(binding = 0) uniform utexture2DMS samplerId;
|
||||
#if BARYCENTRIC
|
||||
#if !BARYCENTRIC_CALCULATE
|
||||
layout(binding = 1) uniform texture2DMS samplerBary;
|
||||
#endif
|
||||
#else
|
||||
layout(binding = 1) uniform texture2DMS samplerUv;
|
||||
layout(binding = 2) uniform texture2DMS samplerNormal;
|
||||
#endif
|
||||
layout(binding = 3) uniform texture2DMS samplerDepth;
|
||||
#endif
|
||||
|
||||
|
||||
layout(binding = 7, rgba16f) uniform volatile coherent image2D imageColor;
|
||||
layout(binding = 8, rgba16f) uniform volatile coherent image2D imageBright;
|
||||
layout(binding = 9, rg16f) uniform volatile coherent image2D imageMotion;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
#include "../../../common/structs.h"
|
||||
|
||||
layout (binding = 10) uniform UBO {
|
||||
EyeMatrices eyes[2];
|
||||
|
||||
Settings settings;
|
||||
} ubo;
|
||||
/*
|
||||
*/
|
||||
layout (std140, binding = 11) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 12) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
layout (std140, binding = 13) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
layout (std140, binding = 14) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 15) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 16) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout (binding = 17) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 18) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 19) uniform sampler3D samplerNoise;
|
||||
#if VXGI
|
||||
layout (binding = 20) uniform usampler3D voxelId[CASCADES];
|
||||
layout (binding = 21) uniform sampler3D voxelNormal[CASCADES];
|
||||
layout (binding = 22) uniform sampler3D voxelRadiance[CASCADES];
|
||||
#endif
|
||||
#if RT
|
||||
layout (binding = 23) uniform accelerationStructureEXT tlas;
|
||||
#endif
|
||||
|
||||
#if BUFFER_REFERENCE
|
||||
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[]; };
|
||||
#endif
|
||||
|
||||
#include "../../../common/functions.h"
|
||||
#include "../../../common/fog.h"
|
||||
#include "../../../common/light.h"
|
||||
#include "../../../common/shadows.h"
|
||||
#if VXGI
|
||||
#include "../../../common/vxgi.h"
|
||||
#endif
|
||||
|
||||
#if MULTISAMPLING
|
||||
#define IMAGE_LOAD(X) texelFetch( X, ivec2(gl_GlobalInvocationID.xy), msaa.currentID )
|
||||
#else
|
||||
#define IMAGE_LOAD(X) texelFetch( X, ivec2(gl_GlobalInvocationID.xy), 0 )
|
||||
#endif
|
||||
|
||||
#define IMAGE_STORE(X, Y) imageStore( X, ivec2(gl_GlobalInvocationID.xy), Y )
|
||||
|
||||
void postProcess() {
|
||||
#if FOG
|
||||
fog( surface.ray, surface.fragment.rgb, surface.fragment.a );
|
||||
#endif
|
||||
float brightness = dot(surface.fragment.rgb, vec3(0.2126, 0.7152, 0.0722));
|
||||
bool bloom = brightness > ubo.settings.bloom.threshold;
|
||||
//if ( bloom ) toneMap( surface.fragment.rgb, brightness );
|
||||
vec4 outFragColor = vec4(surface.fragment.rgb, 1.0);
|
||||
vec4 outFragBright = bloom ? vec4(surface.fragment.rgb, 1.0) : vec4(0, 0, 0, 1);
|
||||
vec2 outFragMotion = surface.motion;
|
||||
|
||||
IMAGE_STORE( imageColor, outFragColor );
|
||||
IMAGE_STORE( imageBright, outFragBright );
|
||||
IMAGE_STORE( imageMotion, vec4(outFragMotion, 0, 0) );
|
||||
}
|
||||
|
||||
void populateSurface() {
|
||||
uvec2 renderSize = imageSize(imageColor);
|
||||
if ( gl_GlobalInvocationID.x >= renderSize.x || gl_GlobalInvocationID.y >= renderSize.y || gl_GlobalInvocationID.z > PushConstant.pass ) return;
|
||||
|
||||
surface.fragment = vec4(0);
|
||||
surface.pass = PushConstant.pass;
|
||||
|
||||
{
|
||||
vec2 inUv = (vec2(gl_GlobalInvocationID.xy) / vec2(renderSize)) * 2.0f - 1.0f;
|
||||
const mat4 iProjectionView = inverse( ubo.eyes[surface.pass].projection * mat4(mat3(ubo.eyes[surface.pass].view)) );
|
||||
const vec4 near4 = iProjectionView * (vec4(inUv, -1.0, 1.0));
|
||||
const vec4 far4 = iProjectionView * (vec4(inUv, 1.0, 1.0));
|
||||
const vec3 near3 = near4.xyz / near4.w;
|
||||
const vec3 far3 = far4.xyz / far4.w;
|
||||
|
||||
surface.ray.direction = normalize( far3 - near3 );
|
||||
surface.ray.origin = /*near3.xyz;*/ ubo.eyes[surface.pass].eyePos.xyz;
|
||||
|
||||
const float depth = IMAGE_LOAD(samplerDepth).r;
|
||||
|
||||
vec4 eye = ubo.eyes[surface.pass].iProjection * vec4(inUv, depth, 1.0);
|
||||
eye /= eye.w;
|
||||
|
||||
surface.position.eye = eye.xyz;
|
||||
surface.position.world = vec3( ubo.eyes[surface.pass].iView * eye );
|
||||
}
|
||||
|
||||
#if !MULTISAMPLING
|
||||
const uvec2 ID = uvec2(IMAGE_LOAD(samplerId).xy);
|
||||
#else
|
||||
const uvec2 ID = msaa.IDs[msaa.currentID];
|
||||
#endif
|
||||
surface.motion = vec2(0);
|
||||
|
||||
if ( ID.x == 0 || ID.y == 0 ) {
|
||||
if ( 0 <= ubo.settings.lighting.indexSkybox && ubo.settings.lighting.indexSkybox < CUBEMAPS ) {
|
||||
surface.fragment.rgb = texture( samplerCubemaps[ubo.settings.lighting.indexSkybox], surface.ray.direction ).rgb;
|
||||
}
|
||||
surface.fragment.a = 0.0;
|
||||
return;
|
||||
}
|
||||
{
|
||||
const uint triangleID = ID.x - 1;
|
||||
const uint instanceID = ID.y - 1;
|
||||
surface.subID = 1;
|
||||
|
||||
#if BARYCENTRIC
|
||||
#if !BARYCENTRIC_CALCULATE
|
||||
surface.barycentric = decodeBarycentrics(IMAGE_LOAD(samplerBary).xy).xyz;
|
||||
#endif
|
||||
populateSurface( instanceID, triangleID );
|
||||
#else
|
||||
vec4 uvst = IMAGE_LOAD(samplerUv);
|
||||
vec4 normaltangent = IMAGE_LOAD(samplerNormal);
|
||||
|
||||
surface.uv.xy = uvst.xy;
|
||||
surface.uv.z = 0;
|
||||
surface.st.xy = uvst.zw;
|
||||
surface.st.z = 0;
|
||||
|
||||
surface.normal.world = decodeNormals(normaltangent.xy);
|
||||
// surface.tangent.world = decodeNormals(normaltangent.zw);
|
||||
|
||||
surface.fragment = vec4(0);
|
||||
surface.light = vec4(0);
|
||||
surface.instance = instances[instanceID];
|
||||
|
||||
populateSurfaceMaterial();
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
vec4 pNDC = ubo.eyes[surface.pass].previous * surface.instance.previous * vec4(surface.position.world, 1);
|
||||
vec4 cNDC = ubo.eyes[surface.pass].model * surface.instance.model * vec4(surface.position.world, 1);
|
||||
pNDC /= pNDC.w;
|
||||
cNDC /= cNDC.w;
|
||||
|
||||
surface.motion = cNDC.xy - pNDC.xy;
|
||||
}
|
||||
}
|
||||
|
||||
void directLighting() {
|
||||
surface.light.rgb += surface.material.albedo.rgb * ubo.settings.lighting.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;
|
||||
|
||||
}
|
||||
|
||||
#if MULTISAMPLING
|
||||
void resolveSurfaceFragment() {
|
||||
for ( int i = 0; i < ubo.settings.mode.msaa; ++i ) {
|
||||
msaa.currentID = i;
|
||||
msaa.IDs[i] = uvec3(IMAGE_LOAD(samplerId)).xy;
|
||||
|
||||
// check if ID is already used
|
||||
bool unique = true;
|
||||
for ( int j = msaa.currentID - 1; j >= 0; --j ) {
|
||||
if ( msaa.IDs[j] == msaa.IDs[i] ) {
|
||||
surface.fragment = msaa.fragments[j];
|
||||
unique = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( unique ) {
|
||||
populateSurface();
|
||||
#if VXGI
|
||||
indirectLighting();
|
||||
#endif
|
||||
directLighting();
|
||||
}
|
||||
|
||||
msaa.fragment += surface.fragment;
|
||||
msaa.fragments[msaa.currentID] = surface.fragment;
|
||||
}
|
||||
|
||||
surface.fragment = msaa.fragment / ubo.settings.mode.msaa;
|
||||
}
|
||||
#endif
|
||||
13
bin/data/shaders - 1.1/display/deferred/comp/msaa.comp.glsl
Normal file
13
bin/data/shaders - 1.1/display/deferred/comp/msaa.comp.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 0
|
||||
#define VXGI 0
|
||||
#define MULTISAMPLING 1
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
resolveSurfaceFragment();
|
||||
|
||||
postProcess();
|
||||
}
|
||||
13
bin/data/shaders - 1.1/display/deferred/comp/rt.comp.glsl
Normal file
13
bin/data/shaders - 1.1/display/deferred/comp/rt.comp.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
#version 460
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 1
|
||||
#define VXGI 0
|
||||
#define MULTISAMPLING 0
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
#version 460
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 1
|
||||
#define VXGI 0
|
||||
#define MULTISAMPLING 1
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
#version 460
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 1
|
||||
#define VXGI 1
|
||||
#define MULTISAMPLING 0
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
indirectLighting();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
#version 460
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 1
|
||||
#define VXGI 1
|
||||
#define MULTISAMPLING 1
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
14
bin/data/shaders - 1.1/display/deferred/comp/vxgi.comp.glsl
Normal file
14
bin/data/shaders - 1.1/display/deferred/comp/vxgi.comp.glsl
Normal file
@ -0,0 +1,14 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 0
|
||||
#define VXGI 1
|
||||
#define MULTISAMPLING 0
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
populateSurface();
|
||||
indirectLighting();
|
||||
directLighting();
|
||||
postProcess();
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#define RT 0
|
||||
#define VXGI 1
|
||||
#define MULTISAMPLING 1
|
||||
#include "./comp.h"
|
||||
|
||||
void main() {
|
||||
resolveSurfaceFragment();
|
||||
postProcess();
|
||||
}
|
||||
30
bin/data/shaders - 1.1/display/depth-pyramid/comp.glsl
Normal file
30
bin/data/shaders - 1.1/display/depth-pyramid/comp.glsl
Normal file
@ -0,0 +1,30 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
//#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
||||
layout (constant_id = 0) const uint MIPS = 6;
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
|
||||
#define COMPUTE 1
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint _;
|
||||
uint pass;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 3) uniform sampler2D inImage[MIPS];
|
||||
layout (binding = 4, r32f) uniform volatile coherent image2D outImage[MIPS];
|
||||
|
||||
void main() {
|
||||
vec2 imageSize = imageSize(outImage[PushConstant.pass]);
|
||||
uvec2 pos = gl_GlobalInvocationID.xy;
|
||||
if ( pos.x >= imageSize.x || pos.y >= imageSize.y ) return;
|
||||
|
||||
float depth = texture(inImage[PushConstant.pass], (vec2(pos) + vec2(0.5)) / imageSize).x;
|
||||
|
||||
imageStore(outImage[PushConstant.pass], ivec2(pos), vec4(depth));
|
||||
}
|
||||
35
bin/data/shaders - 1.1/display/renderTarget/frag.glsl
Normal file
35
bin/data/shaders - 1.1/display/renderTarget/frag.glsl
Normal file
@ -0,0 +1,35 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) flat in uint inPass;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
layout (binding = 0) uniform sampler2D samplerColor;
|
||||
|
||||
layout (binding = 1) uniform UBO {
|
||||
float curTime;
|
||||
float gamma;
|
||||
float exposure;
|
||||
uint padding;
|
||||
} ubo;
|
||||
|
||||
#define TONE_MAP 1
|
||||
#define GAMMA_CORRECT 1
|
||||
#define TEXTURES 1
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
#include "../../common/functions.h"
|
||||
|
||||
void main() {
|
||||
outColor = texture( samplerColor, inUv );
|
||||
#if TONE_MAP
|
||||
toneMap(outColor, ubo.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,392 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) flat in uint inPass;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
layout (binding = 0) uniform sampler2D samplerColor;
|
||||
|
||||
layout (binding = 1) uniform UBO {
|
||||
float curTime;
|
||||
float gamma;
|
||||
float exposure;
|
||||
uint padding;
|
||||
} ubo;
|
||||
|
||||
#define TONE_MAP 1
|
||||
#define GAMMA_CORRECT 1
|
||||
#define TEXTURES 1
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
#include "../../common/functions.h"
|
||||
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
const float u_imgx = 0;
|
||||
const float u_imgy = 0;
|
||||
const float u_imgw = 1;
|
||||
const float u_imgh = 1;
|
||||
const float u_img_gain = 2;
|
||||
const float u_img_bias = 0;
|
||||
const float u_beam_bias = 0.185;
|
||||
const float u_beam_gain = 0.25;
|
||||
const float u_corner = 0.05;
|
||||
const float u_zoom = 1.0;
|
||||
const float u_shape = 2;
|
||||
const float u_round = -0.02;
|
||||
const float u_grain = 0.4;
|
||||
const float u_vpitch = 936.1;
|
||||
const float u_hpitch = 1024.6;
|
||||
const float u_top = 1;
|
||||
const float u_bot = 1;
|
||||
|
||||
void main() {
|
||||
const vec2 screenResolution = textureSize( samplerColor, 0 );
|
||||
const float u_lines = screenResolution.y * 0.75;
|
||||
|
||||
vec2 uv_orig = (inUv.xy * 2.0 - 1.0);
|
||||
vec2 uv_mod = uv_orig * pow(1.0-abs(uv_orig),vec2(u_round)) * (u_zoom + u_corner * pow( abs(uv_orig.yx), vec2(u_shape)) );
|
||||
vec2 uv = uv_mod / 2.0 + 0.5;
|
||||
|
||||
if ( abs(uv_mod).x > 1.0 || abs(uv_mod.y) > 1.0 ) {
|
||||
outColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float spacing = 1.0/u_lines;
|
||||
uv+=spacing*0.5;
|
||||
|
||||
float line_top = ( ceil(uv.y*u_lines)) / u_lines;
|
||||
float line_bot = line_top - spacing;
|
||||
|
||||
vec2 scale = vec2(u_imgw, u_imgh);
|
||||
vec2 offset = vec2(u_imgx, u_imgy);
|
||||
|
||||
vec2 uv_top = (vec2(uv.x, line_top)+offset) * scale - (scale-1.0)*0.5 ;
|
||||
vec2 uv_bot = (vec2(uv.x, line_bot)+offset) * scale - (scale-1.0)*0.5 ;
|
||||
|
||||
uv_top -= spacing * 0.5;
|
||||
uv_bot -= spacing * 0.5;
|
||||
|
||||
vec4 sampled_top = texture(samplerColor, uv_top);
|
||||
vec4 sampled_bot = texture(samplerColor, uv_bot);
|
||||
|
||||
vec3 color_top = sampled_top.xyz * u_img_gain + u_img_bias;
|
||||
vec3 color_bot = sampled_bot.xyz * u_img_gain + u_img_bias;
|
||||
|
||||
float dist_top = pow(abs(uv.y - line_top), 1.0);
|
||||
float dist_bot = pow(abs(uv.y - line_bot), 1.0);
|
||||
|
||||
vec3 beam_top = 1.0 - (dist_top / (spacing * (color_top * u_beam_gain + u_beam_bias)));
|
||||
vec3 beam_bot = 1.0 - (dist_bot / (spacing * (color_bot * u_beam_gain + u_beam_bias)));
|
||||
|
||||
beam_top = clamp(beam_top, 0.0, 1.0) ;
|
||||
beam_bot = clamp(beam_bot, 0.0, 1.0) ;
|
||||
|
||||
vec3 color = (color_top*beam_top)*u_top + (color_bot*beam_bot)*u_bot;
|
||||
|
||||
vec2 dot;
|
||||
dot.y = floor(uv.y * u_vpitch) ;
|
||||
dot.x = uv.x;
|
||||
|
||||
if (mod(dot.y, 2.0) > 0.5)
|
||||
dot.x += (4.5/3.0) / u_hpitch;
|
||||
|
||||
dot.x = (floor(dot.x*u_hpitch)) ;
|
||||
|
||||
int fil = int(mod(dot.x, 3.0));
|
||||
|
||||
vec3 out_color = color * (1.0-u_grain);
|
||||
|
||||
vec3 passthru = vec3(
|
||||
float(fil == 0),
|
||||
float(fil == 1),
|
||||
float(fil == 2)
|
||||
) * (u_grain);
|
||||
|
||||
out_color += color * passthru;
|
||||
|
||||
outColor = vec4(out_color, (sampled_top.a + sampled_bot.a) * 0.5 );
|
||||
|
||||
#if TONE_MAP
|
||||
toneMap(outColor, ubo.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
float iTime = 0;
|
||||
float noise(vec2 p) {
|
||||
float s = (fract(sin(dot(p * sin( iTime * 0.5 ), vec2(12.9898,78.233)*2.0)) * 43758.5453)); // texture(iChannel1,vec2(1.,2.*cos(iTime))*iTime*8. + p*1.).x;
|
||||
s *= s;
|
||||
return s;
|
||||
}
|
||||
|
||||
float onOff(float a, float b, float c) {
|
||||
return step(c, sin(iTime + a*cos(iTime*b)));
|
||||
}
|
||||
|
||||
float ramp(float y, float start, float end) {
|
||||
float inside = step(start,y) - step(end,y);
|
||||
float fact = (y-start)/(end-start)*inside;
|
||||
return (1.-fact) * inside;
|
||||
|
||||
}
|
||||
|
||||
float stripes(vec2 uv) {
|
||||
float noi = noise(uv*vec2(0.5,1.) + vec2(1.,3.));
|
||||
return ramp(mod(uv.y*4. + iTime/2.+sin(iTime + sin(iTime*0.63)),1.),0.5,0.6)*noi;
|
||||
}
|
||||
|
||||
vec4 getVideo(vec2 uv) {
|
||||
vec2 look = uv;
|
||||
float window = 1./(1.+20.*(look.y-mod(iTime/4.,1.))*(look.y-mod(iTime/4.,1.)));
|
||||
look.x = look.x + sin(look.y*10. + iTime)/50.*onOff(4.,4.,.3)*(1.+cos(iTime*80.))*window;
|
||||
float vShift = 0.4*onOff(2.,3.,.9)*(sin(iTime)*sin(iTime*20.) +
|
||||
(0.5 + 0.1*sin(iTime*200.)*cos(iTime)));
|
||||
look.y = mod(look.y + vShift, 1.);
|
||||
return texture(samplerColor,look);
|
||||
}
|
||||
|
||||
vec2 screenDistort(vec2 uv) {
|
||||
uv -= vec2(.5,.5);
|
||||
uv = uv*1.2*(1./1.2+2.*uv.x*uv.x*uv.y*uv.y);
|
||||
uv += vec2(.5,.5);
|
||||
return uv;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = inUv.xy; // fragCoord.xy / iResolution.xy;
|
||||
iTime = ubo.curTime;
|
||||
|
||||
uv = screenDistort(uv);
|
||||
vec4 video = getVideo(uv);
|
||||
float vigAmt = 3.+.3*sin(iTime + 5.*cos(iTime*5.));
|
||||
float vignette = (1.-vigAmt*(uv.y-.5)*(uv.y-.5))*(1.-vigAmt*(uv.x-.5)*(uv.x-.5));
|
||||
|
||||
video.rgb += stripes(uv);
|
||||
video.rgb += noise(uv*2.)/4.;
|
||||
video.rgb *= vignette;
|
||||
video.rgb *= (12.+mod(uv.y*30.+iTime,1.))/13.;
|
||||
|
||||
outColor = video;
|
||||
#if TONE_MAP
|
||||
toneMap(outColor, ubo.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
vec2 curveRemapUV(vec2 uv, vec2 curvature) {
|
||||
uv = uv * 2.0 - 1.0;
|
||||
vec2 offset = abs(uv.yx) / vec2(curvature.x, curvature.y);
|
||||
uv = uv + uv * offset * offset;
|
||||
uv = uv * 0.5 + 0.5;
|
||||
return uv;
|
||||
}
|
||||
|
||||
vec4 scanLineIntensity(float uv, float resolution, float opacity) {
|
||||
float intensity = sin(uv * resolution * PI * 2.0);
|
||||
intensity = ((0.5 * intensity) + 0.5) * 0.9 + 0.1;
|
||||
return vec4(vec3(pow(intensity, opacity)), 1.0);
|
||||
}
|
||||
|
||||
vec4 vignetteIntensity(vec2 uv, vec2 resolution, float opacity, float roundness) {
|
||||
float intensity = uv.x * uv.y * (1.0 - uv.x) * (1.0 - uv.y);
|
||||
return vec4(vec3(clamp(pow((resolution.x / roundness) * intensity, opacity), 0.0, 1.0)), 1.0);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
const vec2 screenResolution = textureSize( samplerColor, 0 );
|
||||
const vec2 scanLineOpacity = vec2(0.5);
|
||||
const float brightness = 2;
|
||||
const float vignetteOpacity = 0.5;
|
||||
const float vignetteRoundness = 0.5;
|
||||
const vec2 curvature = vec2(8);
|
||||
|
||||
const vec2 remappedUV = curveRemapUV(vec2(inUv.x, inUv.y), curvature);
|
||||
vec4 baseColor = texture(samplerColor, remappedUV);
|
||||
|
||||
baseColor *= vignetteIntensity(remappedUV, screenResolution, vignetteOpacity, vignetteRoundness);
|
||||
|
||||
baseColor *= scanLineIntensity(remappedUV.x, screenResolution.y, scanLineOpacity.x);
|
||||
baseColor *= scanLineIntensity(remappedUV.y, screenResolution.x, scanLineOpacity.y);
|
||||
|
||||
baseColor *= vec4(vec3(brightness), 1.0);
|
||||
|
||||
if (remappedUV.x < 0.0 || remappedUV.y < 0.0 || remappedUV.x > 1.0 || remappedUV.y > 1.0){
|
||||
outColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
} else {
|
||||
outColor = baseColor;
|
||||
}
|
||||
|
||||
#if TONE_MAP
|
||||
toneMap(outColor, ubo.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
vec2 fragCoord = vec2(0,0);
|
||||
vec2 iResolution = vec2(640,480);
|
||||
|
||||
// Emulated input resolution.
|
||||
#if 0
|
||||
// Fix resolution to set amount.
|
||||
#define res (vec2(320.0/1.0,160.0/1.0))
|
||||
#else
|
||||
// Optimize for resize.
|
||||
#define res (iResolution.xy/6.0)
|
||||
#endif
|
||||
|
||||
// Hardness of scanline.
|
||||
// -8.0 = soft
|
||||
// -16.0 = medium
|
||||
float hardScan=-8.0;
|
||||
|
||||
// Hardness of pixels in scanline.
|
||||
// -2.0 = soft
|
||||
// -4.0 = hard
|
||||
float hardPix=-3.0;
|
||||
|
||||
// Display warp.
|
||||
// 0.0 = none
|
||||
// 1.0/8.0 = extreme
|
||||
vec2 warp=vec2(1.0/32.0,1.0/24.0);
|
||||
|
||||
// Amount of shadow mask.
|
||||
float maskDark=0.5;
|
||||
float maskLight=1.5;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// sRGB to Linear.
|
||||
// Assuing using sRGB typed textures this should not be needed.
|
||||
float ToLinear1(float c){return(c<=0.04045)?c/12.92:pow((c+0.055)/1.055,2.4);}
|
||||
vec3 ToLinear(vec3 c){return vec3(ToLinear1(c.r),ToLinear1(c.g),ToLinear1(c.b));}
|
||||
|
||||
// Linear to sRGB.
|
||||
// Assuing using sRGB typed textures this should not be needed.
|
||||
float ToSrgb1(float c){return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);}
|
||||
vec3 ToSrgb(vec3 c){return vec3(ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));}
|
||||
|
||||
// Nearest emulated sample given floating point position and texel offset.
|
||||
// Also zero's off screen.
|
||||
vec3 Fetch(vec2 pos,vec2 off){
|
||||
pos=floor(pos*res+off)/res;
|
||||
if(max(abs(pos.x-0.5),abs(pos.y-0.5))>0.5)return vec3(0.0,0.0,0.0);
|
||||
return ToLinear(texture(samplerColor,pos.xy,-16.0).rgb);}
|
||||
|
||||
// Distance in emulated pixels to nearest texel.
|
||||
vec2 Dist(vec2 pos){pos=pos*res;return -((pos-floor(pos))-vec2(0.5));}
|
||||
|
||||
// 1D Gaussian.
|
||||
float Gaus(float pos,float scale){return exp2(scale*pos*pos);}
|
||||
|
||||
// 3-tap Gaussian filter along horz line.
|
||||
vec3 Horz3(vec2 pos,float off){
|
||||
vec3 b=Fetch(pos,vec2(-1.0,off));
|
||||
vec3 c=Fetch(pos,vec2( 0.0,off));
|
||||
vec3 d=Fetch(pos,vec2( 1.0,off));
|
||||
float dst=Dist(pos).x;
|
||||
// Convert distance to weight.
|
||||
float scale=hardPix;
|
||||
float wb=Gaus(dst-1.0,scale);
|
||||
float wc=Gaus(dst+0.0,scale);
|
||||
float wd=Gaus(dst+1.0,scale);
|
||||
// Return filtered sample.
|
||||
return (b*wb+c*wc+d*wd)/(wb+wc+wd);}
|
||||
|
||||
// 5-tap Gaussian filter along horz line.
|
||||
vec3 Horz5(vec2 pos,float off){
|
||||
vec3 a=Fetch(pos,vec2(-2.0,off));
|
||||
vec3 b=Fetch(pos,vec2(-1.0,off));
|
||||
vec3 c=Fetch(pos,vec2( 0.0,off));
|
||||
vec3 d=Fetch(pos,vec2( 1.0,off));
|
||||
vec3 e=Fetch(pos,vec2( 2.0,off));
|
||||
float dst=Dist(pos).x;
|
||||
// Convert distance to weight.
|
||||
float scale=hardPix;
|
||||
float wa=Gaus(dst-2.0,scale);
|
||||
float wb=Gaus(dst-1.0,scale);
|
||||
float wc=Gaus(dst+0.0,scale);
|
||||
float wd=Gaus(dst+1.0,scale);
|
||||
float we=Gaus(dst+2.0,scale);
|
||||
// Return filtered sample.
|
||||
return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);}
|
||||
|
||||
// Return scanline weight.
|
||||
float Scan(vec2 pos,float off){
|
||||
float dst=Dist(pos).y;
|
||||
return Gaus(dst+off,hardScan);}
|
||||
|
||||
// Allow nearest three lines to effect pixel.
|
||||
vec3 Tri(vec2 pos){
|
||||
vec3 a=Horz3(pos,-1.0);
|
||||
vec3 b=Horz5(pos, 0.0);
|
||||
vec3 c=Horz3(pos, 1.0);
|
||||
float wa=Scan(pos,-1.0);
|
||||
float wb=Scan(pos, 0.0);
|
||||
float wc=Scan(pos, 1.0);
|
||||
return a*wa+b*wb+c*wc;}
|
||||
|
||||
// Distortion of scanlines, and end of screen alpha.
|
||||
vec2 Warp(vec2 pos){
|
||||
pos=pos*2.0-1.0;
|
||||
pos*=vec2(1.0+(pos.y*pos.y)*warp.x,1.0+(pos.x*pos.x)*warp.y);
|
||||
return pos*0.5+0.5;}
|
||||
|
||||
// Shadow mask.
|
||||
vec3 Mask(vec2 pos){
|
||||
pos.x+=pos.y*3.0;
|
||||
vec3 mask=vec3(maskDark,maskDark,maskDark);
|
||||
pos.x=fract(pos.x/6.0);
|
||||
if(pos.x<0.333)mask.r=maskLight;
|
||||
else if(pos.x<0.666)mask.g=maskLight;
|
||||
else mask.b=maskLight;
|
||||
return mask;}
|
||||
|
||||
void main() {
|
||||
iResolution = textureSize( samplerColor, 0 );
|
||||
fragCoord = inUv * iResolution;
|
||||
|
||||
vec2 pos = Warp(fragCoord.xy / iResolution.xy);
|
||||
|
||||
hardScan = -12.0;
|
||||
maskDark = maskLight = 1.0;
|
||||
|
||||
outColor.rgb = Tri(pos) * Mask(fragCoord.xy);
|
||||
outColor.rgb = ToSrgb(outColor.rgb);
|
||||
outColor.a = 1.0;
|
||||
|
||||
#if TONE_MAP
|
||||
toneMap(outColor, ubo.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
void main() {
|
||||
const vec2 uv = 0.025 * sin( ubo.curTime ) * inUv.xy;
|
||||
const float mdf = 0.5;
|
||||
const float noise = (fract(sin(dot(uv, vec2(12.9898,78.233)*2.0)) * 43758.5453));
|
||||
const vec4 sampled = texture( samplerColor, inUv );
|
||||
|
||||
outColor = sampled - noise * mdf;
|
||||
|
||||
toneMap(outColor, ubo.exposure);
|
||||
gammaCorrect(outColor, ubo.gamma);
|
||||
}
|
||||
#endif
|
||||
16
bin/data/shaders - 1.1/display/renderTarget/vert.glsl
Normal file
16
bin/data/shaders - 1.1/display/renderTarget/vert.glsl
Normal file
@ -0,0 +1,16 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out flat uint outPass;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
void main() {
|
||||
outUv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
outPass = PushConstant.pass;
|
||||
gl_Position = vec4(outUv * 2.0f + -1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
148
bin/data/shaders - 1.1/display/vxgi/comp.glsl
Normal file
148
bin/data/shaders - 1.1/display/vxgi/comp.glsl
Normal file
@ -0,0 +1,148 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
||||
|
||||
#define COMPUTE 1
|
||||
|
||||
#define VXGI 1
|
||||
#define MAX_CUBEMAPS CUBEMAPS
|
||||
#define GAMMA_CORRECT 1
|
||||
#define PBR 1
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 512;
|
||||
layout (constant_id = 1) const uint CUBEMAPS = 128;
|
||||
layout (constant_id = 2) const uint CASCADES = 16;
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
EyeMatrices eyes[2];
|
||||
|
||||
Settings settings;
|
||||
} ubo;
|
||||
layout (std140, binding = 1) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 2) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
layout (std140, binding = 3) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
layout (std140, binding = 4) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 5) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 6) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout (binding = 7) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 8) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 9) uniform sampler3D samplerNoise;
|
||||
|
||||
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 = 12, rgba32f) uniform volatile coherent image3D voxelRadiance[CASCADES];
|
||||
#else
|
||||
layout (binding = 12, rgba16f) uniform volatile coherent image3D voxelRadiance[CASCADES];
|
||||
#endif
|
||||
|
||||
#include "../../common/functions.h"
|
||||
#include "../../common/light.h"
|
||||
#undef VXGI //
|
||||
#include "../../common/shadows.h"
|
||||
void main() {
|
||||
const vec3 tUvw = gl_GlobalInvocationID.xzy;
|
||||
for ( uint CASCADE = 0; CASCADE < CASCADES; ++CASCADE ) {
|
||||
surface.normal.world = decodeNormals( vec2(imageLoad(voxelNormal[CASCADE], ivec3(tUvw) ).xy) );
|
||||
surface.normal.eye = vec3( ubo.settings.vxgi.matrix * vec4( surface.normal.world, 0.0f ) );
|
||||
|
||||
surface.position.eye = (vec3(gl_GlobalInvocationID.xyz) / vec3(imageSize(voxelRadiance[CASCADE])) * 2.0f - 1.0f) * cascadePower(CASCADE);
|
||||
surface.position.world = vec3( inverse(ubo.settings.vxgi.matrix) * vec4( surface.position.eye, 1.0f ) );
|
||||
|
||||
const uvec2 ID = uvec2(imageLoad(voxelId[CASCADE], ivec3(tUvw) ).xy);
|
||||
const uint drawID = ID.x - 1;
|
||||
const uint instanceID = ID.y - 1;
|
||||
if ( ID.x == 0 || ID.y == 0 ) {
|
||||
imageStore(voxelRadiance[CASCADE], ivec3(tUvw), vec4(0));
|
||||
continue;
|
||||
}
|
||||
const DrawCommand drawCommand = drawCommands[drawID];
|
||||
surface.instance = instances[instanceID];
|
||||
const Material material = materials[surface.instance.materialID];
|
||||
surface.material.albedo = material.colorBase;
|
||||
surface.fragment = material.colorEmissive;
|
||||
|
||||
surface.material.albedo = imageLoad(voxelRadiance[CASCADE], ivec3(tUvw) );
|
||||
surface.material.metallic = material.factorMetallic;
|
||||
surface.material.roughness = material.factorRoughness;
|
||||
surface.material.occlusion = material.factorOcclusion;
|
||||
|
||||
const vec3 ambient = ubo.settings.lighting.ambient.rgb * surface.material.occlusion;
|
||||
if ( validTextureIndex( surface.instance.lightmapID ) ) {
|
||||
surface.fragment.rgb += surface.material.albedo.rgb;
|
||||
} else {
|
||||
surface.fragment.rgb += surface.material.albedo.rgb * ambient;
|
||||
// corrections
|
||||
surface.position.eye = vec3( ubo.eyes[surface.pass].view * vec4( surface.position.world, 1 ) );
|
||||
surface.normal.eye = vec3( ubo.eyes[surface.pass].view * vec4(surface.normal.world, 0) );
|
||||
pbr();
|
||||
/*
|
||||
surface.material.roughness *= 4.0;
|
||||
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
|
||||
const vec3 Lo = normalize( surface.position.world );
|
||||
const float cosLo = max(0.0, dot(surface.normal.world, Lo));
|
||||
for ( uint i = 0; i < ubo.settings.lengths.lights; ++i ) {
|
||||
const Light light = lights[i];
|
||||
if ( light.power <= LIGHT_POWER_CUTOFF ) continue;
|
||||
if ( light.type >= 0 && validTextureIndex( surface.instance.lightmapID ) ) continue;
|
||||
const vec3 Lp = light.position;
|
||||
const vec3 Liu = light.position - surface.position.world;
|
||||
const vec3 Li = normalize(Liu);
|
||||
const float Ls = shadowFactor( light, 0.0 );
|
||||
const float La = 1.0 / (1 + (PI * pow(length(Liu), 2.0)));
|
||||
if ( light.power * La * Ls <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const float cosLi = max(0.0, dot(surface.normal.world, Li));
|
||||
const vec3 Lr = light.color.rgb * light.power * La * Ls;
|
||||
#if LAMBERT
|
||||
const vec3 diffuse = surface.material.albedo.rgb;
|
||||
const vec3 specular = vec3(0);
|
||||
#elif PBR
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
const float cosLh = max(0.0, dot(surface.normal.world, Lh));
|
||||
|
||||
const vec3 F = fresnelSchlick( F0, max( 0.0, dot(Lh, Lo) ) );
|
||||
const float D = ndfGGX( cosLh, surface.material.roughness );
|
||||
const float G = gaSchlickGGX(cosLi, cosLo, surface.material.roughness);
|
||||
const vec3 diffuse = mix( vec3(1.0) - F, vec3(0.0), surface.material.metallic ) * surface.material.albedo.rgb;
|
||||
const vec3 specular = (F * D * G) / max(EPSILON, 4.0 * cosLi * cosLo);
|
||||
#endif
|
||||
// lightmapped, compute only specular
|
||||
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
surface.light.a += light.power * La * Ls;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
surface.fragment.rgb += surface.light.rgb;
|
||||
|
||||
#if TONE_MAP
|
||||
toneMap(surface.fragment.rgb, ubo.settings.bloom.exposure);
|
||||
#endif
|
||||
#if GAMMA_CORRECT
|
||||
gammaCorrect(surface.fragment.rgb, 1.0 / ubo.settings.bloom.gamma);
|
||||
#endif
|
||||
|
||||
imageStore(voxelRadiance[CASCADE], ivec3(tUvw), vec4(surface.fragment.rgb, surface.material.albedo.a));
|
||||
}
|
||||
}
|
||||
67
bin/data/shaders - 1.1/display/vxgi/mip.gaussian.comp.glsl
Normal file
67
bin/data/shaders - 1.1/display/vxgi/mip.gaussian.comp.glsl
Normal file
@ -0,0 +1,67 @@
|
||||
#version 450
|
||||
#pragma shader_stage(compute)
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
|
||||
|
||||
layout (constant_id = 0) const uint CASCADES = 16;
|
||||
layout (constant_id = 1) const uint MIPS = 16;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint cascade;
|
||||
uint mip;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 1, rg16f) uniform volatile coherent image3D voxelRadiance[CASCADES * MIPS];
|
||||
|
||||
const float gaussianWeights[] = {
|
||||
//Top slice
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
|
||||
//Center slice
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 4.0f,
|
||||
1 / 16.0f,
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 32.0f,
|
||||
|
||||
//Bottom slice
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
1 / 32.0f,
|
||||
1 / 64.0f,
|
||||
};
|
||||
|
||||
void main() {
|
||||
const ivec3 inUVW = ivec3(gl_GlobalInvocationID.xyz) * 2;
|
||||
const ivec3 outUVW = ivec3(gl_GlobalInvocationID.xyz);
|
||||
const uint CASCADE_IN = PushConstant.cascade * CASCADES + PushConstant.mip;
|
||||
const uint CASCADE_OUT = PushConstant.cascade * CASCADES + (PushConstant.mip + 1);
|
||||
|
||||
vec4 color = vec4(0);
|
||||
for ( int z = -1; z <= 1; ++z ) {
|
||||
for ( int y = -1; y <= 1; ++y ) {
|
||||
for ( int x = -1; x <= 1; ++x ) {
|
||||
color += imageLoad( voxelRadiance[CASCADE_IN], inUVW + ivec3(x,y,z) ) * gaussianWeights[x + 1 + (y + 1) * 3 + (z + 1) * 9];
|
||||
}
|
||||
}
|
||||
}
|
||||
imageStore(voxelRadiance[CASCADE_OUT], ivec3(outUVW), vec4(color));
|
||||
}
|
||||
5
bin/data/shaders - 1.1/graph/baking/frag.glsl
Normal file
5
bin/data/shaders - 1.1/graph/baking/frag.glsl
Normal file
@ -0,0 +1,5 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
#define RT 0
|
||||
#include "./frag.h"
|
||||
204
bin/data/shaders - 1.1/graph/baking/frag.h
Normal file
204
bin/data/shaders - 1.1/graph/baking/frag.h
Normal file
@ -0,0 +1,204 @@
|
||||
//#extension GL_EXT_nonuniform_qualifier : enable
|
||||
#if RT
|
||||
#extension GL_EXT_ray_tracing : enable
|
||||
#extension GL_EXT_ray_query : enable
|
||||
#endif
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 512;
|
||||
layout (constant_id = 1) const uint CUBEMAPS = 128;
|
||||
layout (constant_id = 2) const uint LAYERS = 32;
|
||||
|
||||
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 6) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
|
||||
#define SHADOW_SAMPLES 16
|
||||
#define FRAGMENT 1
|
||||
#define BAKING 1
|
||||
#define PBR 1
|
||||
#define MAX_LIGHTS min(ubo.lights, lights.length())
|
||||
#define MAX_SHADOWS MAX_LIGHTS
|
||||
#define VIEW_MATRIX camera.viewport[0].view
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
layout (binding = 7) uniform Camera {
|
||||
Viewport viewport[6];
|
||||
} camera;
|
||||
|
||||
layout (binding = 8) uniform UBO {
|
||||
uint lights;
|
||||
uint currentID;
|
||||
uint padding1;
|
||||
uint padding2;
|
||||
} ubo;
|
||||
|
||||
layout (std140, binding = 9) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 10) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
layout (std140, binding = 11) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
layout (std140, binding = 12) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 13) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 14) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout (binding = 15, rgba8) uniform volatile coherent image3D outAlbedos;
|
||||
|
||||
#if RT
|
||||
layout (binding = 16) uniform accelerationStructureEXT tlas;
|
||||
#endif
|
||||
|
||||
#include "../../common/functions.h"
|
||||
#if RT
|
||||
float shadowFactor( const Light light, float def ) {
|
||||
Ray ray;
|
||||
ray.origin = surface.position.world;
|
||||
ray.direction = light.position - ray.origin;
|
||||
|
||||
float tMin = 0.001;
|
||||
float tMax = length(ray.direction) + tMin;
|
||||
|
||||
ray.direction = normalize(ray.direction);
|
||||
|
||||
uint rayFlags = gl_RayFlagsOpaqueEXT | gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsSkipClosestHitShaderEXT;
|
||||
uint cullMask = 0xFF;
|
||||
|
||||
rayQueryEXT rayQuery;
|
||||
rayQueryInitializeEXT(rayQuery, tlas, rayFlags, cullMask, ray.origin, tMin, ray.direction, tMax);
|
||||
|
||||
while(rayQueryProceedEXT(rayQuery)) {}
|
||||
|
||||
return rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionNoneEXT ? 1.0 : 0.0;
|
||||
}
|
||||
#else
|
||||
#include "../../common/shadows.h"
|
||||
#endif
|
||||
|
||||
#include "../../common/light.h"
|
||||
|
||||
layout (location = 0) flat in uvec4 inId;
|
||||
layout (location = 1) flat in vec4 inPOS0;
|
||||
layout (location = 2) in vec4 inPOS1;
|
||||
layout (location = 3) in vec3 inPosition;
|
||||
layout (location = 4) in vec2 inUv;
|
||||
layout (location = 5) in vec4 inColor;
|
||||
layout (location = 6) in vec2 inSt;
|
||||
layout (location = 7) in vec3 inNormal;
|
||||
layout (location = 8) in vec3 inTangent;
|
||||
|
||||
layout (location = 0) out vec4 outAlbedo;
|
||||
|
||||
void main() {
|
||||
const uint triangleID = uint(inId.x); // gl_PrimitiveID
|
||||
const uint drawID = uint(inId.y);
|
||||
const uint instanceID = uint(inId.z);
|
||||
|
||||
if ( instanceID != ubo.currentID ) discard;
|
||||
|
||||
surface.uv.xy = wrap(inUv.xy);
|
||||
surface.uv.z = mipLevel(dFdx(inUv), dFdy(inUv));
|
||||
|
||||
surface.position.world = inPosition;
|
||||
surface.normal.world = inNormal;
|
||||
|
||||
const DrawCommand drawCommand = drawCommands[drawID];
|
||||
const Instance instance = instances[instanceID];
|
||||
const Material material = materials[instance.materialID];
|
||||
|
||||
const uint mapID = instance.auxID;
|
||||
|
||||
vec4 A = material.colorBase;
|
||||
surface.material.metallic = material.factorMetallic;
|
||||
surface.material.roughness = material.factorRoughness;
|
||||
surface.material.occlusion = 1.0f - material.factorOcclusion;
|
||||
|
||||
#if 0
|
||||
vec3 N = inNormal;
|
||||
vec3 T = inTangent;
|
||||
T = normalize(T - dot(T, N) * N);
|
||||
vec3 B = cross(T, N);
|
||||
mat3 TBN = mat3(T, B, N);
|
||||
// mat3 TBN = mat3(N, B, T);
|
||||
if ( T != vec3(0) && validTextureIndex( material.indexNormal ) ) {
|
||||
surface.normal.world = TBN * normalize( sampleTexture( material.indexNormal ).xyz * 2.0 - 1.0 );
|
||||
} else {
|
||||
surface.normal.world = N;
|
||||
}
|
||||
#endif
|
||||
|
||||
surface.light = material.colorEmissive;
|
||||
surface.material.albedo = vec4(1);
|
||||
{
|
||||
surface.normal.eye = surface.normal.eye;
|
||||
surface.position.eye = surface.position.eye;
|
||||
// pbr();
|
||||
|
||||
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
|
||||
for ( uint i = 0; i < min(ubo.lights, lights.length()); ++i ) {
|
||||
const Light light = lights[i];
|
||||
|
||||
if ( light.type <= 0 ) continue;
|
||||
|
||||
const mat4 mat = light.view; // inverse(light.view);
|
||||
const vec3 position = surface.position.world;
|
||||
// const vec3 position = vec3( mat * vec4(surface.position.world, 1.0) );
|
||||
const vec3 normal = surface.normal.world;
|
||||
// const vec3 normal = vec3( mat * vec4(surface.normal.world, 0.0) );
|
||||
|
||||
if ( light.power <= LIGHT_POWER_CUTOFF ) continue;
|
||||
const vec3 Lp = light.position;
|
||||
const vec3 Liu = light.position - surface.position.world;
|
||||
const float La = 1.0 / (1 + PI * pow(length(Liu), 2.0));
|
||||
const float Ls = shadowFactor( light, 0.0 );
|
||||
if ( light.power * La * Ls <= LIGHT_POWER_CUTOFF ) continue;
|
||||
|
||||
const vec3 Lo = normalize( -position );
|
||||
const float cosLo = max(0.0, abs(dot(normal, Lo)));
|
||||
|
||||
const vec3 Li = normalize(Liu);
|
||||
const vec3 Lr = light.color.rgb * light.power * La * Ls;
|
||||
// const float cosLi = max(0.0, dot(normal, Li));
|
||||
const float cosLi = abs(dot(normal, Li));
|
||||
#if LAMBERT
|
||||
const vec3 diffuse = surface.material.albedo.rgb;
|
||||
const vec3 specular = vec3(0);
|
||||
#elif PBR
|
||||
const vec3 Lh = normalize(Li + Lo);
|
||||
// const float cosLh = max(0.0, dot(normal, Lh));
|
||||
const float cosLh = abs(dot(normal, Lh));
|
||||
|
||||
const vec3 F = fresnelSchlick( F0, max( 0.0, dot(Lh, Lo) ) );
|
||||
const float D = 1; // ndfGGX( cosLh, surface.material.roughness );
|
||||
const float G = gaSchlickGGX(cosLi, cosLo, surface.material.roughness);
|
||||
const vec3 diffuse = mix( vec3(1.0) - F, vec3(0.0), surface.material.metallic ) * surface.material.albedo.rgb;
|
||||
const vec3 specular = (F * D * G) / max(EPSILON, 4.0 * cosLi * cosLo);
|
||||
#endif
|
||||
|
||||
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
|
||||
surface.light.a += light.power * La * Ls;
|
||||
}
|
||||
}
|
||||
#define EXPOSURE 0
|
||||
#define GAMMA 0
|
||||
|
||||
// surface.light.rgb = vec3(1.0) - exp(-surface.light.rgb * EXPOSURE);
|
||||
// surface.light.rgb = pow(surface.light.rgb, vec3(1.0 / GAMMA));
|
||||
|
||||
outAlbedo = vec4(surface.light.rgb, 1);
|
||||
|
||||
{
|
||||
const vec2 st = inSt.xy * imageSize(outAlbedos).xy;
|
||||
const ivec3 uvw = ivec3(int(st.x), int(st.y), int(mapID));
|
||||
imageStore(outAlbedos, uvw, vec4(surface.light.rgb, 1) );
|
||||
}
|
||||
}
|
||||
5
bin/data/shaders - 1.1/graph/baking/rt.frag.glsl
Normal file
5
bin/data/shaders - 1.1/graph/baking/rt.frag.glsl
Normal file
@ -0,0 +1,5 @@
|
||||
#version 460
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
#define RT 1
|
||||
#include "./frag.h"
|
||||
8
bin/data/shaders - 1.1/graph/baking/vert.glsl
Normal file
8
bin/data/shaders - 1.1/graph/baking/vert.glsl
Normal file
@ -0,0 +1,8 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define INSTANCED 1
|
||||
#define SKINNED 0
|
||||
#define BAKING 1
|
||||
|
||||
#include "../base/vert.h"
|
||||
126
bin/data/shaders - 1.1/graph/base/frag.glsl
Normal file
126
bin/data/shaders - 1.1/graph/base/frag.glsl
Normal file
@ -0,0 +1,126 @@
|
||||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
//#extension GL_EXT_nonuniform_qualifier : enable
|
||||
|
||||
#define FRAGMENT 1
|
||||
#define CAN_DISCARD 1
|
||||
|
||||
#define MAX_TEXTURES textures.length()
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 1;
|
||||
|
||||
|
||||
#include "../../common/macros.h"
|
||||
#include "../../common/structs.h"
|
||||
|
||||
#if BARYCENTRIC && !BARYCENTRIC_CALCULATE
|
||||
#define BARYCENTRIC_STABILIZE 1
|
||||
// #define BARY_COORD gl_BaryCoordEXT
|
||||
// #extension GL_EXT_fragment_shader_barycentric : enable
|
||||
#define BARY_COORD gl_BaryCoordSmoothAMD
|
||||
#extension GL_AMD_shader_explicit_vertex_parameter : enable
|
||||
#endif
|
||||
|
||||
layout (binding = 5) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (std140, binding = 6) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 7) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
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[];
|
||||
};
|
||||
|
||||
#include "../../common/functions.h"
|
||||
|
||||
layout (location = 0) flat in uvec4 inId;
|
||||
layout (location = 1) flat in vec4 inPOS0;
|
||||
#if BARYCENTRIC_STABILIZE
|
||||
layout (location = 2) __explicitInterpAMD in vec4 inPOS1;
|
||||
#else
|
||||
layout (location = 2) in vec4 inPOS1;
|
||||
#endif
|
||||
layout (location = 3) in vec3 inPosition;
|
||||
layout (location = 4) in vec2 inUv;
|
||||
layout (location = 5) in vec4 inColor;
|
||||
layout (location = 6) in vec2 inSt;
|
||||
layout (location = 7) in vec3 inNormal;
|
||||
layout (location = 8) in vec3 inTangent;
|
||||
|
||||
layout (location = 0) out uvec2 outId;
|
||||
#if BARYCENTRIC
|
||||
layout (location = 1) out vec2 outBary;
|
||||
#else
|
||||
layout (location = 1) out vec4 outUv;
|
||||
layout (location = 2) out vec4 outNormal;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
const uint triangleID = gl_PrimitiveID; // uint(inId.x);
|
||||
const uint drawID = uint(inId.y);
|
||||
const uint instanceID = uint(inId.z);
|
||||
|
||||
#if CAN_DISCARD
|
||||
const DrawCommand drawCommand = drawCommands[drawID];
|
||||
const Instance instance = instances[instanceID];
|
||||
const Material material = materials[instance.materialID];
|
||||
|
||||
surface.uv.xy = wrap(inUv.xy);
|
||||
surface.uv.z = mipLevel(dFdx(inUv), dFdy(inUv));
|
||||
|
||||
surface.st.xy = wrap(inSt.xy);
|
||||
surface.st.z = mipLevel(dFdx(inSt), dFdy(inSt));
|
||||
|
||||
vec4 A = inColor * material.colorBase;
|
||||
// sample albedo
|
||||
if ( validTextureIndex( material.indexAlbedo ) ) {
|
||||
A = sampleTexture( material.indexAlbedo );
|
||||
}
|
||||
// alpha mode OPAQUE
|
||||
if ( material.modeAlpha == 0 ) {
|
||||
A.a = 1;
|
||||
// alpha mode BLEND
|
||||
} else if ( material.modeAlpha == 1 ) {
|
||||
|
||||
// alpha mode MASK
|
||||
} else if ( material.modeAlpha == 2 ) {
|
||||
if ( A.a < abs(material.factorAlphaCutoff) ) discard;
|
||||
A.a = 1;
|
||||
}
|
||||
if ( A.a < 0.0001 ) discard;
|
||||
|
||||
#if !BARYCENTRIC
|
||||
outUv = vec4(surface.uv, surface.st);
|
||||
outNormal = vec4( encodeNormals(inNormal), encodeNormals(inTangent) );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
outId = uvec2(triangleID + 1, instanceID + 1);
|
||||
|
||||
#if BARYCENTRIC && !BARYCENTRIC_CALCULATE
|
||||
vec3 bary = vec3(gl_BaryCoordSmoothAMD.xy, 1 - gl_BaryCoordSmoothAMD.x - gl_BaryCoordSmoothAMD.y);
|
||||
bary = bary.yzx;
|
||||
#if BARYCENTRIC_STABILIZE
|
||||
vec4 v0 = interpolateAtVertexAMD(inPOS1, 0);
|
||||
vec4 v1 = interpolateAtVertexAMD(inPOS1, 1);
|
||||
vec4 v2 = interpolateAtVertexAMD(inPOS1, 2);
|
||||
if (v0 == inPOS0) outBary = encodeBarycentrics(bary.yzx);
|
||||
else if (v1 == inPOS0) outBary = encodeBarycentrics(bary.zxy);
|
||||
else if (v2 == inPOS0) outBary = encodeBarycentrics(bary.xyz);
|
||||
#else
|
||||
outBary = encodeBarycentrics(bary.xyz);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
6
bin/data/shaders - 1.1/graph/base/instanced.vert.glsl
Normal file
6
bin/data/shaders - 1.1/graph/base/instanced.vert.glsl
Normal file
@ -0,0 +1,6 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define INSTANCED 1
|
||||
#define SKINNED 0
|
||||
#include "./vert.h"
|
||||
@ -0,0 +1,6 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define INSTANCED 1
|
||||
#define SKINNED 1
|
||||
#include "./vert.h"
|
||||
6
bin/data/shaders - 1.1/graph/base/skinned.vert.glsl
Normal file
6
bin/data/shaders - 1.1/graph/base/skinned.vert.glsl
Normal file
@ -0,0 +1,6 @@
|
||||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
#define INSTANCED 0
|
||||
#define SKINNED 1
|
||||
#include "./vert.h"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user