Merge pull request #45594 from JFonS/improve_3d_grid
3D editor grid improvements
This commit is contained in:
commit
b24c24f64b
|
@ -5266,6 +5266,42 @@ void Node3DEditor::_init_indicators() {
|
|||
origin_points.push_back(axis * -1048576);
|
||||
}
|
||||
|
||||
Ref<Shader> grid_shader = memnew(Shader);
|
||||
grid_shader->set_code(
|
||||
"\n"
|
||||
"shader_type spatial; \n"
|
||||
"render_mode unshaded; \n"
|
||||
"uniform bool orthogonal; \n"
|
||||
"uniform float grid_size; \n"
|
||||
"\n"
|
||||
"void vertex() { \n"
|
||||
" // From FLAG_SRGB_VERTEX_COLOR \n"
|
||||
" if (!OUTPUT_IS_SRGB) { \n"
|
||||
" COLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045))); \n"
|
||||
" } \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void fragment() { \n"
|
||||
" ALBEDO = COLOR.rgb; \n"
|
||||
" vec3 dir = orthogonal ? -vec3(0, 0, 1) : VIEW; \n"
|
||||
" float angle_fade = abs(dot(dir, NORMAL)); \n"
|
||||
" angle_fade = smoothstep(0.05, 0.2, angle_fade); \n"
|
||||
" \n"
|
||||
" vec3 world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz; \n"
|
||||
" vec3 world_normal = (CAMERA_MATRIX * vec4(NORMAL, 0.0)).xyz; \n"
|
||||
" vec3 camera_world_pos = CAMERA_MATRIX[3].xyz; \n"
|
||||
" vec3 camera_world_pos_on_plane = camera_world_pos * (1.0 - world_normal); \n"
|
||||
" float dist_fade = 1.0 - (distance(world_pos, camera_world_pos_on_plane) / grid_size); \n"
|
||||
" dist_fade = smoothstep(0.02, 0.3, dist_fade); \n"
|
||||
" \n"
|
||||
" ALPHA = COLOR.a * dist_fade * angle_fade; \n"
|
||||
"}");
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
grid_mat[i].instance();
|
||||
grid_mat[i]->set_shader(grid_shader);
|
||||
}
|
||||
|
||||
grid_enable[0] = EditorSettings::get_singleton()->get("editors/3d/grid_xy_plane");
|
||||
grid_enable[1] = EditorSettings::get_singleton()->get("editors/3d/grid_yz_plane");
|
||||
grid_enable[2] = EditorSettings::get_singleton()->get("editors/3d/grid_xz_plane");
|
||||
|
@ -5470,32 +5506,33 @@ void Node3DEditor::_init_indicators() {
|
|||
|
||||
Ref<Shader> rotate_shader = memnew(Shader);
|
||||
|
||||
rotate_shader->set_code("\n"
|
||||
"shader_type spatial; \n"
|
||||
"render_mode unshaded, depth_test_disabled; \n"
|
||||
"uniform vec4 albedo; \n"
|
||||
"\n"
|
||||
"mat3 orthonormalize(mat3 m) { \n"
|
||||
" vec3 x = normalize(m[0]); \n"
|
||||
" vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
|
||||
" vec3 z = m[2] - x * dot(x, m[2]); \n"
|
||||
" z = normalize(z - y * (dot(y,m[2]))); \n"
|
||||
" return mat3(x,y,z); \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void vertex() { \n"
|
||||
" mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
|
||||
" vec3 n = mv * VERTEX; \n"
|
||||
" float orientation = dot(vec3(0,0,-1),n); \n"
|
||||
" if (orientation <= 0.005) { \n"
|
||||
" VERTEX += NORMAL*0.02; \n"
|
||||
" } \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void fragment() { \n"
|
||||
" ALBEDO = albedo.rgb; \n"
|
||||
" ALPHA = albedo.a; \n"
|
||||
"}");
|
||||
rotate_shader->set_code(
|
||||
"\n"
|
||||
"shader_type spatial; \n"
|
||||
"render_mode unshaded, depth_test_disabled; \n"
|
||||
"uniform vec4 albedo; \n"
|
||||
"\n"
|
||||
"mat3 orthonormalize(mat3 m) { \n"
|
||||
" vec3 x = normalize(m[0]); \n"
|
||||
" vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
|
||||
" vec3 z = m[2] - x * dot(x, m[2]); \n"
|
||||
" z = normalize(z - y * (dot(y,m[2]))); \n"
|
||||
" return mat3(x,y,z); \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void vertex() { \n"
|
||||
" mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
|
||||
" vec3 n = mv * VERTEX; \n"
|
||||
" float orientation = dot(vec3(0,0,-1),n); \n"
|
||||
" if (orientation <= 0.005) { \n"
|
||||
" VERTEX += NORMAL*0.02; \n"
|
||||
" } \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void fragment() { \n"
|
||||
" ALBEDO = albedo.rgb; \n"
|
||||
" ALPHA = albedo.a; \n"
|
||||
"}");
|
||||
|
||||
Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial);
|
||||
rotate_mat->set_render_priority(Material::RENDER_PRIORITY_MAX);
|
||||
|
@ -5515,33 +5552,34 @@ void Node3DEditor::_init_indicators() {
|
|||
Ref<ShaderMaterial> border_mat = rotate_mat->duplicate();
|
||||
|
||||
Ref<Shader> border_shader = memnew(Shader);
|
||||
border_shader->set_code("\n"
|
||||
"shader_type spatial; \n"
|
||||
"render_mode unshaded, depth_test_disabled; \n"
|
||||
"uniform vec4 albedo; \n"
|
||||
"\n"
|
||||
"mat3 orthonormalize(mat3 m) { \n"
|
||||
" vec3 x = normalize(m[0]); \n"
|
||||
" vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
|
||||
" vec3 z = m[2] - x * dot(x, m[2]); \n"
|
||||
" z = normalize(z - y * (dot(y,m[2]))); \n"
|
||||
" return mat3(x,y,z); \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void vertex() { \n"
|
||||
" mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
|
||||
" mv = inverse(mv); \n"
|
||||
" VERTEX += NORMAL*0.008; \n"
|
||||
" vec3 camera_dir_local = mv * vec3(0,0,1); \n"
|
||||
" vec3 camera_up_local = mv * vec3(0,1,0); \n"
|
||||
" mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n"
|
||||
" VERTEX = rotation_matrix * VERTEX; \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void fragment() { \n"
|
||||
" ALBEDO = albedo.rgb; \n"
|
||||
" ALPHA = albedo.a; \n"
|
||||
"}");
|
||||
border_shader->set_code(
|
||||
"\n"
|
||||
"shader_type spatial; \n"
|
||||
"render_mode unshaded, depth_test_disabled; \n"
|
||||
"uniform vec4 albedo; \n"
|
||||
"\n"
|
||||
"mat3 orthonormalize(mat3 m) { \n"
|
||||
" vec3 x = normalize(m[0]); \n"
|
||||
" vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
|
||||
" vec3 z = m[2] - x * dot(x, m[2]); \n"
|
||||
" z = normalize(z - y * (dot(y,m[2]))); \n"
|
||||
" return mat3(x,y,z); \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void vertex() { \n"
|
||||
" mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
|
||||
" mv = inverse(mv); \n"
|
||||
" VERTEX += NORMAL*0.008; \n"
|
||||
" vec3 camera_dir_local = mv * vec3(0,0,1); \n"
|
||||
" vec3 camera_up_local = mv * vec3(0,1,0); \n"
|
||||
" mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n"
|
||||
" VERTEX = rotation_matrix * VERTEX; \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
"void fragment() { \n"
|
||||
" ALBEDO = albedo.rgb; \n"
|
||||
" ALPHA = albedo.a; \n"
|
||||
"}");
|
||||
|
||||
border_mat->set_shader(border_shader);
|
||||
border_mat->set_shader_param("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0));
|
||||
|
@ -5704,8 +5742,11 @@ void Node3DEditor::_init_grid() {
|
|||
return; // Camera3D is invalid, don't draw the grid.
|
||||
}
|
||||
|
||||
bool orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL;
|
||||
|
||||
Vector<Color> grid_colors[3];
|
||||
Vector<Vector3> grid_points[3];
|
||||
Vector<Vector3> grid_normals[3];
|
||||
|
||||
Color primary_grid_color = EditorSettings::get_singleton()->get("editors/3d/primary_grid_color");
|
||||
Color secondary_grid_color = EditorSettings::get_singleton()->get("editors/3d/secondary_grid_color");
|
||||
|
@ -5741,10 +5782,26 @@ void Node3DEditor::_init_grid() {
|
|||
int b = (a + 1) % 3;
|
||||
int c = (a + 2) % 3;
|
||||
|
||||
real_t division_level = Math::log(Math::abs(camera_position[c])) / Math::log((double)primary_grid_steps) + division_level_bias;
|
||||
division_level = CLAMP(division_level, division_level_min, division_level_max);
|
||||
real_t division_level_floored = Math::floor(division_level);
|
||||
real_t division_level_decimals = division_level - division_level_floored;
|
||||
Vector3 normal;
|
||||
normal[c] = 1.0;
|
||||
|
||||
real_t camera_distance = Math::abs(camera_position[c]);
|
||||
|
||||
if (orthogonal) {
|
||||
camera_distance = camera->get_size() / 2.0;
|
||||
Vector3 camera_direction = -camera->get_global_transform().get_basis().get_axis(2);
|
||||
Plane grid_plane = Plane(Vector3(), normal);
|
||||
Vector3 intersection;
|
||||
if (grid_plane.intersects_ray(camera_position, camera_direction, &intersection)) {
|
||||
camera_position = intersection;
|
||||
}
|
||||
}
|
||||
|
||||
real_t division_level = Math::log(Math::abs(camera_distance)) / Math::log((double)primary_grid_steps) + division_level_bias;
|
||||
|
||||
real_t clamped_division_level = CLAMP(division_level, division_level_min, division_level_max);
|
||||
real_t division_level_floored = Math::floor(clamped_division_level);
|
||||
real_t division_level_decimals = clamped_division_level - division_level_floored;
|
||||
|
||||
real_t small_step_size = Math::pow(primary_grid_steps, division_level_floored);
|
||||
real_t large_step_size = small_step_size * primary_grid_steps;
|
||||
|
@ -5756,6 +5813,15 @@ void Node3DEditor::_init_grid() {
|
|||
real_t bgn_b = center_b - grid_size * small_step_size;
|
||||
real_t end_b = center_b + grid_size * small_step_size;
|
||||
|
||||
real_t fade_size = Math::pow(primary_grid_steps, division_level - 1.0);
|
||||
real_t min_fade_size = Math::pow(primary_grid_steps, float(division_level_min));
|
||||
real_t max_fade_size = Math::pow(primary_grid_steps, float(division_level_max));
|
||||
fade_size = CLAMP(fade_size, min_fade_size, max_fade_size);
|
||||
|
||||
real_t grid_fade_size = (grid_size - primary_grid_steps) * fade_size;
|
||||
grid_mat[c]->set_shader_param("grid_size", grid_fade_size);
|
||||
grid_mat[c]->set_shader_param("orthogonal", orthogonal);
|
||||
|
||||
// In each iteration of this loop, draw one line in each direction (so two lines per loop, in each if statement).
|
||||
for (int i = -grid_size; i <= grid_size; i++) {
|
||||
Color line_color;
|
||||
|
@ -5766,11 +5832,6 @@ void Node3DEditor::_init_grid() {
|
|||
line_color = secondary_grid_color;
|
||||
line_color.a = line_color.a * (1 - division_level_decimals);
|
||||
}
|
||||
// Makes lines farther from the center fade out.
|
||||
// Due to limitations of lines, any that come near the camera have full opacity always.
|
||||
// This should eventually be replaced by some kind of "distance fade" system, outside of this function.
|
||||
// But the effect is still somewhat convincing...
|
||||
line_color.a *= 1 - (1 - division_level_decimals * 0.9) * (Math::abs(i / (float)grid_size));
|
||||
|
||||
real_t position_a = center_a + i * small_step_size;
|
||||
real_t position_b = center_b + i * small_step_size;
|
||||
|
@ -5787,6 +5848,8 @@ void Node3DEditor::_init_grid() {
|
|||
grid_points[c].push_back(line_end);
|
||||
grid_colors[c].push_back(line_color);
|
||||
grid_colors[c].push_back(line_color);
|
||||
grid_normals[c].push_back(normal);
|
||||
grid_normals[c].push_back(normal);
|
||||
}
|
||||
|
||||
if (!(origin_enabled && Math::is_zero_approx(position_b))) {
|
||||
|
@ -5800,6 +5863,8 @@ void Node3DEditor::_init_grid() {
|
|||
grid_points[c].push_back(line_end);
|
||||
grid_colors[c].push_back(line_color);
|
||||
grid_colors[c].push_back(line_color);
|
||||
grid_normals[c].push_back(normal);
|
||||
grid_normals[c].push_back(normal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5809,8 +5874,9 @@ void Node3DEditor::_init_grid() {
|
|||
d.resize(RS::ARRAY_MAX);
|
||||
d[RenderingServer::ARRAY_VERTEX] = grid_points[c];
|
||||
d[RenderingServer::ARRAY_COLOR] = grid_colors[c];
|
||||
d[RenderingServer::ARRAY_NORMAL] = grid_normals[c];
|
||||
RenderingServer::get_singleton()->mesh_add_surface_from_arrays(grid[c], RenderingServer::PRIMITIVE_LINES, d);
|
||||
RenderingServer::get_singleton()->mesh_surface_set_material(grid[c], 0, indicator_mat->get_rid());
|
||||
RenderingServer::get_singleton()->mesh_surface_set_material(grid[c], 0, grid_mat[c]->get_rid());
|
||||
grid_instance[c] = RenderingServer::get_singleton()->instance_create2(grid[c], get_tree()->get_root()->get_world_3d()->get_scenario());
|
||||
|
||||
// Yes, the end of this line is supposed to be a.
|
||||
|
|
|
@ -590,7 +590,6 @@ private:
|
|||
/////
|
||||
|
||||
ToolMode tool_mode;
|
||||
bool orthogonal;
|
||||
|
||||
RenderingServer::ScenarioDebugMode scenario_debug;
|
||||
|
||||
|
@ -623,6 +622,7 @@ private:
|
|||
RID cursor_mesh;
|
||||
RID cursor_instance;
|
||||
Ref<StandardMaterial3D> indicator_mat;
|
||||
Ref<ShaderMaterial> grid_mat[3];
|
||||
Ref<StandardMaterial3D> cursor_material;
|
||||
|
||||
// Scene drag and drop support
|
||||
|
|
|
@ -735,7 +735,7 @@ void BaseMaterial3D::_update_shader() {
|
|||
|
||||
if (flags[FLAG_SRGB_VERTEX_COLOR]) {
|
||||
code += "\tif (!OUTPUT_IS_SRGB) {\n";
|
||||
code += "\t\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n";
|
||||
code += "\t\tCOLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045)));\n";
|
||||
code += "\t}\n";
|
||||
}
|
||||
if (flags[FLAG_USE_POINT_SIZE]) {
|
||||
|
|
Loading…
Reference in New Issue