Added option to viewport to keep linear color

This commit is contained in:
Bastiaan Olij 2018-04-30 22:30:11 +10:00
parent 2bf71d0eea
commit 6f7fefa489
11 changed files with 61 additions and 9 deletions

View File

@ -212,6 +212,9 @@
<member name="hdr" type="bool" setter="set_hdr" getter="get_hdr">
If [code]true[/code] the viewport rendering will receive benefits from High Dynamic Range algorithm. Default value: [code]true[/code].
</member>
<member name="keep_3d_linear" type="bool" setter="set_keep_3d_linear" getter="get_keep_3d_linear">
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.
</member>
<member name="msaa" type="int" setter="set_msaa" getter="get_msaa" enum="Viewport.MSAA">
The multisample anti-aliasing mode. Default value: [code]MSAA_DISABLED[/code].
</member>

View File

@ -3906,6 +3906,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_FILMIC);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_ACES);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINDHART_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_REINHARDT);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::KEEP_3D_LINEAR, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR]);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, env->auto_exposure);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_FILTER_BICUBIC, env->glow_bicubic_upscale);

View File

@ -258,9 +258,13 @@ void main() {
#endif
#ifdef KEEP_3D_LINEAR
// leave color as is...
#else
//regular Linear -> SRGB conversion
vec3 a = vec3(0.055);
color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308)));
#endif
#if defined(USING_GLOW)
glow = mix( (vec3(1.0)+a)*pow(glow,vec3(1.0/2.4))-a , 12.92*glow , lessThan(glow,vec3(0.0031308)));

View File

@ -2477,6 +2477,16 @@ bool Viewport::is_3d_disabled() const {
return disable_3d;
}
void Viewport::set_keep_3d_linear(bool p_keep_3d_linear) {
keep_3d_linear = p_keep_3d_linear;
VS::get_singleton()->viewport_set_keep_3d_linear(viewport, keep_3d_linear);
}
bool Viewport::get_keep_3d_linear() const {
return keep_3d_linear;
}
Variant Viewport::gui_get_drag_data() const {
return gui.drag_data;
}
@ -2660,6 +2670,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_disable_3d", "disable"), &Viewport::set_disable_3d);
ClassDB::bind_method(D_METHOD("is_3d_disabled"), &Viewport::is_3d_disabled);
ClassDB::bind_method(D_METHOD("set_keep_3d_linear", "keep_3d_linear"), &Viewport::set_keep_3d_linear);
ClassDB::bind_method(D_METHOD("get_keep_3d_linear"), &Viewport::get_keep_3d_linear);
ClassDB::bind_method(D_METHOD("_gui_show_tooltip"), &Viewport::_gui_show_tooltip);
ClassDB::bind_method(D_METHOD("_gui_remove_focus"), &Viewport::_gui_remove_focus);
ClassDB::bind_method(D_METHOD("_post_gui_grab_click_focus"), &Viewport::_post_gui_grab_click_focus);
@ -2684,6 +2697,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x"), "set_msaa", "get_msaa");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr");
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");
ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw");
ADD_GROUP("Render Target", "render_target_");
@ -2806,6 +2820,7 @@ Viewport::Viewport() {
disable_input = false;
disable_3d = false;
keep_3d_linear = false;
//window tooltip
gui.tooltip_timer = -1;

View File

@ -226,6 +226,7 @@ private:
void _update_global_transform();
bool disable_3d;
bool keep_3d_linear;
UpdateMode update_mode;
RID texture_rid;
uint32_t texture_flags;
@ -433,6 +434,9 @@ public:
void set_disable_3d(bool p_disable);
bool is_3d_disabled() const;
void set_keep_3d_linear(bool p_keep_3d_linear);
bool get_keep_3d_linear() const;
void set_attach_to_screen_rect(const Rect2 &p_rect);
Rect2 get_attach_to_screen_rect() const;

View File

@ -514,6 +514,7 @@ public:
RENDER_TARGET_NO_3D,
RENDER_TARGET_NO_SAMPLING,
RENDER_TARGET_HDR,
RENDER_TARGET_KEEP_3D_LINEAR,
RENDER_TARGET_FLAG_MAX
};

View File

@ -451,6 +451,7 @@ public:
BIND2(viewport_set_hide_canvas, RID, bool)
BIND2(viewport_set_disable_environment, RID, bool)
BIND2(viewport_set_disable_3d, RID, bool)
BIND2(viewport_set_keep_3d_linear, RID, bool)
BIND2(viewport_attach_camera, RID, RID)
BIND2(viewport_set_scenario, RID, RID)

View File

@ -178,11 +178,14 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
VSG::rasterizer->restore_render_target();
if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer > scenario_canvas_max_layer) {
Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
if (can_draw_3d) {
VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
} else {
if (!can_draw_3d) {
VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
} else if (p_viewport->use_arvr && arvr_interface.is_valid()) {
VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
} else {
VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
}
scenario_draw_canvas_bg = false;
}
@ -210,11 +213,14 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
i++;
if (scenario_draw_canvas_bg && E->key().layer >= scenario_canvas_max_layer) {
Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
if (can_draw_3d) {
VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
} else {
if (!can_draw_3d) {
VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
} else if (p_viewport->use_arvr && arvr_interface.is_valid()) {
VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
} else {
VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
}
scenario_draw_canvas_bg = false;
@ -222,11 +228,14 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
}
if (scenario_draw_canvas_bg) {
Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
if (can_draw_3d) {
VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
} else {
if (!can_draw_3d) {
VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
} else if (p_viewport->use_arvr && arvr_interface.is_valid()) {
VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
} else {
VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
}
scenario_draw_canvas_bg = false;
@ -453,6 +462,15 @@ void VisualServerViewport::viewport_set_disable_3d(RID p_viewport, bool p_disabl
//this should be just for disabling rendering of 3D, to actually disable it, set usage
}
void VisualServerViewport::viewport_set_keep_3d_linear(RID p_viewport, bool p_keep_3d_linear) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->keep_3d_linear = p_keep_3d_linear;
VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR, p_keep_3d_linear);
}
void VisualServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) {
Viewport *viewport = viewport_owner.getornull(p_viewport);

View File

@ -64,6 +64,7 @@ public:
bool disable_environment;
bool disable_3d;
bool disable_3d_by_usage;
bool keep_3d_linear;
RID shadow_atlas;
int shadow_atlas_size;
@ -110,6 +111,7 @@ public:
shadow_atlas_size = 0;
disable_3d = false;
disable_3d_by_usage = false;
keep_3d_linear = false;
debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED;
for (int i = 0; i < VS::VIEWPORT_RENDER_INFO_MAX; i++) {
render_info[i] = 0;
@ -164,6 +166,7 @@ public:
void viewport_set_hide_canvas(RID p_viewport, bool p_hide);
void viewport_set_disable_environment(RID p_viewport, bool p_disable);
void viewport_set_disable_3d(RID p_viewport, bool p_disable);
void viewport_set_keep_3d_linear(RID p_viewport, bool p_keep_3d_linear);
void viewport_attach_camera(RID p_viewport, RID p_camera);
void viewport_set_scenario(RID p_viewport, RID p_scenario);

View File

@ -378,6 +378,7 @@ public:
FUNC2(viewport_set_hide_canvas, RID, bool)
FUNC2(viewport_set_disable_environment, RID, bool)
FUNC2(viewport_set_disable_3d, RID, bool)
FUNC2(viewport_set_keep_3d_linear, RID, bool)
FUNC2(viewport_attach_camera, RID, RID)
FUNC2(viewport_set_scenario, RID, RID)

View File

@ -592,6 +592,7 @@ public:
virtual void viewport_set_hide_canvas(RID p_viewport, bool p_hide) = 0;
virtual void viewport_set_disable_environment(RID p_viewport, bool p_disable) = 0;
virtual void viewport_set_disable_3d(RID p_viewport, bool p_disable) = 0;
virtual void viewport_set_keep_3d_linear(RID p_viewport, bool p_disable) = 0;
virtual void viewport_attach_camera(RID p_viewport, RID p_camera) = 0;
virtual void viewport_set_scenario(RID p_viewport, RID p_scenario) = 0;