mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-08 14:59:43 +01:00
feat(vulkan): vulkan 1.4 core with the user interface and the launcher, shaders split into ogl46/vk14 with SPIR-V binaries loaded first
This commit is contained in:
@@ -1,19 +1,24 @@
|
||||
#include "stdafx.h"
|
||||
#include "glsl_common.h"
|
||||
#include "rendering/common/shadersource.h"
|
||||
|
||||
std::string gl::glsl_common;
|
||||
|
||||
void gl::glsl_common_setup()
|
||||
{
|
||||
// the values shaders/ogl46/common.glsl takes instead of its own (MASZYNA_CONSTANTS). the settings of the game aren't here,
|
||||
// they are specialization constants of the binaries (glsl_settings_defines(), glsl_settings_values())
|
||||
glsl_common =
|
||||
"#define SHADOWMAP_ENABLED " + std::to_string((int)Global.gfx_shadowmap_enabled) + "\n" +
|
||||
"#define ENVMAP_ENABLED " + std::to_string((int)Global.gfx_envmap_enabled) + "\n" +
|
||||
"#define MOTIONBLUR_ENABLED " + std::to_string((int)Global.gfx_postfx_motionblur_enabled) + "\n" +
|
||||
"#define POSTFX_ENABLED " + std::to_string((int)!Global.gfx_skippipeline) + "\n" +
|
||||
"#define EXTRAEFFECTS_ENABLED " + std::to_string((int)Global.gfx_extraeffects) + "\n" +
|
||||
"#define MASZYNA_CONSTANTS 1\n"
|
||||
"#define MAX_LIGHTS " + std::to_string(MAX_LIGHTS) + "U\n" +
|
||||
"#define MAX_CASCADES " + std::to_string(MAX_CASCADES) + "U\n" +
|
||||
"#define MAX_PARAMS " + std::to_string(MAX_PARAMS) + "U\n" +
|
||||
"#define SHADOW_TEX " + std::to_string(SHADOW_TEX) + "\n" +
|
||||
"#define ENV_TEX " + std::to_string(ENV_TEX) + "\n" +
|
||||
"#define HEADLIGHT_TEX " + std::to_string(HEADLIGHT_TEX) + "\n" +
|
||||
"#define ENV_GGX_TEX " + std::to_string(ENV_GGX_TEX) + "\n" +
|
||||
"#define SCENE_UBO_BINDING " + std::to_string(SCENE_UBO_BINDING) + "\n" +
|
||||
"#define MODEL_UBO_BINDING " + std::to_string(MODEL_UBO_BINDING) + "\n" +
|
||||
"#define INSTANCE_SSBO_BINDING " + std::to_string(INSTANCE_SSBO_BINDING) + "\n" +
|
||||
"#define INSTANCE_RECORD_SSBO_BINDING " + std::to_string(INSTANCE_RECORD_SSBO_BINDING) + "\n" +
|
||||
"#define INSTANCE_JOB_SSBO_BINDING " + std::to_string(INSTANCE_JOB_SSBO_BINDING) + "\n" +
|
||||
@@ -86,223 +91,34 @@ void gl::glsl_common_setup()
|
||||
"#define MAX_CLOUD_LAYERS " + std::to_string(MAX_CLOUD_LAYERS) + "\n" +
|
||||
"#define FOG_HORIZON_SAMPLES " + std::to_string(FOG_HORIZON_SAMPLES) + "\n" +
|
||||
"#define WEATHER_GROUP_SIZE " + std::to_string(WEATHER_GROUP_SIZE) + "\n" +
|
||||
"#define FOG_VOLUME_BIAS " + std::to_string(FOG_VOLUME_BIAS) + "\n" +
|
||||
R"STRING(
|
||||
const uint LIGHT_SPOT = 0U;
|
||||
const uint LIGHT_POINT = 1U;
|
||||
const uint LIGHT_DIR = 2U;
|
||||
const uint LIGHT_HEADLIGHTS = 3U;
|
||||
|
||||
struct light_s
|
||||
{
|
||||
vec3 pos;
|
||||
uint type;
|
||||
|
||||
vec3 dir;
|
||||
float in_cutoff;
|
||||
|
||||
vec3 color;
|
||||
float out_cutoff;
|
||||
|
||||
float linear;
|
||||
float quadratic;
|
||||
|
||||
float intensity;
|
||||
float ambient;
|
||||
|
||||
mat4 headlight_projection;
|
||||
vec4 headlight_weights;
|
||||
};
|
||||
|
||||
// storage blocks are guaranteed only in fragment and compute shaders (GL 4.6 minimum for the other stages is 0)
|
||||
#if defined(STAGE_FRAGMENT) || defined(STAGE_COMPUTE)
|
||||
layout(std430, binding = LIGHT_SSBO_BINDING) readonly buffer light_ssbo
|
||||
{
|
||||
vec3 ambient;
|
||||
// lights stored in lights[], what the cluster culling goes through
|
||||
uint lights_total;
|
||||
|
||||
vec3 fog_color;
|
||||
// lights the shading loop goes through when the lights are not clustered
|
||||
uint lights_count;
|
||||
// 1 if the shading takes the lights from the list of the cluster of a fragment, see cluster_ubo
|
||||
uint lights_clustered;
|
||||
// scale of the directional part of the sky ambient light, see sky_ssbo
|
||||
float sky_ambient_factor;
|
||||
// 1 if rough reflections come from the prefiltered environment map
|
||||
uint env_ggx;
|
||||
|
||||
light_s lights[];
|
||||
};
|
||||
|
||||
// directional part of the sky ambient light: real spherical harmonics (bands 1 and 2, band 0 is ambient) of the light
|
||||
// a surface facing a world space direction gets, in units of ambient. see gl::sky_data
|
||||
layout(std430, binding = SKY_SSBO_BINDING) readonly buffer sky_ssbo
|
||||
{
|
||||
vec4 sky_ambient_sh[9];
|
||||
};
|
||||
#endif
|
||||
|
||||
// light clusters, see gl/cluster_grid.h
|
||||
struct cluster_aabb_s
|
||||
{
|
||||
vec4 lower;
|
||||
vec4 upper;
|
||||
};
|
||||
|
||||
struct cluster_range_s
|
||||
{
|
||||
uint offset;
|
||||
uint count;
|
||||
};
|
||||
|
||||
#if defined(STAGE_FRAGMENT) || defined(STAGE_COMPUTE)
|
||||
// parameters of the grid for the pass being drawn
|
||||
layout(std140, binding = CLUSTER_UBO_BINDING) uniform cluster_ubo
|
||||
{
|
||||
mat4 cluster_projection;
|
||||
float cluster_znear;
|
||||
float cluster_zfar;
|
||||
float cluster_slice_scale;
|
||||
float cluster_slice_bias;
|
||||
vec2 cluster_viewport_size;
|
||||
uint cluster_valid;
|
||||
};
|
||||
|
||||
// the compute passes fill the cluster buffers, shading only reads them
|
||||
#ifdef STAGE_COMPUTE
|
||||
#define CLUSTER_SSBO_ACCESS
|
||||
layout(std430, binding = CLUSTER_AABB_SSBO_BINDING) buffer cluster_aabb_ssbo
|
||||
{
|
||||
cluster_aabb_s cluster_aabbs[];
|
||||
};
|
||||
|
||||
layout(std430, binding = CLUSTER_COUNTER_SSBO_BINDING) buffer cluster_counter_ssbo
|
||||
{
|
||||
uint cluster_index_count;
|
||||
uint cluster_overflow_count;
|
||||
};
|
||||
#else
|
||||
#define CLUSTER_SSBO_ACCESS readonly
|
||||
#endif
|
||||
|
||||
layout(std430, binding = CLUSTER_RANGE_SSBO_BINDING) CLUSTER_SSBO_ACCESS buffer cluster_range_ssbo
|
||||
{
|
||||
cluster_range_s cluster_ranges[];
|
||||
};
|
||||
|
||||
layout(std430, binding = CLUSTER_INDEX_SSBO_BINDING) CLUSTER_SSBO_ACCESS buffer cluster_index_ssbo
|
||||
{
|
||||
uint cluster_light_indices[];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef MODEL_DRAWS
|
||||
// programs of the multi draws of the instances drawn from the gpu culling: the model block of every draw comes from a
|
||||
// storage buffer, picked by the number of the draw in the multi draw. the fragment stage gets the number from the vertex
|
||||
// stage (which writes f_model_draw), and the names of the uniform block below stand for the fields of the draw
|
||||
struct model_draw_s
|
||||
{
|
||||
mat4 modelview;
|
||||
mat3 modelviewnormal;
|
||||
vec4 param[MAX_PARAMS];
|
||||
|
||||
mat4 future;
|
||||
float opacity;
|
||||
float emission;
|
||||
float fog_density;
|
||||
float alpha_mult;
|
||||
float shadow_tone;
|
||||
};
|
||||
|
||||
layout(std430, binding = MODEL_DRAW_SSBO_BINDING) readonly buffer model_draw_ssbo
|
||||
{
|
||||
model_draw_s model_draws[];
|
||||
};
|
||||
|
||||
#if defined(STAGE_VERTEX)
|
||||
flat out uint f_model_draw;
|
||||
#define MODEL_DRAW gl_DrawID
|
||||
#elif defined(STAGE_FRAGMENT)
|
||||
flat in uint f_model_draw;
|
||||
#define MODEL_DRAW f_model_draw
|
||||
#else
|
||||
#define MODEL_DRAW 0
|
||||
#endif
|
||||
|
||||
#define modelview model_draws[MODEL_DRAW].modelview
|
||||
#define modelviewnormal model_draws[MODEL_DRAW].modelviewnormal
|
||||
#define param model_draws[MODEL_DRAW].param
|
||||
#define future model_draws[MODEL_DRAW].future
|
||||
#define opacity model_draws[MODEL_DRAW].opacity
|
||||
#define emission model_draws[MODEL_DRAW].emission
|
||||
#define fog_density model_draws[MODEL_DRAW].fog_density
|
||||
#define alpha_mult model_draws[MODEL_DRAW].alpha_mult
|
||||
#define shadow_tone model_draws[MODEL_DRAW].shadow_tone
|
||||
#else
|
||||
layout (std140) uniform model_ubo
|
||||
{
|
||||
mat4 modelview;
|
||||
mat3 modelviewnormal;
|
||||
vec4 param[MAX_PARAMS];
|
||||
|
||||
mat4 future;
|
||||
float opacity;
|
||||
float emission;
|
||||
float fog_density;
|
||||
float alpha_mult;
|
||||
float shadow_tone;
|
||||
};
|
||||
#endif
|
||||
|
||||
layout (std140) uniform scene_ubo
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 inv_view;
|
||||
mat4 lightview[MAX_CASCADES];
|
||||
vec3 cascade_end;
|
||||
float time;
|
||||
vec4 rain_params;
|
||||
vec4 wiper_pos;
|
||||
vec4 wiper_timer_out;
|
||||
vec4 wiper_timer_return;
|
||||
// shadow maps of the headlights, see gl::scene_ubs
|
||||
mat4 headlight_shadow[MAX_HEADLIGHT_SHADOWS];
|
||||
vec4 headlight_shadow_params[MAX_HEADLIGHT_SHADOWS];
|
||||
// contact shadows, see gl::scene_ubs
|
||||
vec4 contact_shadow_params;
|
||||
vec4 contact_shadow_lamps;
|
||||
// cascades of the sun shadows fitted to the depth of the view, see gl::scene_ubs
|
||||
vec4 shadow_fit;
|
||||
};
|
||||
|
||||
#ifdef STAGE_VERTEX
|
||||
// Per-instance modelview matrices for GPU-instanced draws, element 0 is identity.
|
||||
// Draws which aren't instanced have gl_BaseInstance == 0 and gl_InstanceID == 0,
|
||||
// so effective_modelview() reduces to model_ubo.modelview. For instanced draws
|
||||
// the C++ side uploads camera-space root transforms of the instances and draws
|
||||
// them from base instance onwards, with model_ubo.modelview set to the submodel-local
|
||||
// chain (computed from identity, NOT from the camera/instance), so the product
|
||||
// gives the correct final transform per instance per submodel.
|
||||
layout(std430, binding = INSTANCE_SSBO_BINDING) readonly buffer instance_ssbo
|
||||
{
|
||||
mat4 instance_modelview[];
|
||||
};
|
||||
|
||||
mat4 effective_modelview() {
|
||||
return instance_modelview[gl_BaseInstance + gl_InstanceID] * modelview;
|
||||
}
|
||||
mat3 effective_modelviewnormal() {
|
||||
// instance_modelview can include per-instance scale (uniform or per-axis),
|
||||
// so its upper-3x3 is NOT its own inverse-transpose in the non-uniform
|
||||
// case. Compute the correct normal matrix via transpose(inverse(...)).
|
||||
// For pure rotation+translation this still produces the rotation matrix
|
||||
// (one extra mat3 inverse per vertex — modern GPUs handle it cheaply).
|
||||
mat3 instance_mv3 = mat3(instance_modelview[gl_BaseInstance + gl_InstanceID]);
|
||||
mat3 instance_normal = transpose(inverse(instance_mv3));
|
||||
return instance_normal * modelviewnormal;
|
||||
}
|
||||
#endif
|
||||
|
||||
)STRING";
|
||||
"#define FOG_VOLUME_BIAS " + std::to_string(FOG_VOLUME_BIAS) + "\n";
|
||||
}
|
||||
|
||||
std::string gl::glsl_settings_defines()
|
||||
{
|
||||
auto const value = [](bool const Value) { return std::string(Value ? "true" : "false"); };
|
||||
return
|
||||
"#define SHADOWMAP_ENABLED_VALUE " + value(Global.gfx_shadowmap_enabled) + "\n"
|
||||
"#define ENVMAP_ENABLED_VALUE " + value(Global.gfx_envmap_enabled) + "\n"
|
||||
"#define MOTIONBLUR_ENABLED_VALUE " + value(Global.gfx_postfx_motionblur_enabled) + "\n"
|
||||
"#define POSTFX_ENABLED_VALUE " + value(!Global.gfx_skippipeline) + "\n"
|
||||
"#define EXTRAEFFECTS_ENABLED_VALUE " + value(Global.gfx_extraeffects) + "\n"
|
||||
"#define OUTPUT_GAMMA_VALUE " + value(Global.gfx_shadergamma) + "\n";
|
||||
}
|
||||
|
||||
std::array<GLuint, 6> gl::glsl_settings_values()
|
||||
{
|
||||
// in the order of gl::shader_setting
|
||||
return {
|
||||
static_cast<GLuint>(Global.gfx_shadowmap_enabled),
|
||||
static_cast<GLuint>(Global.gfx_envmap_enabled),
|
||||
static_cast<GLuint>(Global.gfx_postfx_motionblur_enabled),
|
||||
static_cast<GLuint>(!Global.gfx_skippipeline),
|
||||
static_cast<GLuint>(Global.gfx_extraeffects),
|
||||
static_cast<GLuint>(Global.gfx_shadergamma) };
|
||||
}
|
||||
|
||||
bool gl::glsl_common_matches(std::string const &Basedir, std::vector<std::string> &Differences)
|
||||
{
|
||||
return gfx::shader_constants_match(gfx::shader_api::opengl46, "common.glsl", glsl_common, Basedir, Differences);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user