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 screen space AA option, with FXAA implementation. #37819

Merged
merged 1 commit into from
Apr 12, 2020
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
2 changes: 2 additions & 0 deletions editor/plugins/node_3d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2480,6 +2480,8 @@ void Node3DEditorViewport::_notification(int p_what) {

int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/filters/msaa");
viewport->set_msaa(Viewport::MSAA(msaa_mode));
int ssaa_mode = GLOBAL_GET("rendering/quality/filters/screen_space_aa");
viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode));

bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
if (show_info != info_label->is_visible()) {
Expand Down
4 changes: 4 additions & 0 deletions scene/main/scene_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,10 @@ SceneTree::SceneTree() {
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"));
root->set_msaa(Viewport::MSAA(msaa_mode));

int ssaa_mode = GLOBAL_DEF("rendering/quality/filters/screen_space_aa", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/screen_space_aa", PropertyInfo(Variant::INT, "rendering/quality/filters/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"));
root->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode));

{ //load default fallback environment
//get possible extensions
List<String> exts;
Expand Down
21 changes: 19 additions & 2 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3173,7 +3173,7 @@ int Viewport::gui_get_canvas_sort_index() {

void Viewport::set_msaa(MSAA p_msaa) {

ERR_FAIL_INDEX(p_msaa, 7);
ERR_FAIL_INDEX(p_msaa, MSAA_MAX);
if (msaa == p_msaa)
return;
msaa = p_msaa;
Expand All @@ -3185,6 +3185,19 @@ Viewport::MSAA Viewport::get_msaa() const {
return msaa;
}

void Viewport::set_screen_space_aa(ScreenSpaceAA p_screen_space_aa) {

ERR_FAIL_INDEX(p_screen_space_aa, SCREEN_SPACE_AA_MAX);
if (screen_space_aa == p_screen_space_aa)
return;
screen_space_aa = p_screen_space_aa;
RS::get_singleton()->viewport_set_screen_space_aa(viewport, RS::ViewportScreenSpaceAA(p_screen_space_aa));
}

Viewport::ScreenSpaceAA Viewport::get_screen_space_aa() const {

return screen_space_aa;
}
void Viewport::set_debug_draw(DebugDraw p_debug_draw) {

debug_draw = p_debug_draw;
Expand Down Expand Up @@ -3371,6 +3384,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_msaa", "msaa"), &Viewport::set_msaa);
ClassDB::bind_method(D_METHOD("get_msaa"), &Viewport::get_msaa);

ClassDB::bind_method(D_METHOD("set_screen_space_aa", "screen_space_aa"), &Viewport::set_screen_space_aa);
ClassDB::bind_method(D_METHOD("get_screen_space_aa"), &Viewport::get_screen_space_aa);

ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw);
ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw);

Expand Down Expand Up @@ -3444,6 +3460,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally");
ADD_GROUP("Rendering", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa");
ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"), "set_screen_space_aa", "get_screen_space_aa");
ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw");
ADD_GROUP("Canvas Items", "canvas_item_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapLinear,MipmapNearest"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter");
Expand Down Expand Up @@ -3586,7 +3603,7 @@ Viewport::Viewport() {
gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;

msaa = MSAA_DISABLED;

screen_space_aa = SCREEN_SPACE_AA_DISABLED;
debug_draw = DEBUG_DRAW_DISABLED;

snap_controls_to_pixels = true;
Expand Down
12 changes: 12 additions & 0 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ class Viewport : public Node {
MSAA_4X,
MSAA_8X,
MSAA_16X,
MSAA_MAX
};

enum ScreenSpaceAA {
SCREEN_SPACE_AA_DISABLED,
SCREEN_SPACE_AA_FXAA,
SCREEN_SPACE_AA_MAX
};

enum RenderInfo {
Expand Down Expand Up @@ -272,6 +279,7 @@ class Viewport : public Node {
ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];

MSAA msaa;
ScreenSpaceAA screen_space_aa;
Ref<ViewportTexture> default_texture;
Set<ViewportTexture *> viewport_textures;

Expand Down Expand Up @@ -505,6 +513,9 @@ class Viewport : public Node {
void set_msaa(MSAA p_msaa);
MSAA get_msaa() const;

void set_screen_space_aa(ScreenSpaceAA p_screen_space_aa);
ScreenSpaceAA get_screen_space_aa() const;

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

Expand Down Expand Up @@ -624,6 +635,7 @@ class SubViewport : public Viewport {
VARIANT_ENUM_CAST(SubViewport::UpdateMode);
VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
VARIANT_ENUM_CAST(Viewport::MSAA);
VARIANT_ENUM_CAST(Viewport::ScreenSpaceAA);
VARIANT_ENUM_CAST(Viewport::DebugDraw);
VARIANT_ENUM_CAST(SubViewport::ClearMode);
VARIANT_ENUM_CAST(Viewport::RenderInfo);
Expand Down
2 changes: 1 addition & 1 deletion servers/rendering/rasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ class RasterizerScene {
virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0;

virtual RID render_buffers_create() = 0;
virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa) = 0;
virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) = 0;

virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) = 0;
virtual bool screen_space_roughness_limiter_is_active() const = 0;
Expand Down
4 changes: 4 additions & 0 deletions servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,10 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer,

tonemap.push_constant.use_color_correction = p_settings.use_color_correction;

tonemap.push_constant.use_fxaa = p_settings.use_fxaa;
tonemap.push_constant.pixel_size[0] = 1.0 / p_settings.texture_size.x;
tonemap.push_constant.pixel_size[1] = 1.0 / p_settings.texture_size.y;

RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_color), 0);
Expand Down
7 changes: 7 additions & 0 deletions servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ class RasterizerEffectsRD {
float exposure;
float white;
float auto_exposure_grey;

float pixel_size[2];
uint32_t use_fxaa;
uint32_t pad;
};

/* tonemap actually writes to a framebuffer, which is
Expand Down Expand Up @@ -595,6 +599,9 @@ class RasterizerEffectsRD {

bool use_color_correction = false;
RID color_correction_texture;

bool use_fxaa = false;
Vector2i texture_size;
};

void tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings);
Expand Down
9 changes: 8 additions & 1 deletion servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3439,6 +3439,12 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
tonemap.glow_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK);
}

if (rb->screen_space_aa == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) {
tonemap.use_fxaa = true;
}

tonemap.texture_size = Vector2i(rb->width, rb->height);

if (env) {
tonemap.tonemap_mode = env->tone_mapper;
tonemap.white = env->white;
Expand Down Expand Up @@ -3517,13 +3523,14 @@ RID RasterizerSceneRD::render_buffers_get_ao_texture(RID p_render_buffers) {
return rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0];
}

void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa) {

RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
rb->width = p_width;
rb->height = p_height;
rb->render_target = p_render_target;
rb->msaa = p_msaa;
rb->screen_space_aa = p_screen_space_aa;
_free_render_buffer_data(rb);

{
Expand Down
4 changes: 3 additions & 1 deletion servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,8 @@ class RasterizerSceneRD : public RasterizerScene {
RenderBufferData *data = nullptr;
int width = 0, height = 0;
RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED;
RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED;

RID render_target;

uint64_t auto_exposure_version = 1;
Expand Down Expand Up @@ -1149,7 +1151,7 @@ class RasterizerSceneRD : public RasterizerScene {
GIProbeQuality gi_probe_get_quality() const;

RID render_buffers_create();
void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa);
void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa);

RID render_buffers_get_ao_texture(RID p_render_buffers);
RID render_buffers_get_back_buffer_texture(RID p_render_buffers);
Expand Down
58 changes: 56 additions & 2 deletions servers/rendering/rasterizer_rd/shaders/tonemap.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ layout(push_constant, binding = 1, std430) uniform Params {
float exposure;
float white;
float auto_exposure_grey;

vec2 pixel_size;
bool use_fxaa;
uint pad;
}
params;

Expand Down Expand Up @@ -255,16 +259,63 @@ vec3 apply_color_correction(vec3 color, sampler3D correction_tex) {
return texture(correction_tex, color).rgb;
}

vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {

const float FXAA_REDUCE_MIN = (1.0 / 128.0);
const float FXAA_REDUCE_MUL = (1.0 / 8.0);
const float FXAA_SPAN_MAX = 8.0;

vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure;
vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure;
vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure;
vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure;
vec3 rgbM = color;
vec3 luma = vec3(0.299, 0.587, 0.114);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
float lumaM = dot(rgbM, luma);
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));

vec2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));

float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
(0.25 * FXAA_REDUCE_MUL),
FXAA_REDUCE_MIN);

float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
dir * rcpDirMin)) *
params.pixel_size;

vec3 rgbA = 0.5 * (textureLod(source_color, uv_interp + dir * (1.0 / 3.0 - 0.5), 0.0).xyz * exposure + textureLod(source_color, uv_interp + dir * (2.0 / 3.0 - 0.5), 0.0).xyz) * exposure;
vec3 rgbB = rgbA * 0.5 + 0.25 * (textureLod(source_color, uv_interp + dir * -0.5, 0.0).xyz * exposure +
textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz * exposure);

float lumaB = dot(rgbB, luma);
if ((lumaB < lumaMin) || (lumaB > lumaMax))
return rgbA;
else
return rgbB;
}

void main() {
vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb;

// Exposure

float exposure = params.exposure;

if (params.use_auto_exposure) {
color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.auto_exposure_grey;
exposure *= 1.0 / (texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.auto_exposure_grey);
}

color *= params.exposure;
color *= exposure;

// Early Tonemap & SRGB Conversion

Expand All @@ -274,6 +325,9 @@ void main() {
color.rgb = mix(color.rgb, glow, params.glow_intensity);
}

if (params.use_fxaa) {
color = do_fxaa(color, exposure, uv_interp);
}
color = apply_tonemapping(color, params.white);

color = linear_to_srgb(color); // regular linear -> SRGB conversion
Expand Down
1 change: 1 addition & 0 deletions servers/rendering/rendering_server_raster.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ class RenderingServerRaster : public RenderingServer {
BIND2(viewport_set_shadow_atlas_size, RID, int)
BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
BIND2(viewport_set_msaa, RID, ViewportMSAA)
BIND2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)

BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw)
Expand Down
19 changes: 16 additions & 3 deletions servers/rendering/rendering_server_viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) {
//wants to draw 3D but there is no render buffer, create
p_viewport->render_buffers = RSG::scene_render->render_buffers_create();
RSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa);
RSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa);
}

RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor);
Expand Down Expand Up @@ -506,7 +506,7 @@ void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int
RSG::scene_render->free(viewport->render_buffers);
viewport->render_buffers = RID();
} else {
RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa);
RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa);
}
}
}
Expand Down Expand Up @@ -736,7 +736,20 @@ void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA
}
viewport->msaa = p_msaa;
if (viewport->render_buffers.is_valid()) {
RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa);
RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa);
}
}

void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);

if (viewport->screen_space_aa == p_mode) {
return;
}
viewport->screen_space_aa = p_mode;
if (viewport->render_buffers.is_valid()) {
RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode);
}
}

Expand Down
4 changes: 4 additions & 0 deletions servers/rendering/rendering_server_viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class RenderingServerViewport {
RID render_buffers;

RS::ViewportMSAA msaa;
RS::ViewportScreenSpaceAA screen_space_aa;

DisplayServer::WindowID viewport_to_screen;
Rect2 viewport_to_screen_rect;
Expand Down Expand Up @@ -130,6 +131,8 @@ class RenderingServerViewport {

debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
msaa = RS::VIEWPORT_MSAA_DISABLED;
screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED;

for (int i = 0; i < RS::VIEWPORT_RENDER_INFO_MAX; i++) {
render_info[i] = 0;
}
Expand Down Expand Up @@ -206,6 +209,7 @@ class RenderingServerViewport {
void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);

void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa);
void viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode);

virtual int viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info);
virtual void viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw);
Expand Down
1 change: 1 addition & 0 deletions servers/rendering/rendering_server_wrap_mt.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ class RenderingServerWrapMT : public RenderingServer {
FUNC2(viewport_set_shadow_atlas_size, RID, int)
FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
FUNC2(viewport_set_msaa, RID, ViewportMSAA)
FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)

//this passes directly to avoid stalling, but it's pretty dangerous, so don't call after freeing a viewport
virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) {
Expand Down
6 changes: 6 additions & 0 deletions servers/rendering_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,12 @@ class RenderingServer : public Object {

virtual void viewport_set_msaa(RID p_viewport, ViewportMSAA p_msaa) = 0;

enum ViewportScreenSpaceAA {
VIEWPORT_SCREEN_SPACE_AA_DISABLED,
VIEWPORT_SCREEN_SPACE_AA_FXAA,
};
virtual void viewport_set_screen_space_aa(RID p_viewport, ViewportScreenSpaceAA p_mode) = 0;

enum ViewportRenderInfo {

VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME,
Expand Down