Files
fs2open.github.com/code/graphics/util/uniform_structs.h
T
Fabian Woltermann 115491f8a9 Refactor RT shadow handling and Vulkan depth operations (#7685)
- Introduced `shadow_ray_params` to simplify ray origin and cull mask management.
- Shifted shadow ray origins to TLAS-relative space for improved precision and consistency, especially for cockpit rendering.
- Refactored cascade bind functions, adding `shadow_cascade_params_bind_deferred()` for consolidated offset/count handling in deferred lighting.
- Expanded TLAS to include cockpits and additional object types, ensuring parity with rasterized shadows.
- Introduced per-instance cull masks to address cockpit self-shadowing issues.
- Improved Vulkan depth isolation for cockpit rendering via backup/restore mechanism, ensuring correct depth sampling in later passes.
- Extracted reusable helper functions for cockpit rendering state logic.
2026-09-21 05:12:55 +02:00

465 lines
8.8 KiB
C++

#pragma once
#include "globalincs/pstypes.h"
using SPIRV_FLOAT_MAT_4x4 = matrix4;
using SPIRV_FLOAT_VEC4 = vec4;
#include "shader_structs.h"
namespace graphics {
/**
* @file
*
* This file contains definitions for GPU uniform buffer structs. These structs must respect the std140 layout rules.
* The complete rules for this can be found here: https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)#Explicit_variable_layout,
* but the TL;DR here is that everything in here must be 16-byte aligned.
*/
struct deferred_global_data {
matrix4 inv_view_matrix;
float invScreenWidth;
float invScreenHeight;
float nearPlane;
float pad;
};
/**
* @brief Data for one deferred light rendering call
*/
struct deferred_light_data {
vec3d diffuseLightColor;
float coneAngle;
vec3d lightDir;
float coneInnerAngle;
vec3d coneDir;
int dualCone;
vec3d scale;
float lightRadius;
int lightType;
int enable_shadows;
float sourceRadius;
float pad0[1]; // Struct size must be 16-bytes aligned because we use vec3s
};
struct model_light {
vec4 position;
vec3d diffuse_color;
int light_type;
vec3d direction;
float attenuation;
float ml_sourceRadius;
float pad0[3];
};
const size_t MAX_UNIFORM_LIGHTS = 8;
struct model_uniform_data {
matrix4 modelViewMatrix;
matrix4 modelMatrix;
matrix4 viewMatrix;
matrix4 projMatrix;
matrix4 textureMatrix;
vec4 color;
model_light lights[MAX_UNIFORM_LIGHTS];
float outlineWidth;
float fogNear;
float fogDensity;
int buffer_matrix_offset;
vec4 clip_equation;
float thruster_scale;
int use_clip_plane;
int n_lights;
float defaultGloss;
vec3d ambientFactor;
int desaturate;
vec3d diffuseFactor;
int blend_alpha;
vec3d emissionFactor;
int alphaGloss;
int gammaSpec;
int envGloss;
int effect_num;
int sBasemapIndex;
vec4 fogColor;
vec3d base_color;
float anim_timer;
vec3d stripe_color;
float vpwidth;
float vpheight;
int team_glow_enabled;
float znear;
float zfar;
int sGlowmapIndex;
int sSpecmapIndex;
int sNormalmapIndex;
int sAmbientmapIndex;
int sMiscmapIndex;
float alphaMult;
int flags;
float pad;
};
const size_t model_uniform_data_size = sizeof(model_uniform_data);
const float mud_align = model_uniform_data_size / 16.0f;
struct shadow_uniform_data {
matrix4 modelViewMatrix;
matrix4 modelMatrix;
vec4 clip_equation;
int use_clip_plane;
int buffer_matrix_offset;
float pad[2];
};
const size_t shadow_uniform_data_size = sizeof(shadow_uniform_data);
struct shadow_cascade_static_data {
int cascade_offset;
int cascade_count;
float rtShadowBiasMin;
float rtShadowBiasMax;
matrix4 shadow_mv_matrix;
// Position of the view-space origin (the camera) in TLAS-relative space. The RT shadow
// ray origin is mat3(inverse(view)) * viewPos + shadow_ray_view_origin.
//
// The TLAS is not built in true world space: every instance is translated by
// -Shadow_rt_tlas_origin (shadows.h) so all coordinates near the viewer stay small.
// Float32 has ~1 mm steps at 10 km and ~8 mm at 100 km, which made cockpit-scale
// shadows shimmer far from the mission origin. The CPU computes this value from
// exact float differences instead of letting the shader add two large numbers. It is
// the camera position minus Shadow_rt_tlas_origin for ordinary passes; the cockpit
// pass renders in a different frame (view anchored at leaning_position, models offset
// in that same un-translated frame, never combined with objp->pos), so there it also
// includes the viewer ship's position -- see shadow_cascade_params_bind() (shadows.cpp)
// and its callers for where this is set.
//
// Declared before shadow_ray_cull_mask so the trailing int packs into this vec3's
// std140 alignment padding instead of needing a manual pad field (std140 gives a vec3
// 16-byte alignment but only 12-byte size, so a following scalar fills the gap for free).
vec3d shadow_ray_view_origin;
// Ray cull mask for raytraced shadow queries (traceShadowRay()/shadows.sdr). Excludes
// the viewer ship's own hull TLAS instance (TLAS_MASK_VIEWER_HULL, shadows.h) outside
// the cockpit pass, matching the rasterized path's exclusion of Viewer_obj from the
// main shadow cascades. Set in shadow_cascade_params_bind() (shadows.cpp).
int shadow_ray_cull_mask;
};
// Must match the GLSL shadowCascadeParams block's implicit std140 padding
// exactly (16 [4 leading scalars] + 64 [matrix4] + 12 [shadow_ray_view_origin]
// + 4 [shadow_ray_cull_mask, packed into the vec3's alignment padding] = 96) --
// shadow_cascade_params_bind() packs shadow_proj_matrix[] immediately after
// this struct via sizeof(), so a mismatch here silently shifts every cascade
// matrix in the buffer, in both backends.
static_assert(sizeof(shadow_cascade_static_data) == 96, "shadow_cascade_static_data must match the GLSL shadowCascadeParams layout (see comment above)");
enum class NanoVGShaderType: int32_t {
FillGradient = 0, FillImage = 1, Simple = 2, Image = 3
};
struct nanovg_draw_data {
float scissorMat[12]; // matrices are actually 3 vec4s
float paintMat[12];
vec4 innerCol;
vec4 outerCol;
vec2d scissorExt;
vec2d scissorScale;
vec2d extent;
float radius;
float feather;
float strokeMult;
float strokeThr;
int texType;
NanoVGShaderType type;
vec2d viewSize;
int texArrayIndex;
float pad3;
};
struct decal_globals {
matrix4 viewMatrix;
matrix4 projMatrix;
matrix4 invViewMatrix;
matrix4 invProjMatrix;
vec2d viewportSize;
float pad1[2];
};
struct decal_info {
int diffuse_index;
int glow_index;
int normal_index;
int diffuse_blend_mode;
int glow_blend_mode;
float pad[3];
};
struct matrix_uniforms {
matrix4 modelViewMatrix;
matrix4 projMatrix;
};
struct movie_uniforms {
float alpha;
float pad[3];
};
namespace generic_data {
struct passthrough_data {
int noTexturing;
int srgb;
float pad[2];
};
struct tonemapping_data {
float exposure;
int tonemapper;
float x0; //from here on these are for the PPC tonemappers
float y0;
float x1;
float toe_B;
float toe_lnA;
float sh_B;
float sh_lnA;
float sh_offsetX;
float sh_offsetY;
float hdr_paperwhite_nits;
float hdr_peak_nits;
float pad[3];
};
struct smaa_data {
vec2d smaa_rt_metrics;
float pad[2];
};
struct shield_impact_data {
matrix4 shieldModelViewMatrix;
matrix4 shieldProjMatrix;
vec3d hitNormal;
int srgb;
vec4 color;
int shieldMapIndex;
float pad[3];
};
struct rocketui_data {
matrix4 projMatrix;
vec2d offset;
int textured;
int baseMapIndex;
float horizontalSwipeOffset;
float pad[3];
};
struct lightshaft_data {
vec2d sun_pos;
float density;
float weight;
float falloff;
float intensity;
float cp_intensity;
float pad[1];
};
struct fxaa_data {
float rt_w;
float rt_h;
float pad[2];
};
struct fog_data {
vec3d fog_color;
float fog_start;
float fog_density;
float zNear;
float zFar;
float clip_inf_dist;
float clip_dist;
float pad[3];
};
struct volumetric_fog_data {
matrix4 p_inv;
matrix4 v_inv;
vec3d cameraPos;
float zNear;
vec3d globalLightDirection;
float zFar;
vec3d globalLightDiffuse;
float stepsize;
vec3d nebPos;
float opacitydistance;
vec3d nebSize;
float alphalimit;
float nebColor[3];
float udfScale;
float emissiveSpreadFactor;
float emissiveIntensity;
float emissiveFalloff;
float henyeyGreensteinCoeff;
float noiseColor[3];
int directionalLightSampleSteps;
float directionalLightStepSize;
float noiseColorScale1;
float noiseColorScale2;
float noiseColorIntensity;
float aspect;
float fov;
float pad[2];
};
struct msaa_data {
int samples;
float fov;
float pad[2];
};
struct blur_data {
float texSize;
int level;
float pad[2];
};
struct bloom_composition_data {
float bloom_intensity;
int levels;
float pad[2];
};
struct effect_data {
float window_width;
float window_height;
float nearZ;
float farZ;
int linear_depth;
int srgb;
int blend_alpha;
float pad[1];
};
struct effect_distort_data {
float window_width;
float window_height;
float use_offset;
float pad[1];
};
struct batched_data {
vec4 color;
float intensity;
float pad[3];
};
struct post_data {
float timer;
float noise_amount;
float saturation;
float brightness;
float contrast;
float film_grain;
float tv_stripes;
float cutoff;
vec3d tint;
float dither;
vec3d custom_effect_vec3_a;
float custom_effect_float_a;
vec3d custom_effect_vec3_b;
float custom_effect_float_b;
};
struct irrmap_data {
int face;
};
// Final output-encode pass (gamma-correct-f.sdr). The SDR leg uses only `gamma`;
// the HDR10 leg (SDR_FLAG_GAMMA_HDR10 / HDR10_OUTPUT variant) additionally uses
// the paper-white and peak nits. `gamma` is field 0 so both legs read it from
// the same std140 offset.
struct gamma_encode_data {
float gamma;
float hdr_paperwhite_nits; // HDR10_OUTPUT only
float hdr_peak_nits; // HDR10_OUTPUT only
float pad[1];
};
} // namespace generic_data
} // namespace graphics