paint: merge multi raytrace
This commit is contained in:
+13
-7
@@ -126,7 +126,6 @@ void config_save() {
|
||||
json_encode_f32("brush_alpha_discard", g_config->brush_alpha_discard);
|
||||
json_encode_i32("dilate_radius", g_config->dilate_radius);
|
||||
json_encode_string("blender", g_config->blender);
|
||||
json_encode_i32("scene_atlas_res", g_config->scene_atlas_res);
|
||||
json_encode_bool("grid_snap", g_config->grid_snap);
|
||||
json_encode_bool("experimental", g_config->experimental);
|
||||
json_encode_i32("neural_res", g_config->neural_res);
|
||||
@@ -255,7 +254,6 @@ void config_init() {
|
||||
g_config->show_asset_names = false;
|
||||
g_config->dilate_radius = 2;
|
||||
g_config->blender = "";
|
||||
g_config->scene_atlas_res = TEXTURE_RES_RES8192;
|
||||
g_config->pathtrace_mode = PATHTRACE_MODE_FAST;
|
||||
g_config->grid_snap = false;
|
||||
g_config->view2d_grid_show = false;
|
||||
@@ -436,11 +434,6 @@ i32 config_get_layer_res() {
|
||||
return config_texture_res_size(res);
|
||||
}
|
||||
|
||||
i32 config_get_scene_atlas_res() {
|
||||
i32 res = g_config->scene_atlas_res;
|
||||
return config_texture_res_size(res);
|
||||
}
|
||||
|
||||
void config_set_texture_res(i32 pos) {
|
||||
if (pos != TEXTURE_RES_CUSTOM) {
|
||||
f32 res = (f32)config_texture_res_size(pos);
|
||||
@@ -517,3 +510,16 @@ bool config_is_iphone() {
|
||||
return sys_display_ppi() > 330;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool config_is_raytrace_fast() {
|
||||
return g_config->pathtrace_mode == PATHTRACE_MODE_FAST || g_config->pathtrace_mode == PATHTRACE_MODE_MULTI_FAST;
|
||||
}
|
||||
|
||||
bool config_is_raytrace_multi() {
|
||||
bool multi = g_config->pathtrace_mode == PATHTRACE_MODE_MULTI_FAST || g_config->pathtrace_mode == PATHTRACE_MODE_MULTI_QUALITY;
|
||||
return multi && g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE;
|
||||
}
|
||||
|
||||
void config_apply_raytrace_multi() {
|
||||
gpu_raytrace_multi = config_is_raytrace_multi();
|
||||
}
|
||||
|
||||
@@ -325,10 +325,6 @@ void context_select_paint_object(mesh_object_t *o) {
|
||||
p->skip_context = "paint";
|
||||
}
|
||||
|
||||
// #ifdef is_forge
|
||||
// g_context->paint_object->skip_context = "";
|
||||
// #endif
|
||||
|
||||
g_context->paint_object = o;
|
||||
|
||||
i32 mask = slot_layer_get_object_mask(g_context->layer);
|
||||
@@ -467,6 +463,10 @@ void context_set_viewport_mode(viewport_mode_t mode) {
|
||||
}
|
||||
make_material_parse_mesh_material();
|
||||
|
||||
if (g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE) {
|
||||
util_mesh_merge(NULL);
|
||||
}
|
||||
|
||||
// Rotate mode is not supported for path tracing yet
|
||||
if (g_context->viewport_mode == VIEWPORT_MODE_PATH_TRACE && g_context->camera_controls == CAMERA_CONTROLS_ROTATE) {
|
||||
g_context->camera_controls = CAMERA_CONTROLS_ORBIT;
|
||||
|
||||
@@ -108,8 +108,10 @@ typedef enum {
|
||||
} export_destination_t;
|
||||
|
||||
typedef enum {
|
||||
PATHTRACE_MODE_FAST = 0,
|
||||
PATHTRACE_MODE_QUALITY = 1,
|
||||
PATHTRACE_MODE_FAST = 0,
|
||||
PATHTRACE_MODE_QUALITY = 1,
|
||||
PATHTRACE_MODE_MULTI_FAST = 2,
|
||||
PATHTRACE_MODE_MULTI_QUALITY = 3,
|
||||
} pathtrace_mode_t;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -81,6 +81,7 @@ void layers_merge_down();
|
||||
slot_layer_t *layers_merge_group(slot_layer_t *l);
|
||||
void layers_merge_layer(slot_layer_t *l0, slot_layer_t *l1, bool use_mask);
|
||||
slot_layer_t *layers_flatten(bool height_to_normal, slot_layer_t_array_t *layers);
|
||||
void layers_draw_mesh_materials();
|
||||
void layers_on_resized();
|
||||
void layers_create_filter();
|
||||
void layers_create_image_layer(asset_t *asset);
|
||||
@@ -110,7 +111,6 @@ void config_apply();
|
||||
i32 config_get_super_sample_quality(f32 f);
|
||||
f32 config_get_super_sample_size(i32 i);
|
||||
i32 config_get_layer_res();
|
||||
i32 config_get_scene_atlas_res();
|
||||
void config_set_texture_res(i32 pos);
|
||||
i32 config_get_texture_res_x();
|
||||
i32 config_get_texture_res_y();
|
||||
@@ -119,6 +119,9 @@ void config_load_theme(char *theme, bool tag_redraw);
|
||||
void config_enable_plugin(char *f);
|
||||
void config_disable_plugin(char *f);
|
||||
bool config_is_iphone();
|
||||
bool config_is_raytrace_fast();
|
||||
bool config_is_raytrace_multi();
|
||||
void config_apply_raytrace_multi();
|
||||
void box_export_show_textures();
|
||||
void box_export_show_bake_material();
|
||||
void box_export_show_mesh();
|
||||
@@ -228,7 +231,7 @@ void util_layer_repaint_path(slot_layer_t *l);
|
||||
void util_layer_remove_path_point(slot_layer_t *l);
|
||||
void util_layer_clear_path_points(slot_layer_t *l);
|
||||
f32 util_layer_brush_screen_radius();
|
||||
void make_texcoord_run(node_shader_t *kong);
|
||||
void make_texcoord_run(node_shader_t *kong, bool is_atlas);
|
||||
void context_init();
|
||||
void context_select_material(i32 i);
|
||||
void context_set_material(slot_material_t *m);
|
||||
@@ -343,6 +346,7 @@ void render_path_preview_init();
|
||||
void render_path_preview_commands_preview();
|
||||
void render_path_preview_commands_decal();
|
||||
node_shader_context_t *make_paint_run(material_t *data, material_context_t *matcon);
|
||||
node_shader_context_t *make_paint_run_context(material_t *data, material_context_t *matcon, char *context_id);
|
||||
node_shader_context_t *make_mesh_preview_run(material_t *data, material_context_t *matcon, bool viewport);
|
||||
material_data_t *make_mesh_preview_viewport(slot_material_t *slot);
|
||||
void import_sound_run(char *path);
|
||||
@@ -607,7 +611,8 @@ void util_mesh_decimate(f32 strength);
|
||||
void util_mesh_smooth();
|
||||
void util_mesh_bevel(f32 amount);
|
||||
void util_mesh_subdivide();
|
||||
void util_mesh_pack_uvs(i16_array_t *texa);
|
||||
i32 util_mesh_atlas_stride();
|
||||
i32 util_mesh_atlas_slot(object_t *object);
|
||||
void ui_header_init();
|
||||
void ui_header_render_ui();
|
||||
void ui_header_draw_tool_properties();
|
||||
|
||||
@@ -235,7 +235,7 @@ void import_mesh_add_mesh(raw_mesh_t *mesh) {
|
||||
}
|
||||
|
||||
mesh_data_t *raw = import_mesh_raw_mesh(mesh);
|
||||
// util_mesh_pack_uvs(mesh->texa);
|
||||
|
||||
mesh_data_t *md = mesh_data_create(raw);
|
||||
md->_->skin_blob = mesh->blob;
|
||||
gc_unroot(mesh->blob);
|
||||
|
||||
@@ -149,13 +149,48 @@ material_data_t *make_mesh_preview_viewport(slot_material_t *slot) {
|
||||
shader_context_load(con->data);
|
||||
material_context_load(mcon);
|
||||
|
||||
tool_type_t _tool = g_context->tool;
|
||||
i32 _fill_type = g_context->fill_type;
|
||||
slot_layer_t *_layer = g_context->layer;
|
||||
bool _select_active = g_context->select_active;
|
||||
bool _colorid_picked = g_context->colorid_picked;
|
||||
bool _picker_paint_mask = g_context->picker_paint_mask;
|
||||
gpu_texture_t *_brush_stencil_image = g_context->brush_stencil_image;
|
||||
gpu_texture_t *_brush_mask_image = g_context->brush_mask_image;
|
||||
blend_type_t _brush_blending = g_context->brush_blending;
|
||||
g_context->tool = TOOL_TYPE_FILL;
|
||||
g_context->fill_type = FILL_TYPE_OBJECT;
|
||||
g_context->layer = GC_ALLOC_INIT(slot_layer_t, {.fill_material = slot, .uv_type = UV_TYPE_UVMAP, .scale = 1.0, .visible = true});
|
||||
g_context->select_active = false;
|
||||
g_context->colorid_picked = false;
|
||||
g_context->picker_paint_mask = false;
|
||||
g_context->brush_stencil_image = NULL;
|
||||
g_context->brush_mask_image = NULL;
|
||||
g_context->brush_blending = BLEND_TYPE_MIX;
|
||||
|
||||
material_context_t *amcon = GC_ALLOC_INIT(material_context_t, {.name = "atlas", .bind_textures = any_array_create_from_raw((void *[]){}, 0)});
|
||||
material_t *amm = GC_ALLOC_INIT(material_t, {.name = "Material", .canvas = slot->canvas});
|
||||
node_shader_context_t *acon = make_paint_run_context(amm, amcon, "atlas");
|
||||
shader_context_load(acon->data);
|
||||
material_context_load(amcon);
|
||||
|
||||
g_context->tool = _tool;
|
||||
g_context->fill_type = _fill_type;
|
||||
g_context->layer = _layer;
|
||||
g_context->select_active = _select_active;
|
||||
g_context->colorid_picked = _colorid_picked;
|
||||
g_context->picker_paint_mask = _picker_paint_mask;
|
||||
g_context->brush_stencil_image = _brush_stencil_image;
|
||||
g_context->brush_mask_image = _brush_mask_image;
|
||||
g_context->brush_blending = _brush_blending;
|
||||
|
||||
shader_data_t *sd = GC_ALLOC_INIT(shader_data_t, {0});
|
||||
sd->name = string("_material_%s", i32_to_string(slot->id));
|
||||
sd->contexts = any_array_create_from_raw((void *[]){con->data}, 1);
|
||||
sd->contexts = any_array_create_from_raw((void *[]){con->data, acon->data}, 2);
|
||||
|
||||
material_data_t *md = GC_ALLOC_INIT(material_data_t, {0});
|
||||
md->name = sd->name;
|
||||
md->contexts = any_array_create_from_raw((void *[]){mcon}, 1);
|
||||
md->contexts = any_array_create_from_raw((void *[]){mcon, amcon}, 2);
|
||||
md->_ = GC_ALLOC_INIT(material_data_runtime_t, {0});
|
||||
md->_->shader = sd;
|
||||
md->_->uid = 0;
|
||||
|
||||
@@ -98,33 +98,39 @@ string_array_t *make_paint_color_attachments() {
|
||||
}
|
||||
|
||||
node_shader_context_t *make_paint_run(material_t *data, material_context_t *matcon) {
|
||||
return make_paint_run_context(data, matcon, "paint");
|
||||
}
|
||||
|
||||
node_shader_context_t *make_paint_run_context(material_t *data, material_context_t *matcon, char *context_id) {
|
||||
bool picking_tool = g_context->tool == TOOL_TYPE_COLORID || g_context->tool == TOOL_TYPE_PICKER || g_context->tool == TOOL_TYPE_MATERIAL ||
|
||||
g_context->tool == TOOL_TYPE_CURSOR;
|
||||
bool is_atlas = string_equals(context_id, "atlas");
|
||||
if (g_context->layer->texpaint_sculpt != NULL && !picking_tool) {
|
||||
return sculpt_make_sculpt_run(data, matcon);
|
||||
}
|
||||
|
||||
char *context_id = "paint";
|
||||
shader_context_t *props = GC_ALLOC_INIT(shader_context_t, {.name = context_id,
|
||||
.depth_write = false,
|
||||
.compare_mode = "always",
|
||||
.cull_mode = "none",
|
||||
.vertex_elements = any_array_create_from_raw(
|
||||
shader_context_t *props = GC_ALLOC_INIT(shader_context_t, {.name = context_id,
|
||||
.depth_write = false,
|
||||
.compare_mode = "always",
|
||||
.cull_mode = "none",
|
||||
.vertex_elements = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
GC_ALLOC_INIT(vertex_element_t, {.name = "pos", .data = "short4norm"}),
|
||||
GC_ALLOC_INIT(vertex_element_t, {.name = "nor", .data = "short2norm"}),
|
||||
GC_ALLOC_INIT(vertex_element_t, {.name = "tex", .data = "short2norm"}),
|
||||
},
|
||||
3),
|
||||
.color_attachments = make_paint_color_attachments()});
|
||||
node_shader_context_t *con_paint = node_shader_context_create(data, props);
|
||||
.color_attachments = make_paint_color_attachments()});
|
||||
node_shader_context_t *con_paint = node_shader_context_create(data, props);
|
||||
|
||||
if (mesh_data_get_vertex_array(g_context->paint_object->data, "col") != NULL) {
|
||||
node_shader_context_add_elem(con_paint, "col", "short4norm");
|
||||
}
|
||||
if (!is_atlas) {
|
||||
if (mesh_data_get_vertex_array(g_context->paint_object->data, "col") != NULL) {
|
||||
node_shader_context_add_elem(con_paint, "col", "short4norm");
|
||||
}
|
||||
|
||||
if (mesh_data_get_vertex_array(g_context->paint_object->data, "tex1") != NULL) {
|
||||
node_shader_context_add_elem(con_paint, "tex1", "short2norm");
|
||||
if (mesh_data_get_vertex_array(g_context->paint_object->data, "tex1") != NULL) {
|
||||
node_shader_context_add_elem(con_paint, "tex1", "short2norm");
|
||||
}
|
||||
}
|
||||
|
||||
con_paint->data->color_writes_red = u8_array_create_from_raw(
|
||||
@@ -159,7 +165,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
true,
|
||||
},
|
||||
4);
|
||||
con_paint->allow_vcols = mesh_data_get_vertex_array(g_context->paint_object->data, "col") != NULL;
|
||||
con_paint->allow_vcols = !is_atlas && mesh_data_get_vertex_array(g_context->paint_object->data, "col") != NULL;
|
||||
|
||||
node_shader_t *kong = node_shader_context_make_kong(con_paint);
|
||||
|
||||
@@ -189,12 +195,13 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
bool uv_island_fill = g_context->tool == TOOL_TYPE_FILL && g_context->fill_type == FILL_TYPE_UV_ISLAND;
|
||||
bool decal = context_is_decal();
|
||||
|
||||
if (g_context->layer->uv_map == 1) {
|
||||
node_shader_write_vert(kong, "var tpos: float2 = float2(input.tex1.x * 2.0 - 1.0, (1.0 - input.tex1.y) * 2.0 - 1.0);");
|
||||
}
|
||||
else {
|
||||
node_shader_write_vert(kong, "var tpos: float2 = float2(input.tex.x * 2.0 - 1.0, (1.0 - input.tex.y) * 2.0 - 1.0);");
|
||||
char *tuv = g_context->layer->uv_map == 1 ? "input.tex1" : "input.tex";
|
||||
if (is_atlas) {
|
||||
node_shader_add_constant(kong, "atlas_transform: float3", "_atlas_transform");
|
||||
node_shader_write_vert(kong, string("var atlas_uv: float2 = %s * constants.atlas_transform.z + constants.atlas_transform.xy;", tuv));
|
||||
tuv = "atlas_uv";
|
||||
}
|
||||
node_shader_write_vert(kong, string("var tpos: float2 = float2(%s.x * 2.0 - 1.0, (1.0 - %s.y) * 2.0 - 1.0);", tuv, tuv));
|
||||
|
||||
node_shader_write_vert(kong, "output.pos = float4(tpos, 0.0, 1.0);");
|
||||
|
||||
@@ -304,7 +311,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
make_discard_material_id(kong, NULL);
|
||||
}
|
||||
|
||||
make_texcoord_run(kong);
|
||||
make_texcoord_run(kong, is_atlas);
|
||||
|
||||
if (g_context->tool == TOOL_TYPE_CLONE || g_context->tool == TOOL_TYPE_BLUR) {
|
||||
node_shader_add_texture(kong, "gbuffer2", NULL);
|
||||
@@ -328,7 +335,7 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
parser_material_triplanar = uv_type == UV_TYPE_TRIPLANAR && !decal;
|
||||
parser_material_sample_keep_aspect = decal;
|
||||
gc_unroot(parser_material_sample_uv_scale);
|
||||
parser_material_sample_uv_scale = "constants.brush_scale";
|
||||
parser_material_sample_uv_scale = is_atlas ? "1.0" : "constants.brush_scale";
|
||||
gc_root(parser_material_sample_uv_scale);
|
||||
shader_out_t *sout = parser_material_parse(g_context->material->canvas, con_paint, kong, matcon);
|
||||
parser_material_parse_emission = false;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#include "../global.h"
|
||||
|
||||
void make_texcoord_run(node_shader_t *kong) {
|
||||
void make_texcoord_run(node_shader_t *kong, bool is_atlas) {
|
||||
|
||||
bool fill_layer = g_context->layer->fill_material != NULL;
|
||||
uv_type_t uv_type = fill_layer ? g_context->layer->uv_type : g_context->brush_paint;
|
||||
@@ -9,8 +9,13 @@ void make_texcoord_run(node_shader_t *kong) {
|
||||
f32 angle = g_context->brush_angle + g_context->brush_nodes_angle;
|
||||
f32 uv_angle = fill_layer ? g_context->layer->angle : angle;
|
||||
|
||||
if (uv_type == UV_TYPE_PROJECT || decal) { // TexCoords - project
|
||||
char *scale = "1.0";
|
||||
if (!is_atlas) {
|
||||
node_shader_add_constant(kong, "brush_scale: float", "_brush_scale");
|
||||
scale = "constants.brush_scale";
|
||||
}
|
||||
|
||||
if (uv_type == UV_TYPE_PROJECT || decal) { // TexCoords - project
|
||||
node_shader_write_attrib_frag(kong, "var uvsp: float2 = sp.xy;");
|
||||
|
||||
if (fill_layer) { // Decal layer
|
||||
@@ -117,17 +122,16 @@ void make_texcoord_run(node_shader_t *kong) {
|
||||
}
|
||||
}
|
||||
|
||||
node_shader_write_attrib_frag(kong, "var tex_coord: float2 = uvsp * constants.brush_scale;");
|
||||
node_shader_write_attrib_frag(kong, string("var tex_coord: float2 = uvsp * %s;", scale));
|
||||
}
|
||||
else if (uv_type == UV_TYPE_UVMAP) { // TexCoords - uvmap
|
||||
node_shader_add_constant(kong, "brush_scale: float", "_brush_scale");
|
||||
node_shader_add_out(kong, "tex_coord: float2");
|
||||
|
||||
if (g_context->layer->uv_map == 1) {
|
||||
node_shader_write_vert(kong, "output.tex_coord = input.tex1 * constants.brush_scale;");
|
||||
node_shader_write_vert(kong, string("output.tex_coord = input.tex1 * %s;", scale));
|
||||
}
|
||||
else {
|
||||
node_shader_write_vert(kong, "output.tex_coord = input.tex * constants.brush_scale;");
|
||||
node_shader_write_vert(kong, string("output.tex_coord = input.tex * %s;", scale));
|
||||
}
|
||||
|
||||
if (uv_angle > 0.0) {
|
||||
@@ -141,14 +145,13 @@ void make_texcoord_run(node_shader_t *kong) {
|
||||
else { // UV_TYPE_TRIPLANAR, TexCoords - triplanar
|
||||
kong->frag_wposition = true;
|
||||
kong->frag_n = true;
|
||||
node_shader_add_constant(kong, "brush_scale: float", "_brush_scale");
|
||||
node_shader_write_attrib_frag(kong, "var tri_weight: float3 = input.wnormal * input.wnormal;");
|
||||
node_shader_write_attrib_frag(kong, "var tri_max: float = max(tri_weight.x, max(tri_weight.y, tri_weight.z));");
|
||||
node_shader_write_attrib_frag(kong, "tri_weight = max3(tri_weight - float3(tri_max * 0.75, tri_max * 0.75, tri_max * 0.75), float3(0.0, 0.0, 0.0));");
|
||||
node_shader_write_attrib_frag(kong, "var tex_coord_blend: float3 = tri_weight * (1.0 / (tri_weight.x + tri_weight.y + tri_weight.z));");
|
||||
node_shader_write_attrib_frag(kong, "var tex_coord: float2 = input.wposition.yz * constants.brush_scale * 0.5;");
|
||||
node_shader_write_attrib_frag(kong, "var tex_coord1: float2 = input.wposition.xz * constants.brush_scale * 0.5;");
|
||||
node_shader_write_attrib_frag(kong, "var tex_coord2: float2 = input.wposition.xy * constants.brush_scale * 0.5;");
|
||||
node_shader_write_attrib_frag(kong, string("var tex_coord: float2 = input.wposition.yz * %s * 0.5;", scale));
|
||||
node_shader_write_attrib_frag(kong, string("var tex_coord1: float2 = input.wposition.xz * %s * 0.5;", scale));
|
||||
node_shader_write_attrib_frag(kong, string("var tex_coord2: float2 = input.wposition.xy * %s * 0.5;", scale));
|
||||
if (uv_angle != 0.0) {
|
||||
node_shader_add_constant(kong, "brush_angle: float2", "_brush_angle");
|
||||
node_shader_write_attrib_frag(kong, "tex_coord = float2(tex_coord.x * constants.brush_angle.x - tex_coord.y * constants.brush_angle.y, tex_coord.x "
|
||||
|
||||
@@ -90,6 +90,11 @@ void render_gizmo_update() {
|
||||
transform_build_matrix(paint_object->transform);
|
||||
ui_header_handle->redraws = 2;
|
||||
|
||||
if (config_is_raytrace_multi()) {
|
||||
render_path_raytrace_ready = false;
|
||||
g_context->ddirty = 2;
|
||||
}
|
||||
|
||||
physics_body_t *pb = paint_object->_->body;
|
||||
if (pb != NULL) {
|
||||
physics_body_sync_transform(pb);
|
||||
|
||||
@@ -16,10 +16,10 @@ void render_path_raytrace_commands(bool use_live_layer) {
|
||||
render_path_raytrace_init_shader = true;
|
||||
}
|
||||
char *ext = "";
|
||||
// if (g_context->tool == TOOL_TYPE_CURSOR) {
|
||||
// ext = "forge_";
|
||||
// }
|
||||
char *mode = g_config->pathtrace_mode == PATHTRACE_MODE_FAST ? "core" : "full";
|
||||
if (config_is_raytrace_multi()) {
|
||||
ext = "multi_";
|
||||
}
|
||||
char *mode = config_is_raytrace_fast() ? "core" : "full";
|
||||
render_path_raytrace_raytrace_init(string("raytrace_brute_%s%s%s", ext, mode, render_path_raytrace_ext), true);
|
||||
gc_unroot(render_path_raytrace_last_envmap);
|
||||
render_path_raytrace_last_envmap = NULL;
|
||||
@@ -137,12 +137,12 @@ void render_path_raytrace_build_data() {
|
||||
|
||||
mesh_object_t *mo = !context_layer_filter_used() ? g_context->merged_object : g_context->paint_object;
|
||||
|
||||
// if (g_context->tool == TOOL_TYPE_CURSOR) {
|
||||
// render_path_raytrace_transform = mo->base->transform->world_unpack;
|
||||
// }
|
||||
// else {
|
||||
render_path_raytrace_transform = mat4_identity();
|
||||
// }
|
||||
if (config_is_raytrace_multi()) {
|
||||
render_path_raytrace_transform = mo->base->transform->world_unpack;
|
||||
}
|
||||
else {
|
||||
render_path_raytrace_transform = mat4_identity();
|
||||
}
|
||||
|
||||
f32 sc = mo->base->transform->scale.x * mo->data->scale_pos;
|
||||
if (mo->base->parent != NULL) {
|
||||
@@ -174,20 +174,21 @@ void render_path_raytrace_raytrace_init(char *shader_name, bool build) {
|
||||
}
|
||||
|
||||
{
|
||||
config_apply_raytrace_multi();
|
||||
_gpu_raytrace_as_init();
|
||||
|
||||
// if (g_context->tool == TOOL_TYPE_CURSOR) {
|
||||
// for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
|
||||
// mesh_object_t *po = g_project->_->paint_objects->buffer[i];
|
||||
// if (!po->base->visible) {
|
||||
// continue;
|
||||
// }
|
||||
// _gpu_raytrace_as_add(po->data->_->vertex_buffer, po->data->_->index_buffer, po->base->transform->world_unpack);
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
_gpu_raytrace_as_add(render_path_raytrace_vb, render_path_raytrace_ib, render_path_raytrace_transform);
|
||||
// }
|
||||
if (config_is_raytrace_multi()) {
|
||||
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
|
||||
mesh_object_t *po = g_project->_->paint_objects->buffer[i];
|
||||
if (!po->base->visible) {
|
||||
continue;
|
||||
}
|
||||
_gpu_raytrace_as_add(po->data->_->vertex_buffer, po->data->_->index_buffer, po->base->transform->world_unpack);
|
||||
}
|
||||
}
|
||||
else {
|
||||
_gpu_raytrace_as_add(render_path_raytrace_vb, render_path_raytrace_ib, render_path_raytrace_transform);
|
||||
}
|
||||
|
||||
gpu_buffer_t *vb_full = g_context->merged_object->data->_->vertex_buffer;
|
||||
gpu_buffer_t *ib_full = g_context->merged_object->data->_->index_buffer;
|
||||
@@ -197,8 +198,9 @@ void render_path_raytrace_raytrace_init(char *shader_name, bool build) {
|
||||
}
|
||||
|
||||
void render_path_raytrace_draw(bool use_live_layer) {
|
||||
bool is_live = g_config->brush_live && render_path_paint_live_layer_drawn > 0;
|
||||
if (g_context->ddirty > 1 || g_context->pdirty > 0 || is_live) {
|
||||
bool is_live = g_config->brush_live && render_path_paint_live_layer_drawn > 0;
|
||||
bool is_player = g_config->workspace == WORKSPACE_PLAYER;
|
||||
if (g_context->ddirty > 1 || g_context->pdirty > 0 || is_live || is_player) {
|
||||
render_path_raytrace_frame = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,6 @@ typedef struct config {
|
||||
f32 brush_alpha_discard;
|
||||
i32 dilate_radius;
|
||||
char *blender;
|
||||
i32 scene_atlas_res;
|
||||
bool grid_snap;
|
||||
bool experimental;
|
||||
i32 neural_res;
|
||||
|
||||
@@ -413,10 +413,6 @@ void box_preferences_usage_tab() {
|
||||
4);
|
||||
g_config->layer_res = ui_combo(h_layer_res, res_combo, tr("Default Layer Resolution"), true, UI_ALIGN_LEFT, true);
|
||||
|
||||
ui_handle_t *h_scene_atlas_res = ui_handle(__ID__);
|
||||
h_scene_atlas_res->i = g_config->scene_atlas_res;
|
||||
g_config->scene_atlas_res = ui_combo(h_scene_atlas_res, res_combo, tr("Scene Atlas Resolution"), true, UI_ALIGN_LEFT, true);
|
||||
|
||||
ui_handle_t *h_server = ui_handle(__ID__);
|
||||
h_server->text = string_copy(g_config->server);
|
||||
g_config->server = string_copy(ui_text_input(h_server, tr("Cloud Server"), UI_ALIGN_LEFT, true, false));
|
||||
@@ -615,13 +611,16 @@ void box_preferences_viewport_tab() {
|
||||
(void *[]){
|
||||
tr("Fast"),
|
||||
tr("Quality"),
|
||||
tr("Multi Fast"),
|
||||
tr("Multi Quality"),
|
||||
},
|
||||
2);
|
||||
4);
|
||||
g_config->pathtrace_mode = ui_combo(h_pathtrace_mode, pathtrace_mode_combo, tr("Path Tracer"), true, UI_ALIGN_LEFT, true);
|
||||
if (h_pathtrace_mode->changed) {
|
||||
render_path_raytrace_ready = false;
|
||||
render_path_raytrace_init_shader = true;
|
||||
g_context->ddirty = 2;
|
||||
util_mesh_merge(NULL);
|
||||
}
|
||||
|
||||
ui_handle_t *h_render_mode = ui_handle(__ID__);
|
||||
|
||||
@@ -85,6 +85,7 @@ void tab_meshes_on_material_deleted(i32 deleted_index) {
|
||||
if (changed) {
|
||||
g_project->mesh_materials = i32_array_create(0);
|
||||
g_context->ddirty = 2;
|
||||
g_context->rtdirty = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +118,7 @@ void tab_meshes_on_material_reordered(i32 old_index, i32 new_index) {
|
||||
if (changed) {
|
||||
g_project->mesh_materials = i32_array_create(0);
|
||||
g_context->ddirty = 2;
|
||||
g_context->rtdirty = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,6 +368,7 @@ void tab_meshes_draw_context_menu() {
|
||||
if (hmat->changed) {
|
||||
tab_meshes_set_override(o, hmat->i - 1);
|
||||
g_context->ddirty = 2;
|
||||
g_context->rtdirty = 2;
|
||||
g_project->mesh_materials = i32_array_create(0);
|
||||
}
|
||||
|
||||
@@ -392,7 +395,7 @@ void tab_meshes_draw_context_menu() {
|
||||
|
||||
// Physics
|
||||
if (g_config->experimental) {
|
||||
physics_body_t *pb = o->base->_->body;
|
||||
physics_body_t *pb = o->base->_->body;
|
||||
string_array_t *phys_combo = string_array_create(0);
|
||||
string_array_push(phys_combo, ""); // Empty = no physics
|
||||
string_array_push(phys_combo, tr("Box"));
|
||||
@@ -410,7 +413,7 @@ void tab_meshes_draw_context_menu() {
|
||||
}
|
||||
if (hphys->i > 0) {
|
||||
physics_shape_t shape = (physics_shape_t)(hphys->i - 1);
|
||||
bool dynamic = shape == PHYSICS_SHAPE_BOX || shape == PHYSICS_SHAPE_SPHERE;
|
||||
bool dynamic = shape == PHYSICS_SHAPE_BOX || shape == PHYSICS_SHAPE_SPHERE;
|
||||
sim_add_body(o->base, shape, dynamic ? 1.0 : 0.0);
|
||||
pb = o->base->_->body;
|
||||
}
|
||||
@@ -548,7 +551,6 @@ mesh_object_t *tab_meshes_append_shape(char *mesh_name) {
|
||||
raw = scene_raw->mesh_datas->buffer[0];
|
||||
}
|
||||
|
||||
// util_mesh_pack_uvs(raw->vertex_arrays->buffer[2]->values);
|
||||
mesh_data_t *md = mesh_data_create(raw);
|
||||
md->_->handle = md->name;
|
||||
mesh_object_t *mo = scene_add_mesh_object(md, g_project->_->paint_objects->buffer[0]->material, NULL);
|
||||
@@ -568,6 +570,7 @@ mesh_object_t *tab_meshes_append_shape(char *mesh_name) {
|
||||
any_array_push(g_project->_->paint_objects, mo);
|
||||
tab_stages_add_object(mo->base->name);
|
||||
g_context->paint_object = mo;
|
||||
util_mesh_merge(NULL);
|
||||
return mo;
|
||||
}
|
||||
|
||||
|
||||
+23
-18
@@ -87,12 +87,6 @@ f32 uniforms_ext_f32_link(object_t *object, material_data_t *mat, char *link) {
|
||||
return val;
|
||||
}
|
||||
else if (string_equals(link, "_brush_scale")) {
|
||||
// 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;
|
||||
// }
|
||||
bool fill = g_context->layer->fill_material != NULL;
|
||||
f32 val = (fill ? g_context->layer->scale : g_context->brush_scale) * g_context->brush_nodes_scale;
|
||||
return val;
|
||||
@@ -223,6 +217,14 @@ vec4_t uniforms_ext_vec3_link(object_t *object, material_data_t *mat, char *link
|
||||
g_context->prev_paint_vec_y = g_context->last_paint_vec_y;
|
||||
return v;
|
||||
}
|
||||
else if (string_equals(link, "_atlas_transform")) {
|
||||
if (!config_is_raytrace_multi()) {
|
||||
return (vec4_t){0.0, 0.0, 1.0, 1.0};
|
||||
}
|
||||
i32 stride = util_mesh_atlas_stride();
|
||||
i32 slot = util_mesh_atlas_slot(object);
|
||||
return (vec4_t){(slot % stride) / (f32)stride, (slot / stride) / (f32)stride, 1.0 / stride, 1.0};
|
||||
}
|
||||
else if (string_equals(link, "_decal_layer_loc")) {
|
||||
v = (vec4_t){g_context->layer->decal_mat.m30, g_context->layer->decal_mat.m31, g_context->layer->decal_mat.m32, 1.0};
|
||||
return v;
|
||||
@@ -364,26 +366,29 @@ void uniforms_ext_cache_uv_map(void *_) {
|
||||
util_uv_cache_uv_map();
|
||||
}
|
||||
|
||||
static gpu_texture_t *_uniforms_ext_undo_target(char *name) {
|
||||
render_target_t *rt = any_map_get(render_path_render_targets, name);
|
||||
if (rt == NULL) {
|
||||
rt = any_map_get(render_path_render_targets, "empty_black");
|
||||
}
|
||||
return rt->_image;
|
||||
}
|
||||
|
||||
gpu_texture_t *uniforms_ext_tex_link(object_t *object, material_data_t *mat, char *link) {
|
||||
if (string_equals(link, "_texpaint_undo")) {
|
||||
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
|
||||
render_target_t *rt = any_map_get(render_path_render_targets, string("texpaint_undo%d", i));
|
||||
return rt->_image;
|
||||
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
|
||||
return _uniforms_ext_undo_target(string("texpaint_undo%d", i));
|
||||
}
|
||||
else if (string_equals(link, "_texpaint_nor_undo")) {
|
||||
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
|
||||
render_target_t *rt = any_map_get(render_path_render_targets, string("texpaint_nor_undo%d", i));
|
||||
return rt->_image;
|
||||
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
|
||||
return _uniforms_ext_undo_target(string("texpaint_nor_undo%d", i));
|
||||
}
|
||||
else if (string_equals(link, "_texpaint_pack_undo")) {
|
||||
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
|
||||
render_target_t *rt = any_map_get(render_path_render_targets, string("texpaint_pack_undo%d", i));
|
||||
return rt->_image;
|
||||
i32 i = history_undo_i - 1 < 0 ? g_config->undo_steps - 1 : history_undo_i - 1;
|
||||
return _uniforms_ext_undo_target(string("texpaint_pack_undo%d", i));
|
||||
}
|
||||
else if (string_equals(link, "_texpaint_sculpt_undo")) {
|
||||
// Per-frame accumulation reference
|
||||
render_target_t *rt = any_map_get(render_path_render_targets, "texpaint_sculpt_ref");
|
||||
return rt->_image;
|
||||
return _uniforms_ext_undo_target("texpaint_sculpt_ref"); // Per-frame accumulation reference
|
||||
}
|
||||
else if (string_equals(link, "_texcolorid")) {
|
||||
if (g_project->_->assets->length == 0) {
|
||||
|
||||
@@ -703,10 +703,6 @@ void layers_create_fill_layer_on_next_frame(void *_) {
|
||||
}
|
||||
|
||||
void layers_create_fill_layer(uv_type_t uv_type, mat4_t decal_mat, i32 position) {
|
||||
// if (g_context->tool == TOOL_TYPE_CURSOR) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
_layers_uv_type = uv_type;
|
||||
_layers_decal_mat = decal_mat;
|
||||
_layers_position = position;
|
||||
@@ -1049,6 +1045,31 @@ void layers_merge_layer(slot_layer_t *l0, slot_layer_t *l1, bool use_mask) {
|
||||
}
|
||||
}
|
||||
|
||||
void layers_draw_mesh_materials() {
|
||||
bool any = false;
|
||||
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
|
||||
if (tab_meshes_get_override(g_project->_->paint_objects->buffer[i]) >= 0) {
|
||||
any = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!any) {
|
||||
return;
|
||||
}
|
||||
|
||||
string_array_t *additional = any_array_create_from_raw(
|
||||
(void *[]){
|
||||
"expb",
|
||||
"expc",
|
||||
"texpaint_blend0",
|
||||
},
|
||||
3);
|
||||
render_path_set_target("expa", additional, NULL, GPU_CLEAR_NONE, 0, 0.0);
|
||||
render_path_bind_target("main", "gbufferD");
|
||||
render_path_bind_target("texpaint_blend1", "paintmask");
|
||||
render_path_draw_meshes("atlas");
|
||||
}
|
||||
|
||||
slot_layer_t *layers_flatten(bool height_to_normal, slot_layer_t_array_t *layers) {
|
||||
if (layers == NULL) {
|
||||
layers = g_project->_->layers;
|
||||
@@ -1171,6 +1192,8 @@ slot_layer_t *layers_flatten(bool height_to_normal, slot_layer_t_array_t *layers
|
||||
}
|
||||
}
|
||||
|
||||
layers_draw_mesh_materials();
|
||||
|
||||
slot_layer_t *l0 = GC_ALLOC_INIT(slot_layer_t, {.texpaint = layers_expa, .texpaint_nor = layers_expb, .texpaint_pack = layers_expc});
|
||||
|
||||
// Merge height map into normal map
|
||||
|
||||
@@ -12,21 +12,24 @@ void util_mesh_remove_merged() {
|
||||
}
|
||||
}
|
||||
|
||||
static bool _util_mesh_is_representative(i32 i) {
|
||||
mesh_object_t_array_t *paint_objects = g_project->_->paint_objects;
|
||||
if (!paint_objects->buffer[i]->base->visible) {
|
||||
return false;
|
||||
}
|
||||
for (i32 j = 0; j < i; ++j) {
|
||||
if (paint_objects->buffer[j]->base->visible && paint_objects->buffer[j]->data == paint_objects->buffer[i]->data) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
mesh_object_t_array_t *util_mesh_get_unique() {
|
||||
mesh_object_t_array_t *ar = any_array_create_from_raw((void *[]){}, 0);
|
||||
|
||||
for (i32 i = 0; i < g_project->_->paint_objects->length; ++i) {
|
||||
if (!g_project->_->paint_objects->buffer[i]->base->visible) {
|
||||
continue;
|
||||
}
|
||||
bool found = false;
|
||||
for (i32 j = 0; j < i; ++j) {
|
||||
if (g_project->_->paint_objects->buffer[i]->data == g_project->_->paint_objects->buffer[j]->data) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (_util_mesh_is_representative(i)) {
|
||||
any_array_push(ar, g_project->_->paint_objects->buffer[i]);
|
||||
}
|
||||
}
|
||||
@@ -45,6 +48,43 @@ mesh_object_t_array_t *util_mesh_get_visible() {
|
||||
return ar;
|
||||
}
|
||||
|
||||
#define ATLAS_MAX_STRIDE 8
|
||||
#define ATLAS_MAX_SLOTS (ATLAS_MAX_STRIDE * ATLAS_MAX_STRIDE)
|
||||
|
||||
static i32 _util_mesh_atlas_stride_for(i32 count) {
|
||||
i32 stride = 1;
|
||||
while (stride * stride < count && stride < ATLAS_MAX_STRIDE) {
|
||||
stride++;
|
||||
}
|
||||
return stride;
|
||||
}
|
||||
|
||||
static i32 util_mesh_atlas_stride_merged = 1;
|
||||
static mesh_data_t *util_mesh_atlas_slot_data[ATLAS_MAX_SLOTS];
|
||||
static i32 util_mesh_atlas_slot_count = 0;
|
||||
static bool util_mesh_atlas_slots_spent = false;
|
||||
|
||||
i32 util_mesh_atlas_stride() {
|
||||
return util_mesh_atlas_stride_merged;
|
||||
}
|
||||
|
||||
i32 util_mesh_atlas_slot(object_t *object) {
|
||||
mesh_object_t_array_t *paint_objects = g_project->_->paint_objects;
|
||||
mesh_data_t *data = NULL;
|
||||
for (i32 i = 0; i < paint_objects->length; ++i) {
|
||||
if (paint_objects->buffer[i]->base == object) {
|
||||
data = paint_objects->buffer[i]->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i32 i = 0; i < util_mesh_atlas_slot_count; ++i) {
|
||||
if (util_mesh_atlas_slot_data[i] == data) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return util_mesh_atlas_slots_spent ? ATLAS_MAX_SLOTS - 1 : 0;
|
||||
}
|
||||
|
||||
mesh_data_t *util_mesh_data_duplicate(mesh_data_t *source) {
|
||||
mesh_data_t *raw = gc_alloc(sizeof(mesh_data_t));
|
||||
raw->name = string_copy(source->name);
|
||||
@@ -86,6 +126,11 @@ static mesh_data_t *util_mesh_build_merged_data(mesh_object_t_array_t *paint_obj
|
||||
i32 coli = vatex1 != NULL ? 4 : 3;
|
||||
u32_array_t *ia = u32_array_create(ilen);
|
||||
|
||||
i32 atlas_stride = config_is_raytrace_multi() ? _util_mesh_atlas_stride_for(paint_objects->length) : 1;
|
||||
util_mesh_atlas_stride_merged = atlas_stride;
|
||||
util_mesh_atlas_slot_count = 0;
|
||||
util_mesh_atlas_slots_spent = paint_objects->length > ATLAS_MAX_SLOTS;
|
||||
|
||||
i32 voff = 0;
|
||||
i32 ioff = 0;
|
||||
for (i32 i = 0; i < paint_objects->length; ++i) {
|
||||
@@ -117,8 +162,17 @@ static mesh_data_t *util_mesh_build_merged_data(mesh_object_t_array_t *paint_obj
|
||||
va1->buffer[j + voff * 2] = vas->buffer[1]->values->buffer[j];
|
||||
}
|
||||
// Tex
|
||||
for (i32 j = 0; j < vas->buffer[2]->values->length; ++j) {
|
||||
va2->buffer[j + voff * 2] = vas->buffer[2]->values->buffer[j];
|
||||
i32 slot = i < ATLAS_MAX_SLOTS ? i : ATLAS_MAX_SLOTS - 1;
|
||||
if (i < ATLAS_MAX_SLOTS) {
|
||||
util_mesh_atlas_slot_data[slot] = paint_objects->buffer[i]->data;
|
||||
util_mesh_atlas_slot_count = slot + 1;
|
||||
}
|
||||
f32 tile_step = 32767.0f / atlas_stride;
|
||||
f32 tile_x = atlas_stride > 1 ? (slot % atlas_stride) * tile_step : 0.0f;
|
||||
f32 tile_y = atlas_stride > 1 ? (slot / atlas_stride) * tile_step : 0.0f;
|
||||
for (i32 j = 0; j < vas->buffer[2]->values->length / 2; ++j) {
|
||||
va2->buffer[j * 2 + voff * 2] = vas->buffer[2]->values->buffer[j * 2] / (float)atlas_stride + tile_x;
|
||||
va2->buffer[j * 2 + 1 + voff * 2] = vas->buffer[2]->values->buffer[j * 2 + 1] / (float)atlas_stride + tile_y;
|
||||
}
|
||||
// Tex1
|
||||
if (vatex1 != NULL) {
|
||||
@@ -164,12 +218,12 @@ static mesh_data_t *util_mesh_build_merged_data(mesh_object_t_array_t *paint_obj
|
||||
|
||||
void util_mesh_merge(mesh_object_t_array_t *paint_objects) {
|
||||
if (paint_objects == NULL) {
|
||||
// if (g_context->tool == TOOL_TYPE_CURSOR) {
|
||||
// paint_objects = util_mesh_get_unique();
|
||||
// }
|
||||
// else {
|
||||
paint_objects = g_project->_->paint_objects;
|
||||
// }
|
||||
if (config_is_raytrace_multi()) {
|
||||
paint_objects = util_mesh_get_unique();
|
||||
}
|
||||
else {
|
||||
paint_objects = g_project->_->paint_objects;
|
||||
}
|
||||
}
|
||||
if (paint_objects->length == 0) {
|
||||
return;
|
||||
@@ -699,25 +753,6 @@ void util_mesh_decimate(f32 strength) {
|
||||
#endif
|
||||
}
|
||||
|
||||
i32 _util_mesh_unique_data_count() {
|
||||
return util_mesh_get_unique()->length;
|
||||
}
|
||||
|
||||
void util_mesh_pack_uvs(i16_array_t *texa) {
|
||||
// Scale tex coords into global atlas
|
||||
i32 atlas_w = config_get_scene_atlas_res();
|
||||
i32 item_i = _util_mesh_unique_data_count() - 1; // Add the one being imported
|
||||
i32 item_w = config_get_layer_res();
|
||||
i32 atlas_stride = atlas_w / (float)item_w;
|
||||
i32 atlas_step = 32767 / (float)atlas_stride;
|
||||
i32 item_x = (item_i % atlas_stride) * atlas_step;
|
||||
i32 item_y = math_floor(item_i / (float)atlas_stride) * atlas_step;
|
||||
for (i32 i = 0; i < texa->length / 2.0; ++i) {
|
||||
texa->buffer[i * 2] = texa->buffer[i * 2] / (float)atlas_stride + item_x;
|
||||
texa->buffer[i * 2 + 1] = texa->buffer[i * 2 + 1] / (float)atlas_stride + item_y;
|
||||
}
|
||||
}
|
||||
|
||||
static i32 *_cc_he_vlo;
|
||||
static i32 *_cc_he_vhi;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user