Implement Color Clamping (#1753)

* q

* Adjust wrap spot, add directx

* Update comments
This commit is contained in:
Rozelette 2022-10-13 10:15:18 -05:00 committed by GitHub
parent 42a5f46e5e
commit 03c3eef193
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 1 deletions

View File

@ -253,6 +253,13 @@ void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_f
append_line(buf, &len, "[RootSignature(RS)]");
}
append_line(buf, &len, "float4 PSMain(PSInput input, float4 screenSpace : SV_Position) : SV_TARGET {");
// Reference approach to color wrapping as per GLideN64
// Return wrapped value of x in interval [low, high)
// Mod implementation of GLSL sourced from https://registry.khronos.org/OpenGL-Refpages/gl4/html/mod.xhtml
append_line(buf, &len, "#define MOD(x, y) ((x) - (y) * floor((x)/(y)))");
append_line(buf, &len, "#define WRAP(x, low, high) MOD((x)-(low), (high)-(low)) + (low)");
for (int i = 0; i < 2; i++) {
if (cc_features.used_textures[i]) {
len += sprintf(buf + len, " float2 tc%d = input.uv%d;\r\n", i, i);
@ -294,11 +301,18 @@ void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_f
append_formula(buf, &len, cc_features.c[c], cc_features.do_single[c][0], cc_features.do_multiply[c][0], cc_features.do_mix[c][0], cc_features.opt_alpha, false, cc_features.opt_alpha);
}
append_line(buf, &len, ";");
if (c == 0) {
append_str(buf, &len, "texel = WRAP(texel, -1.01, 1.01);");
}
}
if (cc_features.opt_texture_edge && cc_features.opt_alpha) {
append_line(buf, &len, " if (texel.a > 0.19) texel.a = 1.0; else discard;");
}
append_str(buf, &len, "texel = WRAP(texel, -0.51, 1.51);");
append_str(buf, &len, "texel = clamp(texel, 0.0, 1.0);");
// TODO discard if alpha is 0?
if (cc_features.opt_fog) {
if (cc_features.opt_alpha) {

View File

@ -414,6 +414,10 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
append_line(fs_buf, &fs_len, "void main() {");
// Reference approach to color wrapping as per GLideN64
// Return wrapped value of x in interval [low, high)
append_line(fs_buf, &fs_len, "#define WRAP(x, low, high) mod((x)-(low), (high)-(low)) + (low)");
for (int i = 0; i < 2; i++) {
if (cc_features.used_textures[i]) {
bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1];
@ -448,7 +452,14 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
append_formula(fs_buf, &fs_len, cc_features.c[c], cc_features.do_single[c][0], cc_features.do_multiply[c][0], cc_features.do_mix[c][0], cc_features.opt_alpha, false, cc_features.opt_alpha);
}
append_line(fs_buf, &fs_len, ";");
if (c == 0) {
append_str(fs_buf, &fs_len, "texel = WRAP(texel, -1.01, 1.01);");
}
}
append_str(fs_buf, &fs_len, "texel = WRAP(texel, -0.51, 1.51);");
append_str(fs_buf, &fs_len, "texel = clamp(texel, 0.0, 1.0);");
// TODO discard if alpha is 0?
if (cc_features.opt_fog)
{