Skip to content

Commit

Permalink
Add a project setting to control 3D line drawing thickness
Browse files Browse the repository at this point in the history
This setting affects all lines drawn in 3D, including gizmos
in the editor and debug draw options. This can be used to make
debug drawing more visible, particularly when using a high-resolution
viewport.

This relies on hardware support, so it's not available on all platforms
and GPUs. It's also only supported in the Forward+ and Mobile rendering methods.
  • Loading branch information
myaaaaaaaaa authored and Calinou committed Oct 31, 2024
1 parent a308047 commit 250abdd
Show file tree
Hide file tree
Showing 10 changed files with 28 additions and 3 deletions.
7 changes: 7 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,7 @@
</member>
<member name="debug/shapes/paths/geometry_width" type="float" setter="" getter="" default="2.0">
Line width of the curve path geometry, visible when "Visible Paths" is enabled in the Debug menu.
[b]Note:[/b] This setting is only effective in 2D. For 3D, set [member rendering/driver/line_drawing/width] instead.
</member>
<member name="display/display_server/driver" type="String" setter="" getter="">
Sets the driver to be used by the display server. This property can not be edited directly, instead, set the driver using the platform-specific overrides.
Expand Down Expand Up @@ -2434,6 +2435,12 @@
If [code]true[/code], performs a previous depth pass before rendering 3D materials. This increases performance significantly in scenes with high overdraw, when complex materials and lighting are used. However, in scenes with few occluded surfaces, the depth prepass may reduce performance. If your game is viewed from a fixed angle that makes it easy to avoid overdraw (such as top-down or side-scrolling perspective), consider disabling the depth prepass to improve performance. This setting can be changed at run-time to optimize performance depending on the scene currently being viewed.
[b]Note:[/b] Depth prepass is only supported when using the Forward+ or Compatibility rendering method. When using the Mobile rendering method, there is no depth prepass performed.
</member>
<member name="rendering/driver/line_drawing/width" type="float" setter="" getter="" default="1.0">
Render hardware-based 3D lines using the specified value as a thickness (in pixels). Wire thickness does not depend on distance from the camera. This setting affects all lines drawn in 3D, including gizmos in the editor and debug draw options. This can be used to make debug drawing more visible, particularly when using a high-resolution viewport or on hiDPI displays.
[b]Note:[/b] This setting is only implemented in the Forward+ and Mobile rendering methods. In Compatibility, line drawing is always 1 pixel thick.
[b]Note:[/b] This setting relies on hardware capabilities for drawing lines thicker than 1 pixel. Support on Windows and Linux is generally good. Line widths greater than 1 pixel are rarely supported on Android. macOS and iOS do not support line widths greater than 1 pixel.
[b]Note:[/b] This setting has no effect on 2D rendering. For Path2D debug drawing, you can adjust [member debug/shapes/paths/geometry_width] instead.
</member>
<member name="rendering/driver/threads/thread_model" type="int" setter="" getter="" default="1" experimental="This setting has several known bugs which can lead to crashing, especially when using particles or resizing the window. Not recommended for use in production at this stage.">
The thread model to use for rendering. Rendering on a thread may improve performance, but synchronizing to the main thread can cause a bit more jitter.
</member>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p

pipeline_key.framebuffer_format_id = framebuffer_format;
pipeline_key.wireframe = p_params->force_wireframe;
pipeline_key.line_width = line_width;
pipeline_key.ubershader = 0;

const RD::PolygonCullMode cull_mode = shader->get_cull_mode_from_cull_variant(cull_variant);
Expand Down Expand Up @@ -4341,6 +4342,7 @@ void RenderForwardClustered::_mesh_compile_pipelines_for_surface(const SurfacePi
pipeline_key.cull_mode = RD::POLYGON_CULL_DISABLED;
pipeline_key.primitive_type = mesh_storage->mesh_surface_get_primitive(p_surface.mesh_surface);
pipeline_key.wireframe = false;
pipeline_key.line_width = 1;

// Grab the shader and surface used for most passes.
const uint32_t multiview_iterations = multiview_enabled ? 2 : 1;
Expand Down Expand Up @@ -4735,6 +4737,8 @@ void RenderForwardClustered::_update_shader_quality_settings() {
RenderForwardClustered::RenderForwardClustered() {
singleton = this;

line_width = float(GLOBAL_GET("rendering/driver/line_drawing/width"));

/* SCENE SHADER */

{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID render_base_uniform_set;

uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
float line_width = 1.0f;

void _update_render_base_uniform_set();
RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture, const RendererRD::MaterialStorage::Samplers &p_samplers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ void SceneShaderForwardClustered::ShaderData::_create_pipeline(PipelineKey p_pip
"VERSION:", p_pipeline_key.version,
"PASS FLAGS:", p_pipeline_key.color_pass_flags,
"SPEC PACKED #0:", p_pipeline_key.shader_specialization.packed_0,
"WIREFRAME:", p_pipeline_key.wireframe);
"WIREFRAME:", p_pipeline_key.wireframe,
"LINE WIDTH:", p_pipeline_key.line_width);
#endif

// Color pass -> attachment 0: Color/Diffuse, attachment 1: Separate Specular, attachment 2: Motion Vectors
Expand All @@ -298,7 +299,6 @@ void SceneShaderForwardClustered::ShaderData::_create_pipeline(PipelineKey p_pip
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL;
depth_stencil_state.enable_depth_write = depth_draw != DEPTH_DRAW_DISABLED ? true : false;
}
bool depth_pre_pass_enabled = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable"));

RD::RenderPrimitive primitive_rd_table[RS::PRIMITIVE_MAX] = {
RD::RENDER_PRIMITIVE_POINTS,
Expand All @@ -313,6 +313,7 @@ void SceneShaderForwardClustered::ShaderData::_create_pipeline(PipelineKey p_pip
RD::PipelineRasterizationState raster_state;
raster_state.cull_mode = p_pipeline_key.cull_mode;
raster_state.wireframe = wireframe || p_pipeline_key.wireframe;
raster_state.line_width = p_pipeline_key.line_width;

RD::PipelineMultisampleState multisample_state;
multisample_state.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_pipeline_key.framebuffer_format_id, 0);
Expand All @@ -335,6 +336,7 @@ void SceneShaderForwardClustered::ShaderData::_create_pipeline(PipelineKey p_pip
} else {
blend_state = blend_state_color_opaque;

const bool depth_pre_pass_enabled = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable"));
if (depth_pre_pass_enabled) {
// We already have a depth from the depth pre-pass, there is no need to write it again.
// In addition we can use COMPARE_OP_EQUAL instead of COMPARE_OP_LESS_OR_EQUAL.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class SceneShaderForwardClustered {
uint32_t color_pass_flags = 0;
ShaderSpecialization shader_specialization = {};
uint32_t wireframe = false;
float line_width = 1.0f;
uint32_t ubershader = false;

uint32_t hash() const {
Expand All @@ -185,6 +186,7 @@ class SceneShaderForwardClustered {
h = hash_murmur3_one_32(shader_specialization.packed_1, h);
h = hash_murmur3_one_32(shader_specialization.packed_2, h);
h = hash_murmur3_one_32(wireframe, h);
h = hash_murmur3_one_32(line_width, h);
h = hash_murmur3_one_32(ubershader, h);
return hash_fmix32(h);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2240,6 +2240,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr

pipeline_key.framebuffer_format_id = framebuffer_format;
pipeline_key.wireframe = p_params->force_wireframe;
pipeline_key.line_width = line_width;
pipeline_key.render_pass = p_params->subpass;
pipeline_key.ubershader = 0;

Expand Down Expand Up @@ -3148,6 +3149,8 @@ void RenderForwardMobile::_update_shader_quality_settings() {
RenderForwardMobile::RenderForwardMobile() {
singleton = this;

line_width = float(GLOBAL_GET("rendering/driver/line_drawing/width"));

sky.set_texture_format(_render_buffers_get_color_format());

String defines;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ class RenderForwardMobile : public RendererSceneRenderRD {
void _pre_opaque_render(RenderDataRD *p_render_data);

uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
float line_width = 1.0f;

void _update_render_base_uniform_set();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ void SceneShaderForwardMobile::ShaderData::_create_pipeline(PipelineKey p_pipeli
"SPEC PACKED #0:", p_pipeline_key.shader_specialization.packed_0,
"SPEC PACKED #1:", p_pipeline_key.shader_specialization.packed_1,
"RENDER PASS:", p_pipeline_key.render_pass,
"WIREFRAME:", p_pipeline_key.wireframe);
"WIREFRAME:", p_pipeline_key.wireframe,
"LINE WIDTH:", p_pipeline_key.line_width);
#endif

RD::PipelineColorBlendState::Attachment blend_attachment = blend_mode_to_blend_attachment(BlendMode(blend_mode));
Expand Down Expand Up @@ -272,6 +273,7 @@ void SceneShaderForwardMobile::ShaderData::_create_pipeline(PipelineKey p_pipeli
RD::PipelineRasterizationState raster_state;
raster_state.cull_mode = p_pipeline_key.cull_mode;
raster_state.wireframe = wireframe || p_pipeline_key.wireframe;
raster_state.line_width = p_pipeline_key.line_width;

RD::PipelineMultisampleState multisample_state;
multisample_state.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_pipeline_key.framebuffer_format_id, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class SceneShaderForwardMobile {
ShaderVersion version = SHADER_VERSION_MAX;
uint32_t render_pass = 0;
uint32_t wireframe = false;
float line_width = 1.0f;
uint32_t ubershader = false;

uint32_t hash() const {
Expand All @@ -156,6 +157,7 @@ class SceneShaderForwardMobile {
h = hash_murmur3_one_32(version, h);
h = hash_murmur3_one_32(render_pass, h);
h = hash_murmur3_one_32(wireframe, h);
h = hash_murmur3_one_32(line_width, h);
h = hash_murmur3_one_32(ubershader, h);
return hash_fmix32(h);
}
Expand Down
1 change: 1 addition & 0 deletions servers/rendering_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3599,6 +3599,7 @@ void RenderingServer::init() {

GLOBAL_DEF_RST("rendering/driver/depth_prepass/enable", true);
GLOBAL_DEF_RST("rendering/driver/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple");
GLOBAL_DEF_RST(PropertyInfo(Variant::FLOAT, "rendering/driver/line_drawing/width", PROPERTY_HINT_RANGE, "1.0,8.0,0.001"), 1.0);

GLOBAL_DEF_RST("rendering/textures/default_filters/use_nearest_mipmap_filter", false);
GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/textures/default_filters/anisotropic_filtering_level", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Faster),4× (Fast),8× (Average),16× (Slow)")), 2);
Expand Down

0 comments on commit 250abdd

Please sign in to comment.