initial commit, 4.5 stable
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled

This commit is contained in:
2025-09-16 20:46:46 -04:00
commit 9d30169a8d
13378 changed files with 7050105 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")
if "RD_GLSL" in env["BUILDERS"]:
# find all include files
gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")]
# find all shader code(all glsl files excluding our include files)
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
# make sure we recompile shaders if include files change
env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
# compile shaders
for glsl_file in glsl_files:
env.RD_GLSL(glsl_file)

View File

@@ -0,0 +1,43 @@
#[compute]
#version 450
#VERSION_DEFINES
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(r8, set = 0, binding = 0) uniform restrict writeonly image2D current_image;
// This shader is used to generate a "best fit normal texture" as described by:
// https://advances.realtimerendering.com/s2010/Kaplanyan-CryEngine3(SIGGRAPH%202010%20Advanced%20RealTime%20Rendering%20Course).pdf
// This texture tells you what length of normal can be used to store a unit vector
// with the lest amount of error.
vec3 quantize(vec3 c) {
return round(clamp(c * 0.5 + 0.5, 0.0, 1.0) * 255.0) * (1.0 / 255.0) * 2.0 - 1.0;
}
float find_minimum_error(vec3 normal) {
float min_error = 100000.0;
float t_best = 0.0;
for (float nstep = 1.5; nstep < 127.5; ++nstep) {
float t = nstep / 127.5;
vec3 vp = normal * t;
vec3 quantizedp = quantize(vp);
vec3 vdiff = (quantizedp - vp) / t;
float error = max(abs(vdiff.x), max(abs(vdiff.y), abs(vdiff.z)));
if (error < min_error) {
min_error = error;
t_best = t;
}
}
return t_best;
}
void main() {
vec2 uv = vec2(gl_GlobalInvocationID.xy) * vec2(1.0 / 1024.0) + vec2(0.5 / 1024.0);
uv.y *= uv.x;
vec3 dir = vec3(uv.x, uv.y, 1.0);
imageStore(current_image, ivec2(gl_GlobalInvocationID.xy), vec4(find_minimum_error(dir), 1.0, 1.0, 1.0));
}

View File

@@ -0,0 +1,156 @@
#[compute]
#version 450
// References:
// https://www.gamedevs.org/uploads/real-shading-in-unreal-engine-4.pdf
// https://google.github.io/filament/Filament.html
// https://learnopengl.com/PBR/IBL/Specular-IBL
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(rgba16f, set = 0, binding = 0) uniform restrict writeonly image2D current_image;
#define M_PI 3.14159265359
#define SAMPLE_COUNT 1024
#define SIZE 128
#define saturate(x) clamp(x, 0, 1)
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
// efficient VanDerCorpus calculation
float radical_inverse_vdc(uint bits) {
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
vec2 hammersley(uint i, float n) {
return vec2(float(i) / n, radical_inverse_vdc(i));
}
vec3 importance_sample_ggx(vec2 Xi, vec3 N, float roughness) {
float a = roughness * roughness;
float phi = 2.0 * M_PI * Xi.x;
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a * a - 1.0) * Xi.y));
float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
// from spherical coordinates to cartesian coordinates - halfway vector
vec3 H;
H.x = cos(phi) * sinTheta;
H.y = sin(phi) * sinTheta;
H.z = cosTheta;
// from tangent-space H vector to world-space sample vector
vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
vec3 tangent = normalize(cross(up, N));
vec3 bitangent = cross(N, tangent);
vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z;
return normalize(sampleVec);
}
float geometry_schlick_ggx(float NdotV, float roughness) {
// note that we use a different k for IBL
float a = roughness;
float k = (a * a) / 2.0;
float nom = NdotV;
float denom = NdotV * (1.0 - k) + k;
return nom / denom;
}
float geometry_smith(vec3 N, vec3 V, vec3 L, float roughness) {
float NdotV = saturate(dot(N, V));
float NdotL = saturate(dot(N, L));
float ggx2 = geometry_schlick_ggx(NdotV, roughness);
float ggx1 = geometry_schlick_ggx(NdotL, roughness);
return ggx1 * ggx2;
}
vec3 importance_uniform_sample(vec2 u) {
float phi = 2.0f * M_PI * u.x;
float cosTheta = 1 - u.y;
float sinTheta = sqrt(1 - cosTheta * cosTheta);
return vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
}
float distribution_charlie(float NoH, float roughness) {
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
float a = roughness * roughness;
float invAlpha = 1 / a;
float cos2h = NoH * NoH;
float sin2h = 1 - cos2h;
return (2.0f + invAlpha) * pow(sin2h, invAlpha * 0.5f) / (2.0f * M_PI);
}
float visibility_ashikhmin(float NoV, float NoL) {
// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
return 1 / (4 * (NoL + NoV - NoL * NoV));
}
void integrate_brdfs(float n_dot_v, float roughness, out vec2 brdf, out float cloth_brdf) {
vec3 v = vec3(sqrt(1.0 - n_dot_v * n_dot_v), 0, n_dot_v);
vec3 n = vec3(0.0f, 0.0f, 1.0f);
float A = 0.0f;
float B = 0.0f;
float C = 0.0f;
for (uint i = 0; i < SAMPLE_COUNT; ++i) {
vec2 Xi = hammersley(i, SAMPLE_COUNT);
vec3 h = importance_sample_ggx(Xi, n, roughness);
vec3 l = normalize(2.0 * dot(v, h) * h - v);
float n_dot_l = saturate(l.z);
float n_dot_h = saturate(h.z);
float v_dot_h = saturate(dot(v, h));
if (n_dot_l > 0.0) {
float G = geometry_smith(n, v, l, roughness);
float G_Vis = (G * v_dot_h) / (n_dot_h * n_dot_v);
float Fc = pow(1.0 - v_dot_h, 5.0);
// LDFG term for multiscattering
// https://google.github.io/filament/Filament.html#toc5.3.4.7
A += Fc * G_Vis;
B += G_Vis;
}
// Cloth BRDF calculations
// https://github.com/google/filament/blob/main/libs/ibl/src/CubemapIBL.cpp#L856-L874
vec3 h_cloth = importance_uniform_sample(Xi);
vec3 l_cloth = normalize(2.0 * dot(v, h_cloth) * h_cloth - v);
float n_dot_l_cloth = saturate(l_cloth.z);
float n_dot_h_cloth = saturate(h_cloth.z);
float v_dot_h_cloth = saturate(dot(v, h_cloth));
if (n_dot_l_cloth > 0.0) {
float v_cloth = visibility_ashikhmin(n_dot_v, n_dot_l_cloth);
float d_cloth = distribution_charlie(n_dot_h_cloth, roughness);
C += v_cloth * d_cloth * n_dot_l_cloth * v_dot_h_cloth;
}
}
A /= float(SAMPLE_COUNT);
B /= float(SAMPLE_COUNT);
C *= (4.0 * 2.0 * M_PI / SAMPLE_COUNT);
brdf = vec2(A, B);
cloth_brdf = C;
}
void main() {
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
float roughness = float(pos.y + 0.5f) / SIZE;
float NdotV = float(pos.x + 0.5f) / SIZE;
vec2 brdf;
float cloth_brdf;
integrate_brdfs(NdotV, roughness, brdf, cloth_brdf);
ivec2 out_pos = ivec2(pos.x, (SIZE - 1) - pos.y);
imageStore(current_image, out_pos, vec4(brdf, cloth_brdf, 1.0));
}

View File

@@ -0,0 +1,468 @@
#define M_PI 3.14159265359
#define M_TAU 6.28318530718
#define ROUGHNESS_MAX_LOD 5
#define MAX_VOXEL_GI_INSTANCES 8
#define MAX_VIEWS 2
#extension GL_KHR_shader_subgroup_ballot : enable
#extension GL_KHR_shader_subgroup_arithmetic : enable
#include "../cluster_data_inc.glsl"
#include "../decal_data_inc.glsl"
#include "../scene_data_inc.glsl"
#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(BENT_NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
#ifndef NORMAL_USED
#define NORMAL_USED
#endif
#endif
#if !defined(TANGENT_USED) && (defined(NORMAL_MAP_USED) || defined(BENT_NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED))
#define TANGENT_USED
#endif
layout(push_constant, std430) uniform DrawCall {
uint instance_index;
uint uv_offset;
uint multimesh_motion_vectors_current_offset;
uint multimesh_motion_vectors_previous_offset;
#ifdef UBERSHADER
uint sc_packed_0;
uint sc_packed_1;
uint sc_packed_2;
uint uc_packed_0;
#endif
}
draw_call;
/* Specialization Constants */
#ifdef UBERSHADER
#define POLYGON_CULL_DISABLED 0
#define POLYGON_CULL_FRONT 1
#define POLYGON_CULL_BACK 2
// Pull the constants from the draw call's push constants.
uint sc_packed_0() {
return draw_call.sc_packed_0;
}
uint sc_packed_1() {
return draw_call.sc_packed_1;
}
uint uc_cull_mode() {
return (draw_call.uc_packed_0 >> 0) & 3U;
}
#else
// Pull the constants from the pipeline's specialization constants.
layout(constant_id = 0) const uint pso_sc_packed_0 = 0;
layout(constant_id = 1) const uint pso_sc_packed_1 = 0;
uint sc_packed_0() {
return pso_sc_packed_0;
}
uint sc_packed_1() {
return pso_sc_packed_1;
}
#endif
bool sc_use_forward_gi() {
return ((sc_packed_0() >> 0) & 1U) != 0;
}
bool sc_use_light_projector() {
return ((sc_packed_0() >> 1) & 1U) != 0;
}
bool sc_use_light_soft_shadows() {
return ((sc_packed_0() >> 2) & 1U) != 0;
}
bool sc_use_directional_soft_shadows() {
return ((sc_packed_0() >> 3) & 1U) != 0;
}
bool sc_decal_use_mipmaps() {
return ((sc_packed_0() >> 4) & 1U) != 0;
}
bool sc_projector_use_mipmaps() {
return ((sc_packed_0() >> 5) & 1U) != 0;
}
bool sc_use_depth_fog() {
return ((sc_packed_0() >> 6) & 1U) != 0;
}
bool sc_use_lightmap_bicubic_filter() {
return ((sc_packed_0() >> 7) & 1U) != 0;
}
uint sc_soft_shadow_samples() {
return (sc_packed_0() >> 8) & 63U;
}
uint sc_penumbra_shadow_samples() {
return (sc_packed_0() >> 14) & 63U;
}
uint sc_directional_soft_shadow_samples() {
return (sc_packed_0() >> 20) & 63U;
}
uint sc_directional_penumbra_shadow_samples() {
return (sc_packed_0() >> 26) & 63U;
}
bool sc_multimesh() {
return ((sc_packed_1() >> 0) & 1U) != 0;
}
bool sc_multimesh_format_2d() {
return ((sc_packed_1() >> 1) & 1U) != 0;
}
bool sc_multimesh_has_color() {
return ((sc_packed_1() >> 2) & 1U) != 0;
}
bool sc_multimesh_has_custom_data() {
return ((sc_packed_1() >> 3) & 1U) != 0;
}
float sc_luminance_multiplier() {
// Not used in clustered renderer but we share some code with the mobile renderer that requires this.
return 1.0;
}
#define SDFGI_MAX_CASCADES 8
/* Set 0: Base Pass (never changes) */
#include "../light_data_inc.glsl"
layout(set = 0, binding = 2) uniform sampler shadow_sampler;
#define INSTANCE_FLAGS_DYNAMIC (1 << 3)
#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 4)
#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 5)
#define INSTANCE_FLAGS_USE_SDFGI (1 << 6)
#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 7)
#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 8)
#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 9)
#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 10)
#define INSTANCE_FLAGS_PARTICLES (1 << 11)
#define INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT 16
#define INSTANCE_FLAGS_FADE_SHIFT 24
//3 bits of stride
#define INSTANCE_FLAGS_PARTICLE_TRAIL_MASK 0xFF
#define SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO 1
#define SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL 2
layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights {
LightData data[];
}
omni_lights;
layout(set = 0, binding = 4, std430) restrict readonly buffer SpotLights {
LightData data[];
}
spot_lights;
layout(set = 0, binding = 5, std430) restrict readonly buffer ReflectionProbeData {
ReflectionData data[];
}
reflections;
layout(set = 0, binding = 6, std140) uniform DirectionalLights {
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
}
directional_lights;
#define LIGHTMAP_FLAG_USE_DIRECTION 1
#define LIGHTMAP_FLAG_USE_SPECULAR_DIRECTION 2
#define LIGHTMAP_SHADOWMASK_MODE_NONE 0
#define LIGHTMAP_SHADOWMASK_MODE_REPLACE 1
#define LIGHTMAP_SHADOWMASK_MODE_OVERLAY 2
#define LIGHTMAP_SHADOWMASK_MODE_ONLY 3
struct Lightmap {
mat3 normal_xform;
vec2 light_texture_size;
float exposure_normalization;
uint flags;
};
layout(set = 0, binding = 7, std140) restrict readonly buffer Lightmaps {
Lightmap data[];
}
lightmaps;
struct LightmapCapture {
vec4 sh[9];
};
layout(set = 0, binding = 8, std140) restrict readonly buffer LightmapCaptures {
LightmapCapture data[];
}
lightmap_captures;
layout(set = 0, binding = 9) uniform texture2D decal_atlas;
layout(set = 0, binding = 10) uniform texture2D decal_atlas_srgb;
layout(set = 0, binding = 11, std430) restrict readonly buffer Decals {
DecalData data[];
}
decals;
layout(set = 0, binding = 12, std430) restrict readonly buffer GlobalShaderUniformData {
vec4 data[];
}
global_shader_uniforms;
struct SDFVoxelGICascadeData {
vec3 position;
float to_probe;
ivec3 probe_world_offset;
float to_cell; // 1/bounds * grid_size
vec3 pad;
float exposure_normalization;
};
layout(set = 0, binding = 13, std140) uniform SDFGI {
vec3 grid_size;
uint max_cascades;
bool use_occlusion;
int probe_axis_size;
float probe_to_uvw;
float normal_bias;
vec3 lightprobe_tex_pixel_size;
float energy;
vec3 lightprobe_uv_offset;
float y_mult;
vec3 occlusion_clamp;
uint pad3;
vec3 occlusion_renormalize;
uint pad4;
vec3 cascade_probe_size;
uint pad5;
SDFVoxelGICascadeData cascades[SDFGI_MAX_CASCADES];
}
sdfgi;
layout(set = 0, binding = 14) uniform sampler DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP;
layout(set = 0, binding = 15) uniform texture2D best_fit_normal_texture;
layout(set = 0, binding = 16) uniform texture2D dfg;
/* Set 1: Render Pass (changes per render pass) */
layout(set = 1, binding = 0, std140) uniform SceneDataBlock {
SceneData data;
SceneData prev_data;
}
scene_data_block;
struct ImplementationData {
uint cluster_shift;
uint cluster_width;
uint cluster_type_size;
uint max_cluster_element_count_div_32;
uint ss_effects_flags;
float ssao_light_affect;
float ssao_ao_affect;
uint pad1;
mat4 sdf_to_bounds;
ivec3 sdf_offset;
uint pad2;
ivec3 sdf_size;
bool gi_upscale_for_msaa;
bool volumetric_fog_enabled;
float volumetric_fog_inv_length;
float volumetric_fog_detail_spread;
uint volumetric_fog_pad;
};
layout(set = 1, binding = 1, std140) uniform ImplementationDataBlock {
ImplementationData data;
}
implementation_data_block;
#define implementation_data implementation_data_block.data
struct InstanceData {
mat4 transform;
mat4 prev_transform;
uint flags;
uint instance_uniforms_ofs; //base offset in global buffer for instance variables
uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)
uint layer_mask;
vec4 lightmap_uv_scale;
vec4 compressed_aabb_position_pad; // Only .xyz is used. .w is padding.
vec4 compressed_aabb_size_pad; // Only .xyz is used. .w is padding.
vec4 uv_scale;
};
layout(set = 1, binding = 2, std430) buffer restrict readonly InstanceDataBuffer {
InstanceData data[];
}
instances;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
layout(set = 1, binding = 3) uniform textureCubeArray radiance_cubemap;
#else
layout(set = 1, binding = 3) uniform textureCube radiance_cubemap;
#endif
layout(set = 1, binding = 4) uniform textureCubeArray reflection_atlas;
layout(set = 1, binding = 5) uniform texture2D shadow_atlas;
layout(set = 1, binding = 6) uniform texture2D directional_shadow_atlas;
layout(set = 1, binding = 7) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES * 2];
layout(set = 1, binding = 8) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES];
layout(set = 1, binding = 9, std430) buffer restrict readonly ClusterBuffer {
uint data[];
}
cluster_buffer;
layout(set = 1, binding = 10) uniform sampler decal_sampler;
layout(set = 1, binding = 11) uniform sampler light_projector_sampler;
layout(set = 1, binding = 12 + 0) uniform sampler SAMPLER_NEAREST_CLAMP;
layout(set = 1, binding = 12 + 1) uniform sampler SAMPLER_LINEAR_CLAMP;
layout(set = 1, binding = 12 + 2) uniform sampler SAMPLER_NEAREST_WITH_MIPMAPS_CLAMP;
layout(set = 1, binding = 12 + 3) uniform sampler SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP;
layout(set = 1, binding = 12 + 4) uniform sampler SAMPLER_NEAREST_WITH_MIPMAPS_ANISOTROPIC_CLAMP;
layout(set = 1, binding = 12 + 5) uniform sampler SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_CLAMP;
layout(set = 1, binding = 12 + 6) uniform sampler SAMPLER_NEAREST_REPEAT;
layout(set = 1, binding = 12 + 7) uniform sampler SAMPLER_LINEAR_REPEAT;
layout(set = 1, binding = 12 + 8) uniform sampler SAMPLER_NEAREST_WITH_MIPMAPS_REPEAT;
layout(set = 1, binding = 12 + 9) uniform sampler SAMPLER_LINEAR_WITH_MIPMAPS_REPEAT;
layout(set = 1, binding = 12 + 10) uniform sampler SAMPLER_NEAREST_WITH_MIPMAPS_ANISOTROPIC_REPEAT;
layout(set = 1, binding = 12 + 11) uniform sampler SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_REPEAT;
#ifdef MODE_RENDER_SDF
layout(r16ui, set = 1, binding = 24) uniform restrict writeonly uimage3D albedo_volume_grid;
layout(r32ui, set = 1, binding = 25) uniform restrict writeonly uimage3D emission_grid;
layout(r32ui, set = 1, binding = 26) uniform restrict writeonly uimage3D emission_aniso_grid;
layout(r32ui, set = 1, binding = 27) uniform restrict uimage3D geom_facing_grid;
//still need to be present for shaders that use it, so remap them to something
#define depth_buffer shadow_atlas
#define color_buffer shadow_atlas
#define normal_roughness_buffer shadow_atlas
#define multiviewSampler sampler2D
#else
#ifdef USE_MULTIVIEW
layout(set = 1, binding = 24) uniform texture2DArray depth_buffer;
layout(set = 1, binding = 25) uniform texture2DArray color_buffer;
layout(set = 1, binding = 26) uniform texture2DArray normal_roughness_buffer;
layout(set = 1, binding = 27) uniform texture2DArray ao_buffer;
layout(set = 1, binding = 28) uniform texture2DArray ambient_buffer;
layout(set = 1, binding = 29) uniform texture2DArray reflection_buffer;
#define multiviewSampler sampler2DArray
#else // USE_MULTIVIEW
layout(set = 1, binding = 24) uniform texture2D depth_buffer;
layout(set = 1, binding = 25) uniform texture2D color_buffer;
layout(set = 1, binding = 26) uniform texture2D normal_roughness_buffer;
layout(set = 1, binding = 27) uniform texture2D ao_buffer;
layout(set = 1, binding = 28) uniform texture2D ambient_buffer;
layout(set = 1, binding = 29) uniform texture2D reflection_buffer;
#define multiviewSampler sampler2D
#endif
layout(set = 1, binding = 30) uniform texture2DArray sdfgi_lightprobe_texture;
layout(set = 1, binding = 31) uniform texture3D sdfgi_occlusion_cascades;
struct VoxelGIData {
mat4 xform; // 64 - 64
vec3 bounds; // 12 - 76
float dynamic_range; // 4 - 80
float bias; // 4 - 84
float normal_bias; // 4 - 88
bool blend_ambient; // 4 - 92
uint mipmaps; // 4 - 96
vec3 pad; // 12 - 108
float exposure_normalization; // 4 - 112
};
layout(set = 1, binding = 32, std140) uniform VoxelGIs {
VoxelGIData data[MAX_VOXEL_GI_INSTANCES];
}
voxel_gi_instances;
layout(set = 1, binding = 33) uniform texture3D volumetric_fog_texture;
#ifdef USE_MULTIVIEW
layout(set = 1, binding = 34) uniform texture2DArray ssil_buffer;
#else
layout(set = 1, binding = 34) uniform texture2D ssil_buffer;
#endif // USE_MULTIVIEW
#endif
vec4 normal_roughness_compatibility(vec4 p_normal_roughness) {
float roughness = p_normal_roughness.w;
if (roughness > 0.5) {
roughness = 1.0 - roughness;
}
roughness /= (127.0 / 255.0);
return vec4(normalize(p_normal_roughness.xyz * 2.0 - 1.0) * 0.5 + 0.5, roughness);
}
// https://google.github.io/filament/Filament.html#toc5.3.4.7
// Note: The roughness value is inverted
vec3 prefiltered_dfg(float lod, float NoV) {
return textureLod(sampler2D(dfg, SAMPLER_LINEAR_CLAMP), vec2(NoV, 1.0 - lod), 0.0).rgb;
}
// Compute multiscatter compensation
// https://google.github.io/filament/Filament.html#listing_energycompensationimpl
vec3 get_energy_compensation(vec3 f0, float env) {
return 1.0 + f0 * (1.0 / env - 1.0);
}
/* Set 2 Skeleton & Instancing (can change per item) */
layout(set = 2, binding = 0, std430) restrict readonly buffer Transforms {
vec4 data[];
}
transforms;
/* Set 3 User Material */