paint: brush camera align
This commit is contained in:
@@ -8,6 +8,8 @@ const constants: {
|
||||
radius: float;
|
||||
camera_right: float3;
|
||||
tint: float3;
|
||||
camera_up: float3;
|
||||
camera_align: float;
|
||||
};
|
||||
|
||||
#[set(everything)]
|
||||
@@ -40,11 +42,6 @@ fun get_normal(p0: float3, uv: float2): float3 {
|
||||
return normalize(cross(p2 - p0, p1 - p0));
|
||||
}
|
||||
|
||||
// fun create_basis(normal: float3, out tangent: float3, out binormal: float3) {
|
||||
// tangent = normalize(constants.camera_right - normal * dot(constants.camera_right, normal));
|
||||
// binormal = cross(tangent, normal);
|
||||
// }
|
||||
|
||||
fun cursor_vert(input: vert_in): vert_out {
|
||||
var keep: float = input.pos.x + input.nor.x; // hlsl
|
||||
|
||||
@@ -59,9 +56,14 @@ fun cursor_vert(input: vert_in): vert_out {
|
||||
var n_tan: float3;
|
||||
var n_bin: float3;
|
||||
|
||||
// create_basis(n, n_tan, n_bin);
|
||||
n_tan = normalize(constants.camera_right - n * dot(constants.camera_right, n));
|
||||
n_bin = cross(n_tan, n);
|
||||
if (constants.camera_align > 0.0) {
|
||||
n_tan = constants.camera_right;
|
||||
n_bin = constants.camera_up;
|
||||
}
|
||||
else {
|
||||
n_tan = normalize(constants.camera_right - n * dot(constants.camera_right, n));
|
||||
n_bin = cross(n_tan, n);
|
||||
}
|
||||
|
||||
if (vertex_id() == 0) {
|
||||
wpos += normalize(-n_tan - n_bin) * 0.7 * constants.radius;
|
||||
|
||||
@@ -426,8 +426,10 @@ bool context_is_decal_mask() {
|
||||
return context_is_decal() && operator_shortcut(any_map_get(g_keymap, "decal_mask"), SHORTCUT_TYPE_DOWN);
|
||||
}
|
||||
|
||||
bool context_is_decal_camera_align() {
|
||||
return context_is_decal() && (g_context->decal_camera_align || operator_shortcut(any_map_get(g_keymap, "decal_camera_align"), SHORTCUT_TYPE_DOWN));
|
||||
bool context_is_brush_camera_align() {
|
||||
bool brush = g_context->tool == TOOL_TYPE_BRUSH || g_context->tool == TOOL_TYPE_ERASER;
|
||||
return (context_is_decal() || brush) &&
|
||||
(g_context->brush_camera_align || operator_shortcut(any_map_get(g_keymap, "brush_camera_align"), SHORTCUT_TYPE_DOWN));
|
||||
}
|
||||
|
||||
bool context_is_decal_mask_paint() {
|
||||
|
||||
@@ -257,7 +257,7 @@ bool context_in_browser();
|
||||
bool context_is_decal();
|
||||
bool context_is_decal_mask();
|
||||
bool context_is_decal_mask_paint();
|
||||
bool context_is_decal_camera_align();
|
||||
bool context_is_brush_camera_align();
|
||||
bool context_is_floating_toolbar();
|
||||
void context_set_viewport_mode(viewport_mode_t mode);
|
||||
void context_load_envmap();
|
||||
|
||||
@@ -83,6 +83,8 @@ i32 pipes_cursor_tex_step;
|
||||
i32 pipes_cursor_radius;
|
||||
i32 pipes_cursor_camera_right;
|
||||
i32 pipes_cursor_tint;
|
||||
i32 pipes_cursor_camera_up;
|
||||
i32 pipes_cursor_camera_align;
|
||||
i32 pipes_cursor_gbufferd;
|
||||
gpu_pipeline_t *pipes_cursor_decal;
|
||||
i32 pipes_cursor_decal_vp;
|
||||
|
||||
@@ -83,7 +83,7 @@ any_map_t *keymap_get_default() {
|
||||
any_map_set(keymap, "node_search", "space");
|
||||
any_map_set(keymap, "operator_search", "space");
|
||||
any_map_set(keymap, "decal_mask", "ctrl");
|
||||
any_map_set(keymap, "decal_camera_align", "z");
|
||||
any_map_set(keymap, "brush_camera_align", "z");
|
||||
any_map_set(keymap, "grid_snap", "x");
|
||||
any_map_set(keymap, "select_material", "shift+number");
|
||||
any_map_set(keymap, "select_layer", "alt+number");
|
||||
|
||||
@@ -251,7 +251,7 @@ static void texture_mesh_node_project(ui_node_t *node) {
|
||||
|
||||
// Project a camera-aligned decal
|
||||
g_context->tool = TOOL_TYPE_DECAL;
|
||||
g_context->decal_camera_align = true;
|
||||
g_context->brush_camera_align = true;
|
||||
g_context->brush_opacity = 1.0;
|
||||
g_context->brush_angle = 0.0;
|
||||
g_context->brush_scale = 1.0;
|
||||
@@ -302,7 +302,7 @@ static void texture_mesh_node_project(ui_node_t *node) {
|
||||
|
||||
g_context->pdirty = 0;
|
||||
g_context->tool = _tool;
|
||||
g_context->decal_camera_align = false;
|
||||
g_context->brush_camera_align = false;
|
||||
g_context->brush_radius = _brush_radius;
|
||||
g_context->brush_opacity = _brush_opacity;
|
||||
g_context->brush_angle = _brush_angle;
|
||||
|
||||
@@ -214,6 +214,8 @@ void pipes_init() {
|
||||
pipes_cursor_radius = pipes_get_constant_location("float");
|
||||
pipes_cursor_camera_right = pipes_get_constant_location("float3");
|
||||
pipes_cursor_tint = pipes_get_constant_location("float3");
|
||||
pipes_cursor_camera_up = pipes_get_constant_location("float3");
|
||||
pipes_cursor_camera_align = pipes_get_constant_location("float");
|
||||
pipes_cursor_gbufferd = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,15 +56,30 @@ void make_brush_run(node_shader_t *kong) {
|
||||
}
|
||||
node_shader_write_frag(kong, "var ba: float3 = winplast.xyz - winp.xyz;");
|
||||
|
||||
if (g_context->brush_lazy_radius > 0 && g_context->brush_lazy_step > 0) {
|
||||
// Sphere
|
||||
node_shader_write_frag(kong, "dist = distance(input.wposition, winp.xyz);");
|
||||
}
|
||||
else {
|
||||
// Capsule
|
||||
node_shader_write_frag(kong, "var h: float = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);");
|
||||
node_shader_write_frag(kong, "dist = length(pa - ba * h);");
|
||||
}
|
||||
node_shader_add_constant(kong, "VP: float4x4", "_view_proj_matrix");
|
||||
node_shader_add_constant(kong, "camera_up: float3", "_camera_up");
|
||||
node_shader_add_constant(kong, "aspect_ratio: float", "_aspect_ratio_window");
|
||||
node_shader_add_constant(kong, "camera_align: float", "_brush_camera_align");
|
||||
|
||||
node_shader_write_frag(kong, "if (constants.camera_align > 0.0) {");
|
||||
node_shader_write_frag(kong, "var vp_up_y: float = (constants.VP * float4(constants.camera_up, 0.0)).y;");
|
||||
node_shader_write_frag(kong, "var ca_scale: float = (1.0 / winp.w) / (vp_up_y * constants.brush_radius);");
|
||||
node_shader_write_frag(kong, "var sa: float2 = sp.xy - constants.inp.xy;");
|
||||
node_shader_write_frag(kong, "sa.x *= constants.aspect_ratio;");
|
||||
node_shader_write_frag(kong, "sa = sa * ca_scale;");
|
||||
// Capsule
|
||||
node_shader_write_frag(kong, "var sb: float2 = constants.inplast.xy - constants.inp.xy;");
|
||||
node_shader_write_frag(kong, "sb.x *= constants.aspect_ratio;");
|
||||
node_shader_write_frag(kong, "sb = sb * ca_scale;");
|
||||
node_shader_write_frag(kong, "var sh: float = clamp(dot(sa, sb) / dot(sb, sb), 0.0, 1.0);");
|
||||
node_shader_write_frag(kong, "dist = length(sa - sb * sh) * 2.0 * constants.brush_radius;");
|
||||
node_shader_write_frag(kong, "}");
|
||||
|
||||
node_shader_write_frag(kong, "else {");
|
||||
// Capsule
|
||||
node_shader_write_frag(kong, "var h: float = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);");
|
||||
node_shader_write_frag(kong, "dist = length(pa - ba * h);");
|
||||
node_shader_write_frag(kong, "}");
|
||||
|
||||
node_shader_write_frag(kong, "if (dist > constants.brush_radius) { discard; }");
|
||||
|
||||
|
||||
@@ -421,6 +421,9 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
node_shader_add_function(kong, str_octahedron_wrap);
|
||||
node_shader_add_texture(kong, "gbuffer0", NULL);
|
||||
node_shader_add_constant(kong, "camera_right: float3", "_camera_right");
|
||||
node_shader_add_constant(kong, "camera_up: float3", "_camera_up");
|
||||
node_shader_add_constant(kong, "camera_align: float", "_brush_camera_align");
|
||||
node_shader_add_constant(kong, "VP: float4x4", "_view_proj_matrix");
|
||||
node_shader_write_frag(kong, "var mn0: float2 = sample_lod(gbuffer0, sampler_linear, constants.inp.xy, 0.0).rg;");
|
||||
node_shader_write_frag(kong, "var mn: float3;");
|
||||
node_shader_write_frag(kong, "mn.z = 1.0 - abs(mn0.x) - abs(mn0.y);");
|
||||
@@ -432,7 +435,16 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
|
||||
node_shader_write_frag(kong, "var mt: float3 = normalize(mr - mn * dot(mr, mn));");
|
||||
node_shader_write_frag(kong, "var mb: float3 = cross(mt, mn);");
|
||||
node_shader_write_frag(kong, "var pa_mask_3d: float3 = input.wposition - winp.xyz;");
|
||||
node_shader_write_frag(kong, "var pa_mask: float2 = float2(dot(pa_mask_3d, mt), dot(pa_mask_3d, mb));");
|
||||
node_shader_write_frag(kong, "var pa_mask: float2;");
|
||||
node_shader_write_frag(kong, "if (constants.camera_align > 0.0) {");
|
||||
node_shader_write_frag(kong, "var mvp_up_y: float = (constants.VP * float4(constants.camera_up, 0.0)).y;");
|
||||
node_shader_write_frag(kong, "var msa: float2 = sp.xy - constants.inp.xy;");
|
||||
node_shader_write_frag(kong, "msa.x *= constants.aspect_ratio;");
|
||||
node_shader_write_frag(kong, "pa_mask = msa * (2.0 / (mvp_up_y * winp.w));");
|
||||
node_shader_write_frag(kong, "}");
|
||||
node_shader_write_frag(kong, "else {");
|
||||
node_shader_write_frag(kong, "pa_mask = float2(dot(pa_mask_3d, mt), dot(pa_mask_3d, mb));");
|
||||
node_shader_write_frag(kong, "}");
|
||||
if (g_context->brush_directional) {
|
||||
node_shader_add_constant(kong, "brush_direction: float3", "_brush_direction");
|
||||
node_shader_write_frag(kong, "if (constants.brush_direction.z == 0.0) { discard; }");
|
||||
|
||||
@@ -354,7 +354,7 @@ node_shader_context_t *sculpt_make_sculpt_run(material_t *data, material_context
|
||||
node_shader_add_constant(kong, "aspect_ratio: float", "_aspect_ratio_window");
|
||||
node_shader_add_constant(kong, "camera_right: float3", "_camera_right");
|
||||
node_shader_add_constant(kong, "camera_up: float3", "_camera_up");
|
||||
node_shader_add_constant(kong, "camera_align: float", "_decal_camera_align");
|
||||
node_shader_add_constant(kong, "camera_align: float", "_brush_camera_align");
|
||||
|
||||
node_shader_write_attrib_frag(kong, "var uvsp: float2 = float2(0.0, 0.0);");
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ void make_texcoord_run(node_shader_t *kong) {
|
||||
node_shader_add_constant(kong, "VP: float4x4", "_view_proj_matrix");
|
||||
node_shader_add_constant(kong, "camera_right: float3", "_camera_right");
|
||||
node_shader_add_constant(kong, "camera_up: float3", "_camera_up");
|
||||
node_shader_add_constant(kong, "camera_align: float", "_decal_camera_align");
|
||||
node_shader_add_constant(kong, "camera_align: float", "_brush_camera_align");
|
||||
|
||||
node_shader_write_attrib_frag(kong, "if (constants.camera_align > 0.0) {");
|
||||
node_shader_write_attrib_frag(kong, "var ca_depth: float = sample_lod(gbufferD, sampler_linear, constants.decal_mask.xy, 0.0).r;");
|
||||
|
||||
@@ -659,6 +659,9 @@ void render_path_paint_draw_cursor(f32 mx, f32 my, f32 radius, f32 tint_r, f32 t
|
||||
vec4_t right = vec4_norm(camera_object_right_world(scene_camera));
|
||||
gpu_set_float3(pipes_cursor_camera_right, right.x, right.y, right.z);
|
||||
gpu_set_float3(pipes_cursor_tint, tint_r, tint_g, tint_b);
|
||||
vec4_t up = vec4_norm(camera_object_up_world(scene_camera));
|
||||
gpu_set_float3(pipes_cursor_camera_up, up.x, up.y, up.z);
|
||||
gpu_set_float(pipes_cursor_camera_align, context_is_brush_camera_align() ? 1.0f : 0.0f);
|
||||
gpu_set_mat4(pipes_cursor_vp, scene_camera->vp);
|
||||
mat4_t inv_vp = mat4_inv(scene_camera->vp);
|
||||
gpu_set_mat4(pipes_cursor_inv_vp, inv_vp);
|
||||
@@ -699,7 +702,7 @@ void render_path_paint_draw_cursor_decal(f32 mx, f32 my, f32 radius, f32 opacity
|
||||
gpu_set_float3(pipes_cursor_decal_camera_right, right.x, right.y, right.z);
|
||||
vec4_t up = vec4_norm(camera_object_up_world(scene_camera));
|
||||
gpu_set_float3(pipes_cursor_decal_camera_up, up.x, up.y, up.z);
|
||||
gpu_set_float(pipes_cursor_decal_camera_align, context_is_decal_camera_align() ? 1.0f : 0.0f);
|
||||
gpu_set_float(pipes_cursor_decal_camera_align, context_is_brush_camera_align() ? 1.0f : 0.0f);
|
||||
f32 opacity = g_context->brush_opacity * brush_nodes_opacity * opacity_scale;
|
||||
gpu_set_float(pipes_cursor_decal_opacity, opacity);
|
||||
f32 angle = (g_context->brush_angle + brush_nodes_angle) * (math_pi() / 180.0);
|
||||
|
||||
@@ -300,7 +300,7 @@ typedef struct context {
|
||||
bool decal_preview;
|
||||
f32 decal_x;
|
||||
f32 decal_y;
|
||||
bool decal_camera_align;
|
||||
bool brush_camera_align;
|
||||
bool select_active; // Select tool
|
||||
bool select_dragging;
|
||||
f32 select_start_x;
|
||||
|
||||
@@ -131,8 +131,8 @@ f32 uniforms_ext_f32_link(object_t *object, material_data_t *mat, char *link) {
|
||||
vec4_t sc = mat4_get_scale(g_context->layer->decal_mat);
|
||||
return sc.z * 0.5;
|
||||
}
|
||||
else if (string_equals(link, "_decal_camera_align")) {
|
||||
return context_is_decal_camera_align() ? 1.0f : 0.0f;
|
||||
else if (string_equals(link, "_brush_camera_align")) {
|
||||
return context_is_brush_camera_align() ? 1.0f : 0.0f;
|
||||
}
|
||||
else if (string_equals(link, "_picker_opacity")) {
|
||||
return g_context->picked_color->opacity;
|
||||
|
||||
Reference in New Issue
Block a user