mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-26 14:44:58 +00:00
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.
This commit is contained in:
@@ -202,6 +202,11 @@ local flight_layout = {
|
||||
height = 28,
|
||||
spacing = 8,
|
||||
}
|
||||
local physics_layout = {
|
||||
width = 140,
|
||||
height = 28,
|
||||
spacing = 8,
|
||||
}
|
||||
local ui_state = {
|
||||
flyUpActive = false,
|
||||
flyDownActive = false,
|
||||
@@ -271,6 +276,36 @@ local player_state = {
|
||||
noclip_toggle_pressed = false,
|
||||
}
|
||||
|
||||
local function physics_is_available()
|
||||
return type(physics_create_box) == "function"
|
||||
and type(physics_step_simulation) == "function"
|
||||
and type(physics_get_transform) == "function"
|
||||
and type(math3d.from_transform) == "function"
|
||||
end
|
||||
|
||||
local physics_cube_half_extents = {1.5, 1.5, 1.5}
|
||||
local physics_cube_scale = {physics_cube_half_extents[1], physics_cube_half_extents[2], physics_cube_half_extents[3]}
|
||||
local physics_cube_spawn = {
|
||||
0.0,
|
||||
room.floor_top + room.wall_height + physics_cube_half_extents[2] + 0.5,
|
||||
0.0,
|
||||
}
|
||||
|
||||
local physics_state = {
|
||||
enabled = physics_is_available(),
|
||||
ready = false,
|
||||
last_step_time = nil,
|
||||
max_sub_steps = 10,
|
||||
cube_name = "demo_cube",
|
||||
cube_half_extents = physics_cube_half_extents,
|
||||
cube_scale = physics_cube_scale,
|
||||
cube_mass = 1.0,
|
||||
cube_color = {0.92, 0.34, 0.28},
|
||||
cube_spawn = physics_cube_spawn,
|
||||
kick_strength = 6.0,
|
||||
gravity = {0.0, -9.8, 0.0},
|
||||
}
|
||||
|
||||
camera.position[1] = 0.0
|
||||
camera.position[2] = room.floor_top + player_state.eye_height
|
||||
camera.position[3] = 10.0
|
||||
@@ -294,6 +329,104 @@ local function scale_matrix(x, y, z)
|
||||
}
|
||||
end
|
||||
|
||||
local function ensure_physics_setup()
|
||||
if not physics_state.enabled then
|
||||
return false
|
||||
end
|
||||
if physics_state.ready then
|
||||
return true
|
||||
end
|
||||
|
||||
physics_state.last_step_time = nil
|
||||
if type(physics_clear) == "function" then
|
||||
physics_clear()
|
||||
end
|
||||
if type(physics_set_gravity) == "function" then
|
||||
local ok, err = physics_set_gravity(physics_state.gravity)
|
||||
if not ok then
|
||||
log_debug("Physics gravity failed: %s", err or "unknown")
|
||||
end
|
||||
end
|
||||
|
||||
local rotation = {0.0, 0.0, 0.0, 1.0}
|
||||
local function add_static_body(name, half_extents, origin)
|
||||
local ok, err = physics_create_box(name, half_extents, 0.0, origin, rotation)
|
||||
if not ok then
|
||||
log_debug("Physics static body %s failed: %s", name, err or "unknown")
|
||||
end
|
||||
end
|
||||
|
||||
local floor_center_y = room.floor_top - room.floor_half_thickness
|
||||
local wall_center_y = room.floor_top + room.wall_height
|
||||
local ceiling_y = room.floor_top + room.wall_height * 2 + room.floor_half_thickness
|
||||
local wall_offset = room.half_size + room.wall_thickness
|
||||
|
||||
add_static_body("room_floor",
|
||||
{room.half_size, room.floor_half_thickness, room.half_size},
|
||||
{0.0, floor_center_y, 0.0})
|
||||
add_static_body("room_ceiling",
|
||||
{room.half_size, room.floor_half_thickness, room.half_size},
|
||||
{0.0, ceiling_y, 0.0})
|
||||
add_static_body("room_wall_north",
|
||||
{room.half_size, room.wall_height, room.wall_thickness},
|
||||
{0.0, wall_center_y, -wall_offset})
|
||||
add_static_body("room_wall_south",
|
||||
{room.half_size, room.wall_height, room.wall_thickness},
|
||||
{0.0, wall_center_y, wall_offset})
|
||||
add_static_body("room_wall_west",
|
||||
{room.wall_thickness, room.wall_height, room.half_size},
|
||||
{-wall_offset, wall_center_y, 0.0})
|
||||
add_static_body("room_wall_east",
|
||||
{room.wall_thickness, room.wall_height, room.half_size},
|
||||
{wall_offset, wall_center_y, 0.0})
|
||||
|
||||
local ok, err = physics_create_box(
|
||||
physics_state.cube_name,
|
||||
physics_state.cube_half_extents,
|
||||
physics_state.cube_mass,
|
||||
physics_state.cube_spawn,
|
||||
rotation)
|
||||
if not ok then
|
||||
log_debug("Physics cube create failed: %s", err or "unknown")
|
||||
return false
|
||||
end
|
||||
|
||||
if type(physics_set_linear_velocity) == "function" then
|
||||
physics_set_linear_velocity(physics_state.cube_name, {0.0, 0.0, 0.0})
|
||||
end
|
||||
|
||||
physics_state.ready = true
|
||||
log_debug("Physics demo initialized")
|
||||
return true
|
||||
end
|
||||
|
||||
local function step_physics(time)
|
||||
if not physics_state.ready then
|
||||
return
|
||||
end
|
||||
if type(time) ~= "number" then
|
||||
return
|
||||
end
|
||||
if physics_state.last_step_time == time then
|
||||
return
|
||||
end
|
||||
|
||||
local dt = 0.0
|
||||
if physics_state.last_step_time then
|
||||
dt = time - physics_state.last_step_time
|
||||
end
|
||||
physics_state.last_step_time = time
|
||||
|
||||
if dt <= 0.0 then
|
||||
return
|
||||
end
|
||||
if dt > 0.1 then
|
||||
dt = 0.1
|
||||
end
|
||||
|
||||
physics_step_simulation(dt, physics_state.max_sub_steps)
|
||||
end
|
||||
|
||||
local function normalize(vec)
|
||||
local x, y, z = vec[1], vec[2], vec[3]
|
||||
local len = math.sqrt(x * x + y * y + z * z)
|
||||
@@ -332,6 +465,49 @@ local function forward_from_angles(yaw, pitch)
|
||||
}
|
||||
end
|
||||
|
||||
local function reset_physics_cube()
|
||||
if not physics_state.ready then
|
||||
return
|
||||
end
|
||||
if type(physics_set_transform) ~= "function" then
|
||||
return
|
||||
end
|
||||
local rotation = {0.0, 0.0, 0.0, 1.0}
|
||||
local ok, err = physics_set_transform(
|
||||
physics_state.cube_name,
|
||||
physics_state.cube_spawn,
|
||||
rotation)
|
||||
if not ok then
|
||||
log_debug("Physics reset failed: %s", err or "unknown")
|
||||
return
|
||||
end
|
||||
if type(physics_set_linear_velocity) == "function" then
|
||||
physics_set_linear_velocity(physics_state.cube_name, {0.0, 0.0, 0.0})
|
||||
end
|
||||
physics_state.last_step_time = nil
|
||||
end
|
||||
|
||||
local function kick_physics_cube()
|
||||
if not physics_state.ready then
|
||||
return
|
||||
end
|
||||
if type(physics_apply_impulse) ~= "function" then
|
||||
return
|
||||
end
|
||||
local forward = forward_from_angles(camera.yaw, camera.pitch)
|
||||
local lift = math.max(forward[2], 0.2)
|
||||
local direction = normalize({forward[1], lift, forward[3]})
|
||||
local impulse = {
|
||||
direction[1] * physics_state.kick_strength,
|
||||
direction[2] * physics_state.kick_strength,
|
||||
direction[3] * physics_state.kick_strength,
|
||||
}
|
||||
local ok, err = physics_apply_impulse(physics_state.cube_name, impulse)
|
||||
if not ok then
|
||||
log_debug("Physics impulse failed: %s", err or "unknown")
|
||||
end
|
||||
end
|
||||
|
||||
local atan2_available = type(math.atan2) == "function"
|
||||
if not atan2_available then
|
||||
log_debug("math.atan2 unavailable; using fallback for compass heading")
|
||||
@@ -540,6 +716,7 @@ local function apply_color_to_vertices(color)
|
||||
position = v.position,
|
||||
normal = v.normal,
|
||||
color = color,
|
||||
texcoord = v.texcoord,
|
||||
}
|
||||
end
|
||||
return colored_vertices
|
||||
@@ -579,6 +756,39 @@ local function create_skybox()
|
||||
}
|
||||
end
|
||||
|
||||
local function create_physics_cube()
|
||||
if not ensure_physics_setup() then
|
||||
return nil
|
||||
end
|
||||
local shader_key = resolve_material_shader()
|
||||
local last_matrix = math3d.identity()
|
||||
|
||||
local function compute_model_matrix(time)
|
||||
step_physics(time)
|
||||
local transform, err = physics_get_transform(physics_state.cube_name)
|
||||
if not transform then
|
||||
if lua_debug then
|
||||
log_debug("physics_get_transform failed: %s", err or "unknown")
|
||||
end
|
||||
return last_matrix
|
||||
end
|
||||
local matrix = math3d.from_transform(transform.position, transform.rotation)
|
||||
matrix = math3d.multiply(matrix, scale_matrix(
|
||||
physics_state.cube_scale[1],
|
||||
physics_state.cube_scale[2],
|
||||
physics_state.cube_scale[3]))
|
||||
last_matrix = matrix
|
||||
return matrix
|
||||
end
|
||||
|
||||
return {
|
||||
vertices = apply_color_to_vertices(physics_state.cube_color),
|
||||
indices = (#cube_indices_double_sided > 0) and cube_indices_double_sided or cube_indices,
|
||||
compute_model_matrix = compute_model_matrix,
|
||||
shader_key = shader_key,
|
||||
}
|
||||
end
|
||||
|
||||
local function create_spinning_cube()
|
||||
local shader_key = resolve_material_shader()
|
||||
log_debug("Spinning cube shader=%s", shader_key)
|
||||
@@ -597,11 +807,19 @@ local function create_spinning_cube()
|
||||
}
|
||||
end
|
||||
|
||||
local function create_dynamic_cube()
|
||||
local physics_cube = create_physics_cube()
|
||||
if physics_cube then
|
||||
return physics_cube
|
||||
end
|
||||
return create_spinning_cube()
|
||||
end
|
||||
|
||||
local function create_lantern(x, z)
|
||||
local lantern_height = 8
|
||||
local lantern_size = 0.2
|
||||
return create_static_cube({x, lantern_height, z},
|
||||
{lantern_size, lantern_size, lantern_size}, {1.0, 0.9, 0.6})
|
||||
{lantern_size, lantern_size, lantern_size}, {1.0, 0.9, 0.6}, "solid")
|
||||
end
|
||||
|
||||
local function create_room_objects()
|
||||
@@ -766,13 +984,53 @@ local function draw_flight_buttons()
|
||||
ui_state.flyDownPulse = down_clicked
|
||||
end
|
||||
|
||||
local function draw_physics_buttons()
|
||||
if not physics_state.enabled then
|
||||
return
|
||||
end
|
||||
local x = ui_layout.width - physics_layout.width - ui_layout.margin
|
||||
local y = ui_layout.margin * 3 + compass_layout.size
|
||||
+ flight_layout.height * 2 + flight_layout.spacing
|
||||
|
||||
Gui.text(gui_context, {
|
||||
x = x,
|
||||
y = y,
|
||||
width = physics_layout.width,
|
||||
height = 16,
|
||||
}, "Physics", {
|
||||
fontSize = 12,
|
||||
alignX = "center",
|
||||
color = {0.82, 0.88, 0.95, 1.0},
|
||||
})
|
||||
|
||||
local kick_clicked = Gui.button(gui_context, "physics_kick", {
|
||||
x = x,
|
||||
y = y + 18,
|
||||
width = physics_layout.width,
|
||||
height = physics_layout.height,
|
||||
}, "Kick Cube")
|
||||
if kick_clicked then
|
||||
kick_physics_cube()
|
||||
end
|
||||
|
||||
local reset_clicked = Gui.button(gui_context, "physics_reset", {
|
||||
x = x,
|
||||
y = y + 18 + physics_layout.height + physics_layout.spacing,
|
||||
width = physics_layout.width,
|
||||
height = physics_layout.height,
|
||||
}, "Reset Cube")
|
||||
if reset_clicked then
|
||||
reset_physics_cube()
|
||||
end
|
||||
end
|
||||
|
||||
function get_scene_objects()
|
||||
local objects = {}
|
||||
objects[#objects + 1] = create_skybox()
|
||||
for i = 1, #room_objects do
|
||||
objects[#objects + 1] = room_objects[i]
|
||||
end
|
||||
objects[#objects + 1] = create_spinning_cube()
|
||||
objects[#objects + 1] = create_dynamic_cube()
|
||||
return objects
|
||||
end
|
||||
|
||||
@@ -827,6 +1085,7 @@ function get_gui_commands()
|
||||
gui_context:beginFrame(gui_input)
|
||||
draw_compass_widget()
|
||||
draw_flight_buttons()
|
||||
draw_physics_buttons()
|
||||
gui_context:endFrame()
|
||||
return gui_context:getCommands()
|
||||
end
|
||||
|
||||
@@ -125,6 +125,12 @@ Context.__index = Context
|
||||
function Context:new(options)
|
||||
options = options or {}
|
||||
local style = options.style or DEFAULT_STYLE
|
||||
if options.style == nil and type(config) == "table" then
|
||||
local guiFont = config.gui_font
|
||||
if type(guiFont) == "table" and type(guiFont.font_size) == "number" then
|
||||
style.fontSize = guiFont.font_size
|
||||
end
|
||||
end
|
||||
local opacity = 1.0
|
||||
if type(config) == "table" and type(config.gui_opacity) == "number" then
|
||||
opacity = config.gui_opacity
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
local math3d = {}
|
||||
|
||||
local function require_glm(name)
|
||||
local fn = _G[name]
|
||||
if type(fn) ~= "function" then
|
||||
error("math3d requires missing binding: " .. name)
|
||||
end
|
||||
return fn
|
||||
end
|
||||
|
||||
local glm_identity = require_glm("glm_matrix_identity")
|
||||
local glm_multiply = require_glm("glm_matrix_multiply")
|
||||
local glm_translation = require_glm("glm_matrix_translation")
|
||||
local glm_rotation_x = require_glm("glm_matrix_rotation_x")
|
||||
local glm_rotation_y = require_glm("glm_matrix_rotation_y")
|
||||
local glm_from_transform = require_glm("glm_matrix_from_transform")
|
||||
local glm_look_at = require_glm("glm_matrix_look_at")
|
||||
local glm_perspective = require_glm("glm_matrix_perspective")
|
||||
|
||||
local function normalize(vec)
|
||||
local x, y, z = vec[1], vec[2], vec[3]
|
||||
local len = math.sqrt(x * x + y * y + z * z)
|
||||
@@ -31,89 +48,35 @@ local function identity_matrix()
|
||||
end
|
||||
|
||||
function math3d.identity()
|
||||
return identity_matrix()
|
||||
return glm_identity()
|
||||
end
|
||||
|
||||
function math3d.multiply(a, b)
|
||||
local result = {}
|
||||
for row = 1, 4 do
|
||||
for col = 1, 4 do
|
||||
local sum = 0.0
|
||||
for idx = 1, 4 do
|
||||
sum = sum + a[(idx - 1) * 4 + row] * b[(col - 1) * 4 + idx]
|
||||
end
|
||||
result[(col - 1) * 4 + row] = sum
|
||||
end
|
||||
end
|
||||
return result
|
||||
return glm_multiply(a, b)
|
||||
end
|
||||
|
||||
function math3d.translation(x, y, z)
|
||||
return {
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
x, y, z, 1.0,
|
||||
}
|
||||
return glm_translation(x, y, z)
|
||||
end
|
||||
|
||||
function math3d.rotation_x(radians)
|
||||
local c = math.cos(radians)
|
||||
local s = math.sin(radians)
|
||||
return {
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, c, s, 0.0,
|
||||
0.0, -s, c, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0,
|
||||
}
|
||||
return glm_rotation_x(radians)
|
||||
end
|
||||
|
||||
function math3d.rotation_y(radians)
|
||||
local c = math.cos(radians)
|
||||
local s = math.sin(radians)
|
||||
return {
|
||||
c, 0.0, -s, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
s, 0.0, c, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0,
|
||||
}
|
||||
return glm_rotation_y(radians)
|
||||
end
|
||||
|
||||
function math3d.from_transform(translation, rotation)
|
||||
return glm_from_transform(translation, rotation)
|
||||
end
|
||||
|
||||
function math3d.look_at(eye, center, up)
|
||||
local f = normalize({center[1] - eye[1], center[2] - eye[2], center[3] - eye[3]})
|
||||
local s = normalize(cross(f, up))
|
||||
local u = cross(s, f)
|
||||
|
||||
local result = identity_matrix()
|
||||
result[1] = s[1]
|
||||
result[2] = u[1]
|
||||
result[3] = -f[1]
|
||||
result[5] = s[2]
|
||||
result[6] = u[2]
|
||||
result[7] = -f[2]
|
||||
result[9] = s[3]
|
||||
result[10] = u[3]
|
||||
result[11] = -f[3]
|
||||
result[13] = -dot(s, eye)
|
||||
result[14] = -dot(u, eye)
|
||||
result[15] = dot(f, eye)
|
||||
return result
|
||||
return glm_look_at(eye, center, up)
|
||||
end
|
||||
|
||||
function math3d.perspective(fov, aspect, zNear, zFar)
|
||||
local tanHalf = math.tan(fov / 2.0)
|
||||
local result = {
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
}
|
||||
result[1] = 1.0 / (aspect * tanHalf)
|
||||
result[6] = -1.0 / tanHalf
|
||||
result[11] = zFar / (zNear - zFar)
|
||||
result[12] = -1.0
|
||||
result[15] = (zNear * zFar) / (zNear - zFar)
|
||||
return result
|
||||
return glm_perspective(fov, aspect, zNear, zFar)
|
||||
end
|
||||
|
||||
return math3d
|
||||
|
||||
@@ -316,7 +316,7 @@ local vertex_color_source = [[
|
||||
|
||||
layout(location = 0) in vec3 inPos;
|
||||
layout(location = 1) in vec3 inNormal;
|
||||
layout(location = 2) in vec3 inColor;
|
||||
layout(location = 3) in vec3 inColor;
|
||||
|
||||
layout(location = 0) out vec3 fragColor;
|
||||
|
||||
@@ -391,7 +391,7 @@ local shadow_vertex_source = [[
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec3 inNormal;
|
||||
layout(location = 2) in vec3 inColor;
|
||||
layout(location = 3) in vec3 inColor;
|
||||
|
||||
layout(push_constant) uniform PushConstants {
|
||||
mat4 model;
|
||||
@@ -596,7 +596,7 @@ local vertex_world_color_source = [[
|
||||
|
||||
layout(location = 0) in vec3 inPos;
|
||||
layout(location = 1) in vec3 inNormal;
|
||||
layout(location = 2) in vec3 inColor;
|
||||
layout(location = 3) in vec3 inColor;
|
||||
|
||||
layout(location = 0) out vec3 fragColor;
|
||||
layout(location = 1) out vec3 fragWorldPos;
|
||||
@@ -1030,7 +1030,7 @@ local pbr_vertex_source = [[
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
layout(location = 1) in vec3 inNormal;
|
||||
layout(location = 2) in vec3 inColor;
|
||||
layout(location = 3) in vec3 inColor;
|
||||
|
||||
layout(location = 0) out vec3 fragColor;
|
||||
layout(location = 1) out vec3 fragWorldPos;
|
||||
|
||||
@@ -203,7 +203,7 @@ local function build_static_cube_variants()
|
||||
|
||||
layout(location = 0) in vec3 inPos;
|
||||
layout(location = 1) in vec3 inNormal;
|
||||
layout(location = 2) in vec3 inColor;
|
||||
layout(location = 3) in vec3 inColor;
|
||||
|
||||
layout(location = 0) out vec3 fragColor;
|
||||
|
||||
@@ -275,72 +275,11 @@ void main() {
|
||||
}
|
||||
end
|
||||
|
||||
local function count_shader_variants(variants)
|
||||
local count = 0
|
||||
for _ in pairs(variants) do
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
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})
|
||||
local shader_parameters = build_shader_parameter_overrides(config, logger)
|
||||
local materialx_parameters = load_materialx_parameters(config, logger)
|
||||
if materialx_parameters then
|
||||
local entry = shader_parameters.pbr or {}
|
||||
local albedo = resolve_color3_optional(materialx_parameters.material_albedo)
|
||||
local roughness = resolve_number_optional(materialx_parameters.material_roughness)
|
||||
local metallic = resolve_number_optional(materialx_parameters.material_metallic)
|
||||
if albedo ~= nil then
|
||||
entry.material_albedo = albedo
|
||||
end
|
||||
if roughness ~= nil then
|
||||
entry.material_roughness = roughness
|
||||
end
|
||||
if metallic ~= nil then
|
||||
entry.material_metallic = metallic
|
||||
end
|
||||
if next(entry) ~= nil then
|
||||
shader_parameters.pbr = entry
|
||||
logger("MaterialX PBR overrides: albedo=%s roughness=%s metallic=%s",
|
||||
format_optional_color(albedo),
|
||||
format_optional_number(roughness),
|
||||
format_optional_number(metallic))
|
||||
end
|
||||
end
|
||||
|
||||
local ok, toolkit = pcall(require, "shader_toolkit")
|
||||
if not ok then
|
||||
logger("Shader toolkit unavailable: %s", tostring(toolkit))
|
||||
return build_static_cube_variants(), skybox_color
|
||||
end
|
||||
|
||||
local output_mode = "source"
|
||||
local compile = false
|
||||
local ok_generate, generated = pcall(toolkit.generate_cube_demo_variants,
|
||||
{compile = compile, output_mode = output_mode, parameters = shader_parameters})
|
||||
if not ok_generate then
|
||||
logger("Shader generation failed: %s", tostring(generated))
|
||||
return build_static_cube_variants(), skybox_color
|
||||
end
|
||||
|
||||
local ok_skybox, skybox_variant = pcall(toolkit.generate_variant, {
|
||||
key = "skybox",
|
||||
template = "solid_color",
|
||||
output_mode = output_mode,
|
||||
compile = compile,
|
||||
parameters = {color = skybox_color},
|
||||
})
|
||||
if ok_skybox then
|
||||
generated.skybox = skybox_variant
|
||||
else
|
||||
logger("Skybox shader generation failed: %s", tostring(skybox_variant))
|
||||
end
|
||||
|
||||
logger("Generated %d shader variants", count_shader_variants(generated))
|
||||
return generated, skybox_color
|
||||
logger("Cube shaders: using fallback sources; MaterialX provides scene material")
|
||||
return build_static_cube_variants(), skybox_color
|
||||
end
|
||||
|
||||
function M.build_gui_variants()
|
||||
|
||||
Reference in New Issue
Block a user