Files
armorpaint/paint/sources/render_path_raytrace_bake.c
T

178 lines
7.2 KiB
C
Raw Normal View History

2026-03-09 13:17:15 +01:00
#include "global.h"
2026-04-05 16:09:00 +02:00
f32 render_path_raytrace_bake_rays_timer = 0.0;
i32 render_path_raytrace_bake_rays_counter = 0;
gpu_texture_t *render_path_raytrace_bake_last_layer = NULL;
i32 render_path_raytrace_bake_last_bake_type = 0;
i32 render_path_raytrace_bake_last_bake_type2 = 0;
2026-03-09 23:02:08 +01:00
void render_path_raytrace_bake_commands_parse_paint_material(void (*parse_paint_material)(bool)) {
parse_paint_material(true);
}
2026-04-04 21:38:20 +02:00
char *render_path_raytrace_bake_get_bake_shader_name() {
2026-04-05 16:41:00 +02:00
return g_context->bake_type == BAKE_TYPE_AO ? string("raytrace_bake_ao%s", render_path_raytrace_ext)
: g_context->bake_type == BAKE_TYPE_LIGHTMAP ? string("raytrace_bake_light%s", render_path_raytrace_ext)
: g_context->bake_type == BAKE_TYPE_BENT_NORMAL ? string("raytrace_bake_bent%s", render_path_raytrace_ext)
2026-04-04 21:38:20 +02:00
: string("raytrace_bake_thick%s", render_path_raytrace_ext);
}
2026-03-06 12:56:38 +01:00
bool render_path_raytrace_bake_commands(void (*parse_paint_material)(bool)) {
2026-04-05 16:41:00 +02:00
if (!render_path_raytrace_ready || !render_path_raytrace_is_bake || render_path_raytrace_bake_last_bake_type != g_context->bake_type) {
2026-03-06 12:56:38 +01:00
2026-04-05 16:41:00 +02:00
bool rebuild = !(render_path_raytrace_ready && render_path_raytrace_is_bake && render_path_raytrace_bake_last_bake_type != g_context->bake_type);
render_path_raytrace_bake_last_bake_type = g_context->bake_type;
2026-03-06 12:56:38 +01:00
render_path_raytrace_ready = true;
render_path_raytrace_is_bake = true;
gc_unroot(render_path_raytrace_last_envmap);
2026-03-07 21:12:59 +01:00
render_path_raytrace_last_envmap = NULL;
2026-03-06 12:56:38 +01:00
gc_unroot(render_path_raytrace_bake_last_layer);
2026-03-07 21:12:59 +01:00
render_path_raytrace_bake_last_layer = NULL;
2026-03-06 12:56:38 +01:00
2026-03-07 21:12:59 +01:00
if (any_map_get(render_path_render_targets, "baketex0") != NULL) {
2026-03-06 12:56:38 +01:00
render_target_t *baketex0 = any_map_get(render_path_render_targets, "baketex0");
render_target_t *baketex1 = any_map_get(render_path_render_targets, "baketex1");
render_target_t *baketex2 = any_map_get(render_path_render_targets, "baketex2");
gpu_delete_texture(baketex0->_image);
gpu_delete_texture(baketex1->_image);
gpu_delete_texture(baketex2->_image);
}
{
render_target_t *t = render_target_create();
t->name = "baketex0";
t->width = config_get_texture_res_x();
t->height = config_get_texture_res_y();
t->format = "RGBA64";
render_path_create_render_target(t);
}
{
render_target_t *t = render_target_create();
t->name = "baketex1";
t->width = config_get_texture_res_x();
t->height = config_get_texture_res_y();
t->format = "RGBA64";
render_path_create_render_target(t);
}
{
render_target_t *t = render_target_create();
t->name = "baketex2";
t->width = config_get_texture_res_x();
t->height = config_get_texture_res_y();
t->format = "RGBA64"; // Match raytrace_target format
render_path_create_render_target(t);
}
2026-04-05 16:41:00 +02:00
bake_type_t _bake_type = g_context->bake_type;
g_context->bake_type = BAKE_TYPE_INIT;
2026-03-06 12:56:38 +01:00
parse_paint_material(true);
2026-03-07 21:12:59 +01:00
render_path_set_target("baketex0", NULL, NULL, GPU_CLEAR_COLOR, 0x00000000, 0.0);
2026-03-06 12:56:38 +01:00
// Pixels with alpha of 0.0 are skipped during raytracing
2026-03-31 18:47:10 +02:00
string_array_t *additional = any_array_create_from_raw(
2026-03-08 08:39:29 +01:00
(void *[]){
2026-03-06 12:56:38 +01:00
"baketex1",
},
1);
2026-03-07 21:12:59 +01:00
render_path_set_target("baketex0", additional, NULL, GPU_CLEAR_NONE, 0, 0.0);
2026-03-06 12:56:38 +01:00
render_path_draw_meshes("paint");
2026-04-05 16:41:00 +02:00
g_context->bake_type = _bake_type;
2026-03-09 23:02:08 +01:00
sys_notify_on_next_frame(&render_path_raytrace_bake_commands_parse_paint_material, parse_paint_material);
2026-03-06 12:56:38 +01:00
render_path_raytrace_init_shader = true;
render_path_raytrace_raytrace_init(render_path_raytrace_bake_get_bake_shader_name(), rebuild);
return false;
}
2026-04-05 16:41:00 +02:00
if (!g_context->envmap_loaded) {
2026-03-06 12:56:38 +01:00
context_load_envmap();
context_update_envmap();
}
world_data_t *probe = scene_world;
2026-04-05 16:41:00 +02:00
gpu_texture_t *saved_envmap = g_context->show_envmap_blur ? probe->_->radiance_mipmaps->buffer[0] : g_context->saved_envmap;
2026-03-06 12:56:38 +01:00
2026-04-05 16:41:00 +02:00
if (render_path_raytrace_last_envmap != saved_envmap || render_path_raytrace_bake_last_layer != g_context->layer->texpaint ||
render_path_raytrace_bake_last_bake_type2 != g_context->bake_type) {
2026-03-06 12:56:38 +01:00
gc_unroot(render_path_raytrace_last_envmap);
render_path_raytrace_last_envmap = saved_envmap;
gc_root(render_path_raytrace_last_envmap);
gc_unroot(render_path_raytrace_bake_last_layer);
2026-04-05 16:41:00 +02:00
render_path_raytrace_bake_last_layer = g_context->layer->texpaint;
2026-03-06 12:56:38 +01:00
gc_root(render_path_raytrace_bake_last_layer);
2026-04-05 16:41:00 +02:00
render_path_raytrace_bake_last_bake_type2 = g_context->bake_type;
2026-03-06 12:56:38 +01:00
2026-03-10 21:00:00 +01:00
gpu_texture_t *bnoise_sobol = any_map_get(scene_embedded, "bnoise_sobol.k");
gpu_texture_t *bnoise_scramble = any_map_get(scene_embedded, "bnoise_scramble.k");
gpu_texture_t *bnoise_rank = any_map_get(scene_embedded, "bnoise_rank.k");
2026-03-06 12:56:38 +01:00
2026-03-10 21:00:00 +01:00
render_target_t *baketex0 = any_map_get(render_path_render_targets, "baketex0");
render_target_t *baketex1 = any_map_get(render_path_render_targets, "baketex1");
2026-03-06 12:56:38 +01:00
2026-03-10 21:00:00 +01:00
gpu_texture_t *tex2 = NULL;
2026-04-05 16:41:00 +02:00
if (g_context->bake_type == BAKE_TYPE_LIGHTMAP) {
2026-03-07 21:12:59 +01:00
slot_layer_t *flat = layers_flatten(true, NULL);
2026-03-06 12:56:38 +01:00
tex2 = flat->texpaint;
}
else {
2026-03-10 21:00:00 +01:00
render_target_t *texpaint_undo = any_map_get(render_path_render_targets, string("texpaint_undo%d", history_undo_i));
2026-03-06 12:56:38 +01:00
tex2 = texpaint_undo->_image;
}
gpu_raytrace_set_textures(baketex0->_image, baketex1->_image, tex2, saved_envmap, bnoise_sobol, bnoise_scramble, bnoise_rank);
}
2026-04-05 16:41:00 +02:00
if (g_context->brush_time > 0) {
g_context->pdirty = 2;
g_context->rdirty = 2;
2026-03-06 12:56:38 +01:00
}
2026-04-05 16:41:00 +02:00
if (g_context->pdirty > 0) {
2026-03-10 21:00:00 +01:00
f32_array_t *f32a = render_path_raytrace_f32a;
f32a->buffer[0] = render_path_raytrace_frame++;
2026-04-05 16:41:00 +02:00
f32a->buffer[1] = g_context->bake_ao_strength;
f32a->buffer[2] = g_context->bake_ao_radius;
f32a->buffer[3] = g_context->bake_ao_offset;
2026-03-10 21:00:00 +01:00
f32a->buffer[4] = scene_world->strength;
2026-04-05 16:41:00 +02:00
f32a->buffer[5] = g_context->bake_up_axis;
f32a->buffer[6] = g_context->envmap_angle;
2026-03-06 12:56:38 +01:00
render_target_t *framebuffer = any_map_get(render_path_render_targets, "baketex2");
_gpu_raytrace_dispatch_rays(framebuffer->_image, f32a);
2026-04-05 16:41:00 +02:00
i32 id = g_context->layer->id;
2026-03-10 21:00:00 +01:00
char *texpaint_id = string("texpaint%d", id);
2026-03-07 21:12:59 +01:00
render_path_set_target(texpaint_id, NULL, NULL, GPU_CLEAR_NONE, 0, 0.0);
2026-03-06 12:56:38 +01:00
render_path_bind_target("baketex2", "tex");
render_path_draw_shader("Scene/copy_pass/copy_pass");
2026-03-10 21:00:00 +01:00
#ifdef IRON_METAL
i32 samples_per_frame = 4;
#else
i32 samples_per_frame = 64;
#endif
2026-03-06 12:56:38 +01:00
render_path_raytrace_bake_rays_pix = render_path_raytrace_frame * samples_per_frame;
render_path_raytrace_bake_rays_counter += samples_per_frame;
render_path_raytrace_bake_rays_timer += sys_real_delta();
if (render_path_raytrace_bake_rays_timer >= 1) {
render_path_raytrace_bake_rays_sec = render_path_raytrace_bake_rays_counter;
render_path_raytrace_bake_rays_timer = 0;
render_path_raytrace_bake_rays_counter = 0;
}
render_path_raytrace_bake_current_sample++;
iron_delay_idle_sleep();
return true;
}
else {
render_path_raytrace_frame = 0;
render_path_raytrace_bake_rays_timer = 0;
render_path_raytrace_bake_rays_counter = 0;
render_path_raytrace_bake_current_sample = 0;
return false;
}
}