GOOENGINE: Fix light info node data storing

Switches the light info node to capture the light properties into GPU uniforms instead of accessing the values from the light data

This allows changing the color and energy without recompiling shaders and if the light object is animated the color and energy can be animated and update in the shader

Big thanks to Joseph and Thorn for their help with this
This commit is contained in:
2025-10-28 22:54:01 -05:00
parent a94f0ca1db
commit 4321d6f234
3 changed files with 35 additions and 35 deletions
-6
View File
@@ -1565,12 +1565,6 @@ typedef enum eNodeWaterRipplesMode {
NODE_WATER_RIPPLES_CAUSTIC = 3
} eNodeWaterRipplesMode;
typedef struct NodeShaderLightInfo {
/** Pointer to the Light object to get information from. */
struct Object *light_object;
char _pad[8];
} NodeShaderLightInfo;
typedef struct NodeSunBeams {
float source[2];
@@ -3139,11 +3139,6 @@ static void rna_NodeGroup_node_tree_set(PointerRNA *ptr,
}
}
static bool rna_NodeShaderLightInfo_light_object_poll(PointerRNA * /*ptr*/, const PointerRNA value)
{
return (static_cast<Object *>(value.data))->type == OB_LAMP;
}
static bool rna_NodeGroup_node_tree_poll(PointerRNA *ptr, const PointerRNA value)
{
bNodeTree *ntree = reinterpret_cast<bNodeTree *>(ptr->owner_id);
@@ -5890,9 +5885,8 @@ static void def_sh_light_info(StructRNA *srna)
PropertyRNA *prop;
prop = RNA_def_property(srna, "light_object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_pointer_sdna(prop, nullptr, "id");
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_pointer_funcs(prop, nullptr, nullptr, nullptr, "rna_NodeShaderLightInfo_light_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "Light Object", "Light object to get information from");
@@ -25,7 +25,6 @@
#include "UI_resources.hh"
#include "node_shader_util.hh"
#include "../../intern/node_util.hh"
namespace blender::nodes::node_shader_light_info_cc {
@@ -34,7 +33,6 @@ static void sh_node_light_info_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Color>("Light Color");
b.add_output<decl::Float>("Light Power");
b.add_output<decl::Float>("Perceptual Power");
// b.add_output<decl::Float>("Light Distance"); // Temporarily removed - causes crash
}
static void node_shader_draw_light_info(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
@@ -43,39 +41,53 @@ static void node_shader_draw_light_info(uiLayout *layout, bContext * /*C*/, Poin
uiItemR(layout, ptr, "light_object", UI_ITEM_R_SPLIT_EMPTY_NAME, "Light", ICON_LIGHT);
}
/* This is the function called during GPU node graph building (before compilation). */
static int node_shader_gpu_light_info(GPUMaterial *mat,
bNode *node,
bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
/* Capture light properties NOW (during graph building on main thread)
* and store them as GPU uniforms. This avoids accessing the Light object
* from the background compilation thread. */
Object *ob = (Object *)node->id;
/* Always use safe defaults to avoid crashes during material compilation */
float light_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float light_power = 1.0f;
/* Only try to access object data if everything is valid */
if (ob && ob != nullptr &&
ob->type == OB_LAMP &&
ob->data != nullptr) {
/* Always use safe defaults. */
static float default_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
static float default_power = 1.0f;
static float default_perceptual_power = 1.0f;
GPUNodeLink *color_link;
GPUNodeLink *power_link;
GPUNodeLink *perceptual_power_link;
/* Try to access light properties if object is valid. */
if (ob && ob->type == OB_LAMP && ob->data != nullptr) {
Light *light = (Light *)ob->data;
Object *light_ob = ob;
Light *light = (Light *)light_ob->data;
/* Capture the light properties as GPU uniforms (thread-safe). */
float color[4] = {light->r, light->g, light->b, 1.0f};
float power = light->energy;
float perceptual_power = light->energy;
/* Safely get light properties */
light_color[0] = light->r;
light_color[1] = light->g;
light_color[2] = light->b;
light_color[3] = 1.0f;
light_power = light->energy;
/* Use GPU_uniform to capture these values safely for later compilation. */
color_link = GPU_uniform(color);
power_link = GPU_uniform(&power);
perceptual_power_link = GPU_uniform(&perceptual_power);
}
else {
/* Use default values */
color_link = GPU_uniform(default_color);
power_link = GPU_uniform(&default_power);
perceptual_power_link = GPU_uniform(&default_perceptual_power);
}
/* Return shader call with just color and power - no distance */
/* Pass the captured uniforms to the GPU stack. */
return GPU_stack_link(mat, node, "node_light_info_simple", in, out,
GPU_constant(light_color), /* Light Color */
GPU_constant(&light_power)); /* Light Power */
color_link, /* Light Color */
power_link, /* Light Power */
perceptual_power_link); /* Perceptual Power */
}
} // namespace blender::nodes::node_shader_light_info_cc