Files
armorpaint/paint/sources/uniforms.c
T

459 lines
18 KiB
C
Raw Normal View History

2026-03-09 13:17:15 +01:00
#include "global.h"
2026-03-07 21:12:59 +01:00
i32 uniforms_ext_i32_link(object_t *object, material_data_t *mat, char *link) {
2026-03-06 12:56:38 +01:00
if (string_equals(link, "_bloom_current_mip")) {
return render_path_base_bloom_current_mip;
}
return INT_MAX;
}
2026-03-07 21:12:59 +01:00
f32 uniforms_ext_f32_link(object_t *object, material_data_t *mat, char *link) {
2026-03-06 12:56:38 +01:00
if (string_equals(link, "_brush_radius")) {
2026-03-10 21:00:00 +01:00
bool decal = context_is_decal();
bool decal_mask = decal && operator_shortcut(string("%s+%s", any_map_get(config_keymap, "decal_mask"), any_map_get(config_keymap, "action_paint")),
SHORTCUT_TYPE_DOWN);
2026-04-05 16:41:00 +02:00
f32 brush_decal_mask_radius = g_context->brush_decal_mask_radius;
2026-05-14 12:51:32 +02:00
bool paint2d = g_context->paint2d || g_context->paint2d_view;
2026-05-15 23:33:34 +02:00
brush_decal_mask_radius *= 2.0;
2026-04-05 16:41:00 +02:00
f32 radius = decal_mask ? brush_decal_mask_radius : g_context->brush_radius;
f32 val = (radius * g_context->brush_nodes_radius) / 15.0;
2026-05-17 11:45:17 +02:00
if (g_config->pressure_radius && pen_down("tip") && !decal && !slot_layer_is_path(g_context->layer)) {
2026-04-05 16:41:00 +02:00
val *= pen_pressure * g_config->pressure_sensitivity;
2026-03-06 12:56:38 +01:00
}
2026-04-05 16:41:00 +02:00
f32 scale2d = (900 / (float)base_h()) * g_config->window_scale;
2026-03-06 12:56:38 +01:00
if (!decal) {
2026-05-14 12:51:32 +02:00
val *= paint2d ? 0.5 * 0.5 * scale2d * ui_view2d_pan_scale : 2;
2026-03-06 12:56:38 +01:00
}
2026-05-15 23:33:34 +02:00
else if (decal_mask) {
val *= paint2d ? 0.5 * 0.5 * scale2d * ui_view2d_pan_scale : scale2d;
}
2026-03-06 12:56:38 +01:00
else {
2026-05-15 23:33:34 +02:00
val *= paint2d ? 0.5 * 0.5 * scale2d * ui_view2d_pan_scale : scale2d * 2.0;
2026-03-06 12:56:38 +01:00
}
return val;
}
else if (string_equals(link, "_vignette_strength")) {
2026-04-05 16:41:00 +02:00
return g_config->rp_vignette;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_grain_strength")) {
2026-04-05 16:41:00 +02:00
return g_config->rp_grain;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_tonemap_strength")) {
2026-04-05 16:41:00 +02:00
bool tonemap = g_context->viewport_mode == VIEWPORT_MODE_LIT || g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE;
2026-03-06 12:56:38 +01:00
return tonemap ? 1.0 : 0.0;
}
2026-05-19 19:56:14 +02:00
else if (string_equals(link, "_lut_size")) {
return lut_image != NULL ? (f32)lut_size : 0.0;
}
2026-03-06 12:56:38 +01:00
else if (string_equals(link, "_bloom_sample_scale")) {
return render_path_base_bloom_sample_scale;
}
else if (string_equals(link, "_bloom_strength")) {
2026-04-05 16:41:00 +02:00
return g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE ? 0.2 : 0.02;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_brush_scale_x")) {
2026-04-05 16:41:00 +02:00
return 1 / (float)g_context->brush_scale_x;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_brush_opacity")) {
2026-04-05 16:41:00 +02:00
f32 val = g_context->brush_opacity * g_context->brush_nodes_opacity;
2026-05-18 09:08:34 +02:00
if (g_config->pressure_opacity && pen_down("tip") && !slot_layer_is_path(g_context->layer)) {
2026-04-05 16:41:00 +02:00
val *= pen_pressure * g_config->pressure_sensitivity;
2026-03-06 12:56:38 +01:00
}
return val;
}
else if (string_equals(link, "_brush_hardness")) {
bool decal_mask = context_is_decal_mask_paint();
2026-04-05 16:41:00 +02:00
if (g_context->tool != TOOL_TYPE_BRUSH && g_context->tool != TOOL_TYPE_ERASER && g_context->tool != TOOL_TYPE_CLONE && !decal_mask) {
2026-03-06 12:56:38 +01:00
return 1.0;
}
2026-04-05 16:41:00 +02:00
f32 val = fmaxf((g_context->brush_hardness * g_context->brush_nodes_hardness) - 0.02, 0.0);
2026-05-18 09:08:34 +02:00
if (g_config->pressure_hardness && pen_down("tip") && !slot_layer_is_path(g_context->layer)) {
2026-04-05 16:41:00 +02:00
val *= pen_pressure * g_config->pressure_sensitivity;
2026-03-06 12:56:38 +01:00
}
2026-05-15 23:33:34 +02:00
val *= val;
2026-03-06 12:56:38 +01:00
return val;
}
else if (string_equals(link, "_brush_scale")) {
2026-05-04 20:30:49 +02:00
// if (g_context->tool == TOOL_TYPE_CURSOR) {
// i32 atlas_w = config_get_scene_atlas_res();
// i32 item_w = config_get_layer_res();
// i32 atlas_stride = atlas_w / (float)item_w;
// return atlas_stride;
// }
2026-05-13 17:11:52 +02:00
bool fill = g_context->layer->fill_material != NULL;
2026-04-05 16:41:00 +02:00
f32 val = (fill ? g_context->layer->scale : g_context->brush_scale) * g_context->brush_nodes_scale;
2026-03-06 12:56:38 +01:00
return val;
}
else if (string_equals(link, "_object_id")) {
return array_index_of(project_paint_objects, object->ext);
}
else if (string_equals(link, "_dilate_radius")) {
2026-04-05 16:41:00 +02:00
return util_uv_dilatemap != NULL ? g_config->dilate_radius : 0.0;
2026-03-06 12:56:38 +01:00
}
2026-05-11 19:48:30 +02:00
else if (string_equals(link, "_particle_radius")) {
i32 idx = g_context->particle_index;
f32 speed = (physics_world_active != NULL && g_context->particles[idx].body != NULL)
? physics_world_get_speed(physics_world_active, g_context->particles[idx].body)
: 0.0f;
f32 vel_scale = fminf(speed / 0.12f, 1.0f);
f32 contact_scale = 1.0f - fminf(g_context->particles[idx].contact_time, 1.0f);
return fmaxf(g_context->brush_radius * vel_scale * contact_scale, 0.1f);
}
2026-03-06 12:56:38 +01:00
else if (string_equals(link, "_decal_layer_dim")) {
2026-04-05 16:41:00 +02:00
vec4_t sc = mat4_get_scale(g_context->layer->decal_mat);
2026-03-06 12:56:38 +01:00
return sc.z * 0.5;
}
else if (string_equals(link, "_picker_opacity")) {
2026-04-05 16:41:00 +02:00
return g_context->picked_color->opacity;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_picker_occlusion")) {
2026-04-05 16:41:00 +02:00
return g_context->picked_color->occlusion;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_picker_roughness")) {
2026-04-05 16:41:00 +02:00
return g_context->picked_color->roughness;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_picker_metallic")) {
2026-04-05 16:41:00 +02:00
return g_context->picked_color->metallic;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_picker_height")) {
2026-04-05 16:41:00 +02:00
return g_context->picked_color->height;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_taa_blend")) {
2026-05-03 21:12:41 +02:00
return scene_camera->frame == 0 ? 0.0 : 0.5;
2026-03-06 12:56:38 +01:00
}
2026-03-07 21:12:59 +01:00
if (parser_material_script_links != NULL) {
2026-03-31 18:47:10 +02:00
string_array_t *keys = map_keys(parser_material_script_links);
2026-03-06 12:56:38 +01:00
for (i32 i = 0; i < keys->length; ++i) {
2026-03-07 21:12:59 +01:00
char *key = keys->buffer[i];
char *script = any_map_get(parser_material_script_links, key);
2026-03-10 21:00:00 +01:00
f32 result = NAN;
2026-03-27 11:52:34 +01:00
if (script != NULL) {
result = 0.0;
}
2026-03-06 12:56:38 +01:00
if (!string_equals(script, "")) {
2026-03-23 23:20:02 +01:00
minic_ctx_t *_ctx = minic_eval(string("float main() { return %s; }", script));
2026-03-27 09:01:55 +01:00
result = minic_ctx_result(_ctx);
minic_ctx_free(_ctx);
2026-03-06 12:56:38 +01:00
}
return result;
}
}
2026-03-08 08:39:29 +01:00
return NAN;
2026-03-06 12:56:38 +01:00
}
2026-03-07 21:12:59 +01:00
vec2_t uniforms_ext_vec2_link(object_t *object, material_data_t *mat, char *link) {
2026-03-06 12:56:38 +01:00
if (string_equals(link, "_gbuffer_size")) {
render_target_t *gbuffer2 = any_map_get(render_path_render_targets, "gbuffer2");
2026-04-05 23:00:47 +02:00
return (vec2_t){gbuffer2->_image->width, gbuffer2->_image->height};
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_clone_delta")) {
2026-04-05 23:00:47 +02:00
return (vec2_t){g_context->clone_delta_x, g_context->clone_delta_y};
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_texpaint_size")) {
2026-04-05 23:00:47 +02:00
return (vec2_t){config_get_texture_res_x(), config_get_texture_res_y()};
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_brush_angle")) {
2026-04-05 16:41:00 +02:00
f32 brush_angle = g_context->brush_angle + g_context->brush_nodes_angle;
2026-05-13 17:11:52 +02:00
f32 angle = g_context->layer->fill_material != NULL ? g_context->layer->angle : brush_angle;
2026-03-15 21:14:44 +01:00
angle *= (math_pi() / 180.0);
2026-05-18 09:08:34 +02:00
if (g_config->pressure_angle && pen_down("tip") && !slot_layer_is_path(g_context->layer)) {
2026-04-05 16:41:00 +02:00
angle *= pen_pressure * g_config->pressure_sensitivity;
2026-03-06 12:56:38 +01:00
}
2026-04-05 23:00:47 +02:00
return (vec2_t){math_cos(-angle), math_sin(-angle)};
2026-03-06 12:56:38 +01:00
}
return vec2_nan();
}
2026-04-04 21:38:20 +02:00
f32 uniforms_ext_vec2d(f32 x) {
// Transform from 3d viewport coord to 2d view coord
2026-04-05 16:41:00 +02:00
g_context->paint2d_view = false;
2026-04-21 10:52:27 +02:00
f32 res = (x * base_w() - base_w()) / (float)ui_view2d_ww;
2026-04-05 16:41:00 +02:00
g_context->paint2d_view = true;
2026-04-04 21:38:20 +02:00
return res;
}
2026-03-07 21:12:59 +01:00
vec4_t uniforms_ext_vec3_link(object_t *object, material_data_t *mat, char *link) {
2026-03-06 12:56:38 +01:00
vec4_t v = vec4_nan();
if (string_equals(link, "_brush_direction")) {
// Discard first paint for directional brush
2026-04-05 16:41:00 +02:00
bool allow_paint = g_context->prev_paint_vec_x != g_context->last_paint_vec_x && g_context->prev_paint_vec_y != g_context->last_paint_vec_y &&
g_context->prev_paint_vec_x > 0 && g_context->prev_paint_vec_y > 0;
f32 x = g_context->paint_vec.x;
f32 y = g_context->paint_vec.y;
f32 lastx = g_context->prev_paint_vec_x;
f32 lasty = g_context->prev_paint_vec_y;
if (g_context->paint2d) {
2026-03-09 23:02:08 +01:00
x = uniforms_ext_vec2d(x);
lastx = uniforms_ext_vec2d(lastx);
2026-03-06 12:56:38 +01:00
}
2026-04-21 10:52:27 +02:00
f32 angle = math_atan2(-y + lasty, x - lastx) - math_pi() / 2.0;
v = (vec4_t){math_cos(angle), math_sin(angle), allow_paint ? 1 : 0, 1.0};
2026-04-05 16:41:00 +02:00
g_context->prev_paint_vec_x = g_context->last_paint_vec_x;
g_context->prev_paint_vec_y = g_context->last_paint_vec_y;
2026-03-06 12:56:38 +01:00
return v;
}
else if (string_equals(link, "_decal_layer_loc")) {
2026-04-05 23:00:47 +02:00
v = (vec4_t){g_context->layer->decal_mat.m30, g_context->layer->decal_mat.m31, g_context->layer->decal_mat.m32, 1.0};
2026-03-06 12:56:38 +01:00
return v;
}
else if (string_equals(link, "_decal_layer_nor")) {
2026-04-05 23:00:47 +02:00
v = (vec4_t){g_context->layer->decal_mat.m20, g_context->layer->decal_mat.m21, g_context->layer->decal_mat.m22, 1.0};
2026-03-06 12:56:38 +01:00
v = vec4_norm(v);
return v;
}
else if (string_equals(link, "_picker_base")) {
2026-04-05 23:00:47 +02:00
v = (vec4_t){color_get_rb(g_context->picked_color->base) / 255.0, color_get_gb(g_context->picked_color->base) / 255.0,
2026-04-21 10:52:27 +02:00
color_get_bb(g_context->picked_color->base) / 255.0, 1.0};
2026-03-06 12:56:38 +01:00
return v;
}
else if (string_equals(link, "_picker_normal")) {
2026-04-05 23:00:47 +02:00
v = (vec4_t){color_get_rb(g_context->picked_color->normal) / 255.0, color_get_gb(g_context->picked_color->normal) / 255.0,
2026-04-21 10:52:27 +02:00
color_get_bb(g_context->picked_color->normal) / 255.0, 1.0};
2026-03-06 12:56:38 +01:00
return v;
}
else if (string_equals(link, "_particle_hit")) {
2026-04-05 23:00:47 +02:00
v = (vec4_t){g_context->particle_hit_x, g_context->particle_hit_y, g_context->particle_hit_z, 1.0};
2026-03-06 12:56:38 +01:00
return v;
}
else if (string_equals(link, "_particle_hit_last")) {
2026-04-05 23:00:47 +02:00
v = (vec4_t){g_context->last_particle_hit_x, g_context->last_particle_hit_y, g_context->last_particle_hit_z, 1.0};
2026-03-06 12:56:38 +01:00
return v;
}
2026-05-15 23:33:34 +02:00
else if (string_equals(link, "_camera_right")) {
v = camera_object_right_world(scene_camera);
return v;
}
2026-03-06 12:56:38 +01:00
return v;
}
2026-03-07 21:12:59 +01:00
vec4_t uniforms_ext_vec4_link(object_t *object, material_data_t *mat, char *link) {
2026-03-06 12:56:38 +01:00
if (string_equals(link, "_input_brush")) {
bool down = mouse_down("left") || pen_down("tip");
2026-04-05 23:00:47 +02:00
vec4_t v = (vec4_t){g_context->paint_vec.x, g_context->paint_vec.y, down ? 1.0 : 0.0, g_context->paint2d ? 1.0 : 0.0};
2026-04-05 16:41:00 +02:00
if (g_context->paint2d) {
2026-03-09 23:02:08 +01:00
v.x = uniforms_ext_vec2d(v.x);
2026-03-06 12:56:38 +01:00
}
return v;
}
else if (string_equals(link, "_input_brush_last")) {
bool down = mouse_down("left") || pen_down("tip");
2026-04-05 23:00:47 +02:00
vec4_t v = (vec4_t){g_context->last_paint_vec_x, g_context->last_paint_vec_y, down ? 1.0 : 0.0, g_context->paint2d ? 1.0 : 0.0};
2026-04-05 16:41:00 +02:00
if (g_context->paint2d) {
2026-03-09 23:02:08 +01:00
v.x = uniforms_ext_vec2d(v.x);
2026-03-06 12:56:38 +01:00
}
return v;
}
else if (string_equals(link, "_envmap_data")) {
2026-04-05 23:00:47 +02:00
return (vec4_t){g_context->envmap_angle, math_sin(-g_context->envmap_angle), math_cos(-g_context->envmap_angle), scene_world->strength * 2.0};
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_envmap_data_world")) {
2026-04-05 16:41:00 +02:00
bool tonemap = g_context->viewport_mode == VIEWPORT_MODE_LIT || g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE;
2026-04-05 23:00:47 +02:00
return (vec4_t){g_context->envmap_angle, tonemap ? 0.0 : 1.0, 0.0, g_context->show_envmap ? scene_world->strength : 1.0};
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_stencil_transform")) {
2026-04-05 23:00:47 +02:00
vec4_t v = (vec4_t){g_context->brush_stencil_x, g_context->brush_stencil_y, g_context->brush_stencil_scale, g_context->brush_stencil_angle};
2026-04-05 16:41:00 +02:00
if (g_context->paint2d) {
2026-03-09 23:02:08 +01:00
v.x = uniforms_ext_vec2d(v.x);
2026-03-06 12:56:38 +01:00
}
return v;
}
else if (string_equals(link, "_decal_mask")) {
bool decal_mask = context_is_decal_mask_paint();
2026-04-05 16:41:00 +02:00
f32 val = (g_context->brush_radius * g_context->brush_nodes_radius) / 15.0;
f32 scale2d = (900 / (float)base_h()) * g_config->window_scale;
2026-05-15 23:33:34 +02:00
val *= g_context->paint2d ? 0.5 * 0.5 * scale2d * ui_view2d_pan_scale : scale2d * 2.0;
2026-04-05 23:00:47 +02:00
vec4_t v = (vec4_t){g_context->decal_x, g_context->decal_y, decal_mask ? 1 : 0, val};
2026-04-05 16:41:00 +02:00
if (g_context->paint2d) {
2026-03-09 23:02:08 +01:00
v.x = uniforms_ext_vec2d(v.x);
2026-03-06 12:56:38 +01:00
}
return v;
}
return vec4_nan();
}
2026-03-07 21:12:59 +01:00
mat4_t uniforms_ext_mat4_link(object_t *object, material_data_t *mat, char *link) {
2026-03-06 12:56:38 +01:00
if (string_equals(link, "_decal_layer_matrix")) { // Decal layer
2026-04-05 16:41:00 +02:00
mat4_t m = mat4_inv(g_context->layer->decal_mat);
2026-03-06 12:56:38 +01:00
f32 f = object->parent->transform->scale.x * object->transform->scale_world;
2026-04-05 23:00:47 +02:00
m = mat4_scale(m, (vec4_t){f, f, f, 1.0});
2026-03-06 12:56:38 +01:00
m = mat4_mult_mat(m, uniforms_ext_ortho_p);
return m;
}
return mat4_nan();
}
2026-03-10 21:00:00 +01:00
void uniforms_ext_cache_uv_island_map(void *_) {
2026-03-09 23:02:08 +01:00
util_uv_cache_uv_island_map();
}
2026-03-10 21:00:00 +01:00
void uniforms_ext_cache_triangle_map(void *_) {
2026-03-09 23:02:08 +01:00
util_uv_cache_triangle_map();
}
2026-03-10 21:00:00 +01:00
void uniforms_ext_cache_uv_map(void *_) {
2026-03-09 23:02:08 +01:00
util_uv_cache_uv_map();
}
2026-03-07 21:12:59 +01:00
gpu_texture_t *uniforms_ext_tex_link(object_t *object, material_data_t *mat, char *link) {
2026-03-06 12:56:38 +01:00
if (string_equals(link, "_texpaint_undo")) {
2026-04-05 16:41:00 +02:00
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
2026-03-10 21:00:00 +01:00
render_target_t *rt = any_map_get(render_path_render_targets, string("texpaint_undo%d", i));
2026-03-06 12:56:38 +01:00
return rt->_image;
}
else if (string_equals(link, "_texpaint_nor_undo")) {
2026-04-05 16:41:00 +02:00
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
2026-03-10 21:00:00 +01:00
render_target_t *rt = any_map_get(render_path_render_targets, string("texpaint_nor_undo%d", i));
2026-03-06 12:56:38 +01:00
return rt->_image;
}
else if (string_equals(link, "_texpaint_pack_undo")) {
2026-04-05 16:41:00 +02:00
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
2026-03-10 21:00:00 +01:00
render_target_t *rt = any_map_get(render_path_render_targets, string("texpaint_pack_undo%d", i));
2026-03-06 12:56:38 +01:00
return rt->_image;
}
else if (string_equals(link, "_texpaint_sculpt_undo")) {
2026-04-05 16:41:00 +02:00
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
2026-03-10 21:00:00 +01:00
render_target_t *rt = any_map_get(render_path_render_targets, string("texpaint_sculpt_undo%d", i));
2026-03-06 12:56:38 +01:00
return rt->_image;
}
else if (string_equals(link, "_texcolorid")) {
if (project_assets->length == 0) {
render_target_t *rt = any_map_get(render_path_render_targets, "empty_white");
return rt->_image;
}
else {
2026-04-05 16:41:00 +02:00
return project_get_image(project_assets->buffer[g_context->colorid_handle->i]);
2026-03-06 12:56:38 +01:00
}
}
else if (string_equals(link, "_textexttool")) { // Opacity map for text
2026-04-05 16:41:00 +02:00
return g_context->text_tool_image;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_texbrushmask")) {
2026-04-05 16:41:00 +02:00
return g_context->brush_mask_image;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_texbrushstencil")) {
2026-04-05 16:41:00 +02:00
return g_context->brush_stencil_image;
2026-03-06 12:56:38 +01:00
}
else if (string_equals(link, "_texuvmap")) {
if (!util_uv_uvmap_cached) {
2026-03-09 23:02:08 +01:00
sys_notify_on_next_frame(&uniforms_ext_cache_uv_map, NULL);
2026-03-06 12:56:38 +01:00
}
return util_uv_uvmap;
}
else if (string_equals(link, "_textrianglemap")) {
if (!util_uv_trianglemap_cached) {
2026-03-09 23:02:08 +01:00
sys_notify_on_next_frame(&uniforms_ext_cache_triangle_map, NULL);
2026-03-06 12:56:38 +01:00
}
return util_uv_trianglemap;
}
else if (string_equals(link, "_texuvislandmap")) {
2026-03-09 23:02:08 +01:00
sys_notify_on_next_frame(&uniforms_ext_cache_uv_island_map, NULL);
2026-03-06 12:56:38 +01:00
if (util_uv_uvislandmap_cached) {
return util_uv_uvislandmap;
}
else {
render_target_t *rt = any_map_get(render_path_render_targets, "empty_black");
return rt->_image;
}
}
else if (string_equals(link, "_texdilatemap")) {
return util_uv_dilatemap;
}
if (starts_with(link, "_texpaint_pack_vert")) {
2026-03-10 21:00:00 +01:00
char *tid = substring(link, string_length(link) - 1, string_length(link));
render_target_t *rt = any_map_get(render_path_render_targets, string("texpaint_pack%s", tid));
2026-03-06 12:56:38 +01:00
return rt->_image;
}
if (starts_with(link, "_texpaint_vert")) {
i32 tid = parse_int(substring(link, string_length(link) - 1, string_length(link)));
2026-03-07 21:12:59 +01:00
return tid < project_layers->length ? project_layers->buffer[tid]->texpaint : NULL;
2026-03-06 12:56:38 +01:00
}
if (starts_with(link, "_texpaint_nor")) {
i32 tid = parse_int(substring(link, string_length(link) - 1, string_length(link)));
2026-03-07 21:12:59 +01:00
return tid < project_layers->length ? project_layers->buffer[tid]->texpaint_nor : NULL;
2026-03-06 12:56:38 +01:00
}
if (starts_with(link, "_texpaint_pack")) {
i32 tid = parse_int(substring(link, string_length(link) - 1, string_length(link)));
2026-03-07 21:12:59 +01:00
return tid < project_layers->length ? project_layers->buffer[tid]->texpaint_pack : NULL;
2026-03-06 12:56:38 +01:00
}
if (starts_with(link, "_texpaint_sculpt")) {
i32 tid = parse_int(substring(link, string_length(link) - 1, string_length(link)));
2026-03-07 21:12:59 +01:00
return tid < project_layers->length ? project_layers->buffer[tid]->texpaint_sculpt : NULL;
2026-03-06 12:56:38 +01:00
}
if (starts_with(link, "_texpaint")) {
i32 tid = parse_int(substring(link, string_length(link) - 1, string_length(link)));
2026-03-07 21:12:59 +01:00
return tid < project_layers->length ? project_layers->buffer[tid]->texpaint : NULL;
2026-03-06 12:56:38 +01:00
}
if (starts_with(link, "_texblur_")) {
2026-03-07 21:12:59 +01:00
char *id = substring(link, 9, string_length(link));
2026-04-05 16:41:00 +02:00
if (g_context->node_previews != NULL) {
return any_map_get(g_context->node_previews, id);
2026-03-06 12:56:38 +01:00
}
else {
render_target_t *rt = any_map_get(render_path_render_targets, "empty_black");
return rt->_image;
}
}
if (starts_with(link, "_texwarp_")) {
2026-03-07 21:12:59 +01:00
char *id = substring(link, 9, string_length(link));
2026-04-05 16:41:00 +02:00
if (g_context->node_previews != NULL) {
return any_map_get(g_context->node_previews, id);
2026-03-06 12:56:38 +01:00
}
else {
render_target_t *rt = any_map_get(render_path_render_targets, "empty_black");
return rt->_image;
}
}
if (starts_with(link, "_texbake_")) {
2026-03-07 21:12:59 +01:00
char *id = substring(link, 9, string_length(link));
2026-04-05 16:41:00 +02:00
if (g_context->node_previews != NULL) {
return any_map_get(g_context->node_previews, id);
2026-03-06 12:56:38 +01:00
}
else {
render_target_t *rt = any_map_get(render_path_render_targets, "empty_black");
return rt->_image;
}
}
if (string_equals(link, "_camera_texture")) {
render_target_t *rt = any_map_get(render_path_render_targets, "last");
return rt->_image;
}
2026-05-19 19:56:14 +02:00
if (string_equals(link, "_lut_tex")) {
if (lut_image == NULL) {
render_target_t *rt = any_map_get(render_path_render_targets, "empty_white");
return rt->_image;
}
return lut_image;
}
2026-03-07 21:12:59 +01:00
return NULL;
2026-03-06 12:56:38 +01:00
}
2026-04-04 21:38:20 +02:00
void uniforms_ext_init() {
gc_unroot(uniforms_i32_links);
uniforms_i32_links = uniforms_ext_i32_link;
gc_root(uniforms_i32_links);
gc_unroot(uniforms_f32_links);
uniforms_f32_links = uniforms_ext_f32_link;
gc_root(uniforms_f32_links);
gc_unroot(uniforms_vec2_links);
uniforms_vec2_links = uniforms_ext_vec2_link;
gc_root(uniforms_vec2_links);
gc_unroot(uniforms_vec3_links);
uniforms_vec3_links = uniforms_ext_vec3_link;
gc_root(uniforms_vec3_links);
gc_unroot(uniforms_vec4_links);
uniforms_vec4_links = uniforms_ext_vec4_link;
gc_root(uniforms_vec4_links);
gc_unroot(uniforms_mat4_links);
uniforms_mat4_links = uniforms_ext_mat4_link;
gc_root(uniforms_mat4_links);
gc_unroot(uniforms_tex_links);
uniforms_tex_links = uniforms_ext_tex_link;
gc_root(uniforms_tex_links);
}