Files
SDL3CPlusPlus/scripts/shader_variants.lua
johndoe6345789 cb5b58ca9e feat(physics): Enhance physics bridge service with new functionalities
- Added SetGravity method to adjust the gravity in the physics world.
- Introduced AddSphereRigidBody method for creating sphere rigid bodies.
- Implemented RemoveRigidBody method to delete existing rigid bodies.
- Added SetRigidBodyTransform method to update the position and rotation of rigid bodies.
- Included ApplyForce and ApplyImpulse methods for applying forces and impulses to rigid bodies.
- Added SetLinearVelocity method to set the linear velocity of rigid bodies.
- Enhanced StepSimulation method to accept a maxSubSteps parameter.
- Implemented GetBodyCount method to retrieve the number of rigid bodies in the world.
- Added Clear method to remove all rigid bodies from the physics world.
- Updated the script engine service to bind new physics methods to Lua.
- Enhanced material configuration handling in shader script service.
- Introduced MaterialXMaterialConfig structure for better material management.
- Added texture binding support in ShaderPaths structure.
- Included stb_image implementation for image loading support.
2026-01-07 00:20:19 +00:00

325 lines
9.3 KiB
Lua

local M = {}
local string_format = string.format
local function get_logger(log_debug)
if type(log_debug) == "function" then
return log_debug
end
return function()
end
end
local function resolve_color3(value, fallback)
if type(value) == "table" then
local r = tonumber(value[1])
local g = tonumber(value[2])
local b = tonumber(value[3])
if r and g and b then
return {r, g, b}
end
end
return {fallback[1], fallback[2], fallback[3]}
end
local function resolve_number_optional(value)
if type(value) == "number" then
return value
end
return nil
end
local function resolve_color3_optional(value)
if type(value) == "table" then
local r = tonumber(value[1])
local g = tonumber(value[2])
local b = tonumber(value[3])
if r and g and b then
return {r, g, b}
end
end
return nil
end
local function format_optional_number(value)
if type(value) == "number" then
return string_format("%.3f", value)
end
return "default"
end
local function format_optional_color(value)
if type(value) == "table"
and type(value[1]) == "number"
and type(value[2]) == "number"
and type(value[3]) == "number" then
return string_format("{%.2f, %.2f, %.2f}", value[1], value[2], value[3])
end
return "default"
end
local function build_shader_parameter_overrides(config, log_debug)
if type(config) ~= "table" or type(config.atmospherics) ~= "table" then
return {}
end
local atmospherics = config.atmospherics
local ambient_strength = resolve_number_optional(atmospherics.ambient_strength)
local light_intensity = resolve_number_optional(atmospherics.light_intensity)
local key_intensity = resolve_number_optional(atmospherics.key_light_intensity)
local fill_intensity = resolve_number_optional(atmospherics.fill_light_intensity)
local light_color = resolve_color3_optional(atmospherics.light_color)
local pbr_roughness = resolve_number_optional(atmospherics.pbr_roughness)
local pbr_metallic = resolve_number_optional(atmospherics.pbr_metallic)
local parameters = {}
local function apply_common(key)
if ambient_strength == nil and light_intensity == nil and light_color == nil then
return
end
local entry = {}
if ambient_strength ~= nil then
entry.ambient_strength = ambient_strength
end
if light_intensity ~= nil then
entry.light_intensity = light_intensity
end
if light_color ~= nil then
entry.light_color = light_color
end
parameters[key] = entry
end
apply_common("solid")
apply_common("floor")
apply_common("wall")
apply_common("ceiling")
if ambient_strength ~= nil or key_intensity ~= nil or fill_intensity ~= nil or light_intensity ~= nil then
local entry = {}
if ambient_strength ~= nil then
entry.ambient_strength = ambient_strength
end
if key_intensity ~= nil then
entry.key_intensity = key_intensity
elseif light_intensity ~= nil then
entry.key_intensity = light_intensity
end
if fill_intensity ~= nil then
entry.fill_intensity = fill_intensity
elseif light_intensity ~= nil then
entry.fill_intensity = light_intensity * 0.45
end
parameters.default = entry
end
if light_intensity ~= nil or light_color ~= nil or pbr_roughness ~= nil or pbr_metallic ~= nil then
local entry = {}
if light_intensity ~= nil then
entry.light_intensity = light_intensity
end
if light_color ~= nil then
entry.light_color = light_color
end
if pbr_roughness ~= nil then
entry.material_roughness = pbr_roughness
end
if pbr_metallic ~= nil then
entry.material_metallic = pbr_metallic
end
parameters.pbr = entry
end
if next(parameters) ~= nil then
log_debug("Shader lighting overrides: ambient=%s light_intensity=%s light_color=%s",
format_optional_number(ambient_strength),
format_optional_number(light_intensity),
format_optional_color(light_color))
end
return parameters
end
local function load_materialx_parameters(config, log_debug)
if type(config) ~= "table" then
return nil
end
local materialx = config.materialx
if type(materialx) ~= "table" then
return nil
end
local enabled = materialx.enabled
if type(materialx.parameters_enabled) == "boolean" then
enabled = materialx.parameters_enabled
end
if not enabled then
return nil
end
if type(materialx.document) ~= "string" or materialx.document == "" then
log_debug("MaterialX enabled but document path is missing")
return nil
end
if type(materialx_get_surface_parameters) ~= "function" then
log_debug("MaterialX loader unavailable (materialx_get_surface_parameters missing)")
return nil
end
local material_name = nil
if type(materialx.material) == "string" and materialx.material ~= "" then
material_name = materialx.material
end
local ok, result, err = pcall(materialx_get_surface_parameters, materialx.document, material_name)
if not ok then
log_debug("MaterialX parameter load failed: %s", tostring(result))
return nil
end
if result == nil then
log_debug("MaterialX parameter load failed: %s", tostring(err))
return nil
end
if type(result) ~= "table" then
log_debug("MaterialX parameter load returned unexpected result")
return nil
end
return result
end
local function resolve_skybox_color(config, default_color)
if type(config) ~= "table" then
return default_color
end
local atmospherics = config.atmospherics
if type(atmospherics) ~= "table" then
return default_color
end
return resolve_color3(atmospherics.sky_color, default_color)
end
local function build_static_cube_variants()
local fallback_vertex_source = [[
#version 450
layout(location = 0) in vec3 inPos;
layout(location = 1) in vec3 inNormal;
layout(location = 3) in vec3 inColor;
layout(location = 0) out vec3 fragColor;
layout(push_constant) uniform PushConstants {
mat4 model;
mat4 viewProj;
mat4 view;
mat4 proj;
mat4 lightViewProj;
vec3 cameraPos;
float time;
float ambientStrength;
float fogDensity;
float fogStart;
float fogEnd;
vec3 fogColor;
float gamma;
float exposure;
int enableShadows;
int enableFog;
} pushConstants;
void main() {
fragColor = inColor;
gl_Position = pushConstants.viewProj * pushConstants.model * vec4(inPos, 1.0);
}
]]
local fallback_fragment_source = [[
#version 450
layout(location = 0) in vec3 fragColor;
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(fragColor, 1.0);
}
]]
return {
default = {
vertex_source = fallback_vertex_source,
fragment_source = fallback_fragment_source,
},
solid = {
vertex_source = fallback_vertex_source,
fragment_source = fallback_fragment_source,
},
floor = {
vertex_source = fallback_vertex_source,
fragment_source = fallback_fragment_source,
},
wall = {
vertex_source = fallback_vertex_source,
fragment_source = fallback_fragment_source,
},
ceiling = {
vertex_source = fallback_vertex_source,
fragment_source = fallback_fragment_source,
},
pbr = {
vertex_source = fallback_vertex_source,
fragment_source = fallback_fragment_source,
},
skybox = {
vertex_source = fallback_vertex_source,
fragment_source = fallback_fragment_source,
},
}
end
function M.build_cube_variants(config, log_debug, base_skybox_color)
local logger = get_logger(log_debug)
local skybox_color = resolve_skybox_color(config, base_skybox_color or {0.04, 0.05, 0.08})
logger("Cube shaders: using fallback sources; MaterialX provides scene material")
return build_static_cube_variants(), skybox_color
end
function M.build_gui_variants()
local ok, toolkit = pcall(require, "shader_toolkit")
if not ok then
error("Shader toolkit unavailable: " .. tostring(toolkit))
end
local ok_generate, variant = pcall(toolkit.generate_variant, {
key = "default",
template = "gui_2d",
output_mode = "source",
compile = false,
})
if not ok_generate then
error("Shader generation failed: " .. tostring(variant))
end
return {default = variant}
end
function M.build_soundboard_variants()
local ok, toolkit = pcall(require, "shader_toolkit")
if not ok then
error("Shader toolkit unavailable: " .. tostring(toolkit))
end
local ok_generate, variant = pcall(toolkit.generate_variant, {
key = "default",
template = "cube_rainbow",
output_name = "cube",
output_mode = "source",
compile = false,
})
if not ok_generate then
error("Shader generation failed: " .. tostring(variant))
end
return {default = variant}
end
return M