Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Viewport property to use full floating-point precision in HDR (3.x) #51708

Merged
merged 1 commit into from
Jan 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1267,12 +1267,17 @@
[b]Note:[/b] Generally you should only use this option if you encounter bugs when it is set to [code]false[/code], i.e. there are problems with the default method.
</member>
<member name="rendering/quality/depth/hdr" type="bool" setter="" getter="" default="true">
If [code]true[/code], allocates the main framebuffer with high dynamic range. High dynamic range allows the use of [Color] values greater than 1.
If [code]true[/code], allocates the root [Viewport]'s framebuffer with high dynamic range. High dynamic range allows the use of [Color] values greater than 1.
[b]Note:[/b] Only available on the GLES3 backend.
</member>
<member name="rendering/quality/depth/hdr.mobile" type="bool" setter="" getter="" default="false">
Lower-end override for [member rendering/quality/depth/hdr] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/quality/depth/use_32_bpc_depth" type="bool" setter="" getter="" default="false">
If [code]true[/code], allocates the root [Viewport]'s framebuffer with full floating-point precision (32-bit) instead of half floating-point precision (16-bit). Only effective when [member rendering/quality/depth/hdr] is also enabled.
[b]Note:[/b] Enabling this setting does not improve rendering quality. Using full floating-point precision is slower, and is generally only needed for advanced shaders that require a high level of precision. To reduce banding, enable [member rendering/quality/filters/use_debanding] instead.
[b]Note:[/b] Only available on the GLES3 backend.
</member>
<member name="rendering/quality/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default="&quot;PowerVR,Mali,Adreno,Apple&quot;">
Disables depth pre-pass for some GPU vendors (usually mobile), as their architecture already does this.
</member>
Expand Down
8 changes: 7 additions & 1 deletion doc/classes/Viewport.xml
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,9 @@
<member name="handle_input_locally" type="bool" setter="set_handle_input_locally" getter="is_handling_input_locally" default="true">
</member>
<member name="hdr" type="bool" setter="set_hdr" getter="get_hdr" default="true">
If [code]true[/code], the viewport rendering will receive benefits from High Dynamic Range algorithm. High Dynamic Range allows the viewport to receive values that are outside the 0-1 range. In Godot HDR uses 16 bits, meaning it does not store the full range of a floating point number.
If [code]true[/code], the viewport rendering will receive benefits from High Dynamic Range algorithm. High Dynamic Range allows the viewport to receive values that are outside the 0-1 range. In Godot, HDR uses half floating-point precision (16-bit) by default. To use full floating-point precision (32-bit), enable [member use_32_bpc_depth].
[b]Note:[/b] Requires [member usage] to be set to [constant USAGE_3D] or [constant USAGE_3D_NO_EFFECTS], since HDR is not supported for 2D.
[b]Note:[/b] Only available on the GLES3 backend.
</member>
<member name="keep_3d_linear" type="bool" setter="set_keep_3d_linear" getter="get_keep_3d_linear" default="false">
If [code]true[/code], the result after 3D rendering will not have a linear to sRGB color conversion applied. This is important when the viewport is used as a render target where the result is used as a texture on a 3D object rendered in another viewport. It is also important if the viewport is used to create data that is not color based (noise, heightmaps, pickmaps, etc.). Do not enable this when the viewport is used as a texture on a 2D object or if the viewport is your final output.
Expand Down Expand Up @@ -283,6 +284,11 @@
<member name="usage" type="int" setter="set_usage" getter="get_usage" enum="Viewport.Usage" default="2">
The rendering mode of viewport.
</member>
<member name="use_32_bpc_depth" type="bool" setter="set_use_32_bpc_depth" getter="get_use_32_bpc_depth" default="false">
If [code]true[/code], allocates the viewport's framebuffer with full floating-point precision (32-bit) instead of half floating-point precision (16-bit). Only effective when [member hdr] is also enabled.
[b]Note:[/b] Enabling this setting does not improve rendering quality. Using full floating-point precision is slower, and is generally only needed for advanced shaders that require a high level of precision. To reduce banding, enable [member debanding] instead.
[b]Note:[/b] Only available on the GLES3 backend.
</member>
<member name="world" type="World" setter="set_world" getter="get_world">
The custom [World] which can be used as 3D environment source.
</member>
Expand Down
23 changes: 17 additions & 6 deletions drivers/gles3/rasterizer_storage_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6873,8 +6873,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
GLuint color_type;
Image::Format image_format;

bool hdr = rt->flags[RENDER_TARGET_HDR] && config.framebuffer_half_float_supported;
//hdr = false;
const bool hdr = rt->flags[RENDER_TARGET_HDR] && config.framebuffer_half_float_supported;

if (!hdr || rt->flags[RENDER_TARGET_NO_3D]) {
if (rt->flags[RENDER_TARGET_NO_3D_EFFECTS] && !rt->flags[RENDER_TARGET_TRANSPARENT]) {
Expand All @@ -6891,10 +6890,21 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
image_format = Image::FORMAT_RGBA8;
}
} else {
color_internal_format = GL_RGBA16F;
color_format = GL_RGBA;
color_type = GL_HALF_FLOAT;
image_format = Image::FORMAT_RGBAH;
// HDR enabled.
if (rt->flags[RENDER_TARGET_USE_32_BPC_DEPTH]) {
// 32 bpc. Can be useful for advanced shaders, but should not be used
// for general-purpose rendering as it's slower.
color_internal_format = GL_RGBA32F;
color_format = GL_RGBA;
color_type = GL_FLOAT;
image_format = Image::FORMAT_RGBAF;
} else {
// 16 bpc. This is the default HDR mode.
color_internal_format = GL_RGBA16F;
color_format = GL_RGBA;
color_type = GL_HALF_FLOAT;
image_format = Image::FORMAT_RGBAH;
}
}

{
Expand Down Expand Up @@ -7436,6 +7446,7 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT

switch (p_flag) {
case RENDER_TARGET_HDR:
case RENDER_TARGET_USE_32_BPC_DEPTH:
case RENDER_TARGET_NO_3D:
case RENDER_TARGET_NO_SAMPLING:
case RENDER_TARGET_NO_3D_EFFECTS: {
Expand Down
5 changes: 4 additions & 1 deletion editor/plugins/spatial_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2520,9 +2520,12 @@ void SpatialEditorViewport::_notification(int p_what) {
float sharpen_intensity = ProjectSettings::get_singleton()->get("rendering/quality/filters/sharpen_intensity");
viewport->set_sharpen_intensity(sharpen_intensity);

bool hdr = ProjectSettings::get_singleton()->get("rendering/quality/depth/hdr");
const bool hdr = ProjectSettings::get_singleton()->get("rendering/quality/depth/hdr");
viewport->set_hdr(hdr);

const bool use_32_bpc_depth = ProjectSettings::get_singleton()->get("rendering/quality/depth/use_32_bpc_depth");
viewport->set_use_32_bpc_depth(use_32_bpc_depth);

bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
info_label->set_visible(show_info);

Expand Down
9 changes: 7 additions & 2 deletions scene/main/scene_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2069,12 +2069,17 @@ SceneTree::SceneTree() {
const float sharpen_intensity = GLOBAL_GET("rendering/quality/filters/sharpen_intensity");
root->set_sharpen_intensity(sharpen_intensity);

GLOBAL_DEF_RST("rendering/quality/depth/hdr", true);
GLOBAL_DEF("rendering/quality/depth/hdr", true);
Copy link
Member Author

@Calinou Calinou Aug 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out restarting the editor isn't required to apply HDR changes, at least in my experience. I could notice the added banding immediately as soon as I unchecked HDR in the project settings.

The same applies to the new 32 bpc depth setting.

GLOBAL_DEF("rendering/quality/depth/hdr.mobile", false);

bool hdr = GLOBAL_GET("rendering/quality/depth/hdr");
const bool hdr = GLOBAL_GET("rendering/quality/depth/hdr");
root->set_hdr(hdr);

GLOBAL_DEF("rendering/quality/depth/use_32_bpc_depth", false);

const bool use_32_bpc_depth = GLOBAL_GET("rendering/quality/depth/use_32_bpc_depth");
root->set_use_32_bpc_depth(use_32_bpc_depth);

VS::get_singleton()->scenario_set_reflection_atlas_size(root->get_world()->get_scenario(), ref_atlas_size, ref_atlas_subdiv);

{ //load default fallback environment
Expand Down
20 changes: 19 additions & 1 deletion scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3013,6 +3013,19 @@ bool Viewport::get_hdr() const {
return hdr;
}

void Viewport::set_use_32_bpc_depth(bool p_enable) {
if (use_32_bpc_depth == p_enable) {
return;
}

use_32_bpc_depth = p_enable;
VS::get_singleton()->viewport_set_use_32_bpc_depth(viewport, p_enable);
}

bool Viewport::is_using_32_bpc_depth() const {
return use_32_bpc_depth;
}

void Viewport::set_usage(Usage p_usage) {
usage = p_usage;
VS::get_singleton()->viewport_set_usage(viewport, VS::ViewportUsage(p_usage));
Expand Down Expand Up @@ -3075,7 +3088,7 @@ bool Viewport::is_handling_input_locally() const {
}

void Viewport::_validate_property(PropertyInfo &property) const {
if (VisualServer::get_singleton()->is_low_end() && property.name == "hdr") {
if (VisualServer::get_singleton()->is_low_end() && (property.name == "hdr" || property.name == "use_32_bpc_depth")) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
}
}
Expand Down Expand Up @@ -3138,6 +3151,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_hdr", "enable"), &Viewport::set_hdr);
ClassDB::bind_method(D_METHOD("get_hdr"), &Viewport::get_hdr);

ClassDB::bind_method(D_METHOD("set_use_32_bpc_depth", "enable"), &Viewport::set_use_32_bpc_depth);
ClassDB::bind_method(D_METHOD("get_use_32_bpc_depth"), &Viewport::is_using_32_bpc_depth);

ClassDB::bind_method(D_METHOD("set_usage", "usage"), &Viewport::set_usage);
ClassDB::bind_method(D_METHOD("get_usage"), &Viewport::get_usage);

Expand Down Expand Up @@ -3229,6 +3245,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debanding"), "set_use_debanding", "get_use_debanding");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "sharpen_intensity"), "set_sharpen_intensity", "get_sharpen_intensity");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_32_bpc_depth"), "set_use_32_bpc_depth", "get_use_32_bpc_depth");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_3d_linear"), "set_keep_3d_linear", "get_keep_3d_linear");
ADD_PROPERTY(PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_ENUM, "2D,2D No-Sampling,3D,3D No-Effects"), "set_usage", "get_usage");
Expand Down Expand Up @@ -3389,6 +3406,7 @@ Viewport::Viewport() {
use_debanding = false;
sharpen_intensity = 0.0;
hdr = true;
use_32_bpc_depth = false;

usage = USAGE_3D;
debug_draw = DEBUG_DRAW_DISABLED;
Expand Down
4 changes: 4 additions & 0 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ class Viewport : public Node {
bool use_debanding;
float sharpen_intensity;
bool hdr;
bool use_32_bpc_depth;

Ref<ViewportTexture> default_texture;
Set<ViewportTexture *> viewport_textures;
Expand Down Expand Up @@ -509,6 +510,9 @@ class Viewport : public Node {
void set_hdr(bool p_hdr);
bool get_hdr() const;

void set_use_32_bpc_depth(bool p_enable);
bool is_using_32_bpc_depth() const;

Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const;
Vector2 get_camera_rect_size() const;

Expand Down
1 change: 1 addition & 0 deletions servers/visual/rasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ class RasterizerStorage {
RENDER_TARGET_HDR,
RENDER_TARGET_KEEP_3D_LINEAR,
RENDER_TARGET_DIRECT_TO_SCREEN,
RENDER_TARGET_USE_32_BPC_DEPTH,
RENDER_TARGET_FLAG_MAX
};

Expand Down
1 change: 1 addition & 0 deletions servers/visual/visual_server_raster.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ class VisualServerRaster : public VisualServer {
BIND2(viewport_set_use_debanding, RID, bool)
BIND2(viewport_set_sharpen_intensity, RID, float)
BIND2(viewport_set_hdr, RID, bool)
BIND2(viewport_set_use_32_bpc_depth, RID, bool)
BIND2(viewport_set_usage, RID, ViewportUsage)

BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
Expand Down
7 changes: 7 additions & 0 deletions servers/visual/visual_server_viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,13 @@ void VisualServerViewport::viewport_set_hdr(RID p_viewport, bool p_enabled) {
VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_HDR, p_enabled);
}

void VisualServerViewport::viewport_set_use_32_bpc_depth(RID p_viewport, bool p_enabled) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);

VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_USE_32_BPC_DEPTH, p_enabled);
}

void VisualServerViewport::viewport_set_usage(RID p_viewport, VS::ViewportUsage p_usage) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
Expand Down
1 change: 1 addition & 0 deletions servers/visual/visual_server_viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ class VisualServerViewport {
void viewport_set_use_debanding(RID p_viewport, bool p_debanding);
void viewport_set_sharpen_intensity(RID p_viewport, float p_intensity);
void viewport_set_hdr(RID p_viewport, bool p_enabled);
void viewport_set_use_32_bpc_depth(RID p_viewport, bool p_enabled);
void viewport_set_usage(RID p_viewport, VS::ViewportUsage p_usage);

virtual int viewport_get_render_info(RID p_viewport, VS::ViewportRenderInfo p_info);
Expand Down
1 change: 1 addition & 0 deletions servers/visual/visual_server_wrap_mt.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ class VisualServerWrapMT : public VisualServer {
FUNC2(viewport_set_use_debanding, RID, bool)
FUNC2(viewport_set_sharpen_intensity, RID, float)
FUNC2(viewport_set_hdr, RID, bool)
FUNC2(viewport_set_use_32_bpc_depth, RID, bool)
FUNC2(viewport_set_usage, RID, ViewportUsage)

//this passes directly to avoid stalling, but it's pretty dangerous, so don't call after freeing a viewport
Expand Down
1 change: 1 addition & 0 deletions servers/visual_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ class VisualServer : public Object {
};

virtual void viewport_set_hdr(RID p_viewport, bool p_enabled) = 0;
virtual void viewport_set_use_32_bpc_depth(RID p_viewport, bool p_enabled) = 0;
virtual void viewport_set_usage(RID p_viewport, ViewportUsage p_usage) = 0;

enum ViewportRenderInfo {
Expand Down