Merge pull request #60070 from Calinou/proceduralskymaterial-add-dithering

Add dithering to ProceduralSkyMaterial to combat banding
This commit is contained in:
Rémi Verschelde 2022-04-29 20:28:11 +02:00 committed by GitHub
commit 0e98dbb19c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 1 deletions

View file

@ -12,7 +12,7 @@
</tutorials>
<members>
<member name="dither_strength" type="float" setter="set_dither_strength" getter="get_dither_strength" default="1.0">
Sets the amount of dithering to use. Dithering helps reduce banding that appears from the smooth changes in color in the sky. Use the lowest value possible, higher amounts may add fuzziness to the sky.
The amount of dithering to use. Dithering helps reduce banding that appears from the smooth changes in color in the sky. Use the lowest value possible for your given sky settings, as higher amounts may add fuzziness to the sky.
</member>
<member name="exposure" type="float" setter="set_exposure" getter="get_exposure" default="0.1">
Sets the exposure of the sky. Higher exposure values make the entire sky brighter.

View file

@ -11,6 +11,9 @@
<tutorials>
</tutorials>
<members>
<member name="dither_strength" type="float" setter="set_dither_strength" getter="get_dither_strength" default="1.0">
The amount of dithering to use. Dithering helps reduce banding that appears from the smooth changes in color in the sky. Use the lowest value possible for your given sky settings, as higher amounts may add fuzziness to the sky.
</member>
<member name="ground_bottom_color" type="Color" setter="set_ground_bottom_color" getter="get_ground_bottom_color" default="Color(0.2, 0.169, 0.133, 1)">
Color of the ground at the bottom. Blends with [member ground_horizon_color].
</member>

View file

@ -144,6 +144,15 @@ float ProceduralSkyMaterial::get_sun_curve() const {
return sun_curve;
}
void ProceduralSkyMaterial::set_dither_strength(float p_dither_strength) {
dither_strength = p_dither_strength;
RS::get_singleton()->material_set_param(_get_material(), "dither_strength", dither_strength);
}
float ProceduralSkyMaterial::get_dither_strength() const {
return dither_strength;
}
Shader::Mode ProceduralSkyMaterial::get_shader_mode() const {
return Shader::MODE_SKY;
}
@ -199,6 +208,9 @@ void ProceduralSkyMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSkyMaterial::set_sun_curve);
ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSkyMaterial::get_sun_curve);
ClassDB::bind_method(D_METHOD("set_dither_strength", "strength"), &ProceduralSkyMaterial::set_dither_strength);
ClassDB::bind_method(D_METHOD("get_dither_strength"), &ProceduralSkyMaterial::get_dither_strength);
ADD_GROUP("Sky", "sky_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_sky_top_color", "get_sky_top_color");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_sky_horizon_color", "get_sky_horizon_color");
@ -216,6 +228,9 @@ void ProceduralSkyMaterial::_bind_methods() {
ADD_GROUP("Sun", "sun_");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
ADD_GROUP("", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dither_strength", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_dither_strength", "get_dither_strength");
}
void ProceduralSkyMaterial::cleanup_shader() {
@ -247,6 +262,14 @@ uniform float ground_curve : hint_range(0, 1) = 0.02;
uniform float ground_energy = 1.0;
uniform float sun_angle_max = 30.0;
uniform float sun_curve : hint_range(0, 1) = 0.15;
uniform float dither_strength : hint_range(0, 10) = 1.0;
// From: https://www.shadertoy.com/view/4sfGzS credit to iq
float hash(vec3 p) {
p = fract( p * 0.3183099 + 0.1 );
p *= 17.0;
return fract(p.x * p.y * p.z * (p.x + p.y + p.z));
}
void sky() {
float v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0));
@ -302,6 +325,9 @@ void sky() {
ground *= ground_energy;
COLOR = mix(ground, sky, step(0.0, EYEDIR.y));
// Make optional, eliminates banding.
COLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;
}
)");
}
@ -322,6 +348,7 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() {
set_sun_angle_max(30.0);
set_sun_curve(0.15);
set_dither_strength(1.0);
}
ProceduralSkyMaterial::~ProceduralSkyMaterial() {

View file

@ -52,6 +52,7 @@ private:
float sun_angle_max;
float sun_curve;
float dither_strength;
static Mutex shader_mutex;
static RID shader;
@ -98,6 +99,9 @@ public:
void set_sun_curve(float p_curve);
float get_sun_curve() const;
void set_dither_strength(float p_dither_strength);
float get_dither_strength() const;
virtual Shader::Mode get_shader_mode() const override;
virtual RID get_shader_rid() const override;
virtual RID get_rid() const override;