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

Implemented dither noise #492

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
26 changes: 23 additions & 3 deletions src/graphic/Fast3D/gfx_direct3d_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,23 @@ void gfx_direct3d_common_build_shader(char buf[8192], size_t& len, size_t& num_f
append_line(buf, &len, " float noise_scale;");
append_line(buf, &len, "}");

append_line(buf, &len, "float3 colorDither(in float _noise_val, in float3 _color)");
append_line(buf, &len, "{");
append_line(buf, &len, " float3 _noise = float3(_noise_val, _noise_val, _noise_val);");
append_line(buf, &len, " float3 threshold = 7.0 / 255.0 * (_noise - 0.5);");
append_line(buf, &len, " _color = clamp(_color + threshold, 0.0, 1.0);");
append_line(buf, &len, " _color.rgb = round(_color.rgb * 32.0) / 32.0;");
append_line(buf, &len, " return _color;");
append_line(buf, &len, "}");

append_line(buf, &len, "float alphaDither(in float _noise, in float _alpha)");
append_line(buf, &len, "{");
append_line(buf, &len, " float threshold = 7.0 / 255.0 * (_noise - 0.5);");
append_line(buf, &len, " _alpha = clamp(_alpha + threshold, 0.0, 1.0);");
append_line(buf, &len, " _alpha = round(_alpha * 32.0) / 32.0;");
append_line(buf, &len, " return _alpha;");
append_line(buf, &len, "}");

append_line(buf, &len, "float random(in float3 value) {");
append_line(buf, &len, " float random = dot(value, float3(12.9898, 78.233, 37.719));");
append_line(buf, &len, " return frac(sin(random) * 143758.5453);");
Expand Down Expand Up @@ -428,14 +445,17 @@ void gfx_direct3d_common_build_shader(char buf[8192], size_t& len, size_t& num_f
}

if (cc_features.opt_alpha && cc_features.opt_noise) {
append_line(buf, &len, " float2 coords = screenSpace.xy * noise_scale;");
append_line(buf, &len,
" texel.a *= round(saturate(random(float3(floor(coords), noise_frame)) + texel.a - 0.5));");
" texel.a = alphaDither(random(float3(floor(screenSpace.xy * noise_scale), "
"float(noise_frame))), texel.a);");
}

if (cc_features.opt_alpha) {
append_line(buf, &len, " float alphaValue = texel.a;");

if (cc_features.opt_alpha_threshold) {
append_line(buf, &len, " if (texel.a < 8.0 / 256.0) discard;");
append_line(buf, &len, "alphaValue = clamp(alphaValue, 0.0, 1.0);");
append_line(buf, &len, "if (alphaValue < alphaTestValue) discard;");
}
if (cc_features.opt_invisible) {
append_line(buf, &len, " texel.a = 0.0;");
Expand Down
30 changes: 27 additions & 3 deletions src/graphic/Fast3D/gfx_opengl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,22 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
append_line(fs_buf, &fs_len, "uniform int frame_count;");
append_line(fs_buf, &fs_len, "uniform float noise_scale;");

append_line(fs_buf, &fs_len, "vec3 colorDither(float _noise_val, vec3 _color)");
append_line(fs_buf, &fs_len, "{");
append_line(fs_buf, &fs_len, " vec3 _noise = vec3(_noise_val, _noise_val, _noise_val);");
append_line(fs_buf, &fs_len, " vec3 threshold = 7.0 / 255.0 * (_noise - 0.5);");
append_line(fs_buf, &fs_len, " _color = clamp(_color + threshold, 0.0, 1.0);");
append_line(fs_buf, &fs_len, " _color.rgb = round(_color.rgb * 32.0) / 32.0;");
append_line(fs_buf, &fs_len, " return _color;");
append_line(fs_buf, &fs_len, "}");
append_line(fs_buf, &fs_len, "float alphaDither(float _noise, float _alpha)");
append_line(fs_buf, &fs_len, "{");
append_line(fs_buf, &fs_len, " float threshold = 7.0 / 255.0 * (_noise - 0.5);");
append_line(fs_buf, &fs_len, " _alpha = clamp(_alpha + threshold, 0.0, 1.0);");
append_line(fs_buf, &fs_len, " _alpha = round(_alpha * 32.0) / 32.0;");
append_line(fs_buf, &fs_len, " return _alpha;");
append_line(fs_buf, &fs_len, "}");

append_line(fs_buf, &fs_len, "float random(in vec3 value) {");
append_line(fs_buf, &fs_len, " float random = dot(sin(value), vec3(12.9898, 78.233, 37.719));");
append_line(fs_buf, &fs_len, " return fract(sin(random) * 143758.5453);");
Expand Down Expand Up @@ -554,9 +570,13 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
}

if (cc_features.opt_alpha && cc_features.opt_noise) {
append_line(
fs_buf, &fs_len,
"texel.a = alphaDither(random(vec3(floor(gl_FragCoord.xy * noise_scale), float(frame_count))), texel.a);");
} else if (cc_features.opt_noise) {
append_line(fs_buf, &fs_len,
"texel.a *= floor(clamp(random(vec3(floor(gl_FragCoord.xy * noise_scale), float(frame_count))) + "
"texel.a, 0.0, 1.0));");
"texel.rgb = colorDither(random(vec3(floor(gl_FragCoord.xy * noise_scale), float(frame_count))), "
"texel.rgb);");
}
Comment on lines 583 to 591
Copy link
Contributor

Choose a reason for hiding this comment

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

At least from what I can see in MM, it is possible for aplha dithering and color dithering to be applied at the same time. This if / if else does not allow that currently.

We may even need to split opt_noise into two values, or something so that we can control which is used.


if (cc_features.opt_grayscale) {
Expand All @@ -566,8 +586,12 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
}

if (cc_features.opt_alpha) {
append_line(fs_buf, &fs_len, "float cvg = 1.0;");
KiritoDv marked this conversation as resolved.
Show resolved Hide resolved
append_line(fs_buf, &fs_len, "float alphaValue = texel.a;");

if (cc_features.opt_alpha_threshold) {
append_line(fs_buf, &fs_len, "if (texel.a < 8.0 / 256.0) discard;");
append_line(fs_buf, &fs_len, "alphaValue = clamp(alphaValue, 0.0, 1.0);");
append_line(fs_buf, &fs_len, "if (alphaValue < alphaTestValue) discard;");
KiritoDv marked this conversation as resolved.
Show resolved Hide resolved
}
if (cc_features.opt_invisible) {
append_line(fs_buf, &fs_len, "texel.a = 0.0;");
Expand Down
15 changes: 11 additions & 4 deletions src/graphic/Fast3D/gfx_pc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1412,7 +1412,10 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo
(g_rdp.other_mode_l & (3 << 16)) == (G_BL_1MA << 16);
bool use_fog = (g_rdp.other_mode_l >> 30) == G_BL_CLR_FOG;
bool texture_edge = (g_rdp.other_mode_l & CVG_X_ALPHA) == CVG_X_ALPHA;
bool use_noise = (g_rdp.other_mode_l & (3U << G_MDSFT_ALPHACOMPARE)) == G_AC_DITHER;
bool use_noise = ((g_rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)) < G_CYC_COPY) &&
((g_rdp.other_mode_l & (3U << G_MDSFT_ALPHACOMPARE)) == G_AC_DITHER ||
(g_rdp.other_mode_h & (3U << G_MDSFT_ALPHADITHER)) == G_AD_NOISE ||
(g_rdp.other_mode_h & (3U << G_MDSFT_COLORDITHER)) == G_CD_NOISE);
bool use_2cyc = (g_rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)) == G_CYC_2CYCLE;
bool alpha_threshold = (g_rdp.other_mode_l & (3U << G_MDSFT_ALPHACOMPARE)) == G_AC_THRESHOLD;
bool invisible =
Expand Down Expand Up @@ -3283,11 +3286,15 @@ bool gfx_set_fb_handler_custom(Gfx** cmd0) {
return false;
}

float gfx_calculate_noise_scale() {
return ((float)gfx_current_dimensions.height / SCREEN_HEIGHT) * 0.5f;
KiritoDv marked this conversation as resolved.
Show resolved Hide resolved
}

bool gfx_reset_fb_handler_custom(Gfx** cmd0) {
gfx_flush();
fbActive = 0;
gfx_rapi->start_draw_to_framebuffer(game_renders_to_framebuffer ? game_framebuffer : 0,
(float)gfx_current_dimensions.height / gfx_native_dimensions.height);
gfx_calculate_noise_scale());
return false;
}

Expand Down Expand Up @@ -3886,7 +3893,7 @@ void gfx_run(Gfx* commands, const std::unordered_map<Mtx*, MtxF>& mtx_replacemen
!game_renders_to_framebuffer);
gfx_rapi->start_frame();
gfx_rapi->start_draw_to_framebuffer(game_renders_to_framebuffer ? game_framebuffer : 0,
(float)gfx_current_dimensions.height / gfx_native_dimensions.height);
gfx_calculate_noise_scale());
gfx_rapi->clear_framebuffer();
g_rdp.viewport_or_scissor_changed = true;
rendering_state.viewport = {};
Expand Down Expand Up @@ -4015,7 +4022,7 @@ void gfx_copy_framebuffer(int fb_dst_id, int fb_src_id, bool copyOnce, bool* has
}

void gfx_reset_framebuffer() {
gfx_rapi->start_draw_to_framebuffer(0, (float)gfx_current_dimensions.height / gfx_native_dimensions.height);
gfx_rapi->start_draw_to_framebuffer(0, gfx_calculate_noise_scale());
gfx_rapi->clear_framebuffer();
}

Expand Down
Loading