diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 73916fc83..f6daa8da6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -914,10 +914,13 @@ consvar_t cv_glbatching = CVAR_INIT ("gr_batching", "On", 0, CV_OnOff, NULL); CV_PossibleValue_t glpalettedepth_cons_t[] = {{16, "16 bits"}, {24, "24 bits"}, {0, NULL}}; void CV_glpaletterendering_OnChange(void); void CV_glpalettedepth_OnChange(void); +void CV_gllightdithering_OnChange(void); consvar_t cv_glpaletterendering = CVAR_INIT ("gr_paletteshader", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_glpaletterendering_OnChange); consvar_t cv_glpalettedepth = CVAR_INIT ("gr_palettedepth", "16 bits", CV_SAVE|CV_CALL, glpalettedepth_cons_t, CV_glpalettedepth_OnChange); +consvar_t cv_gllightdither = CVAR_INIT ("gr_lightdithering", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_gllightdithering_OnChange); + // Isolates rendering to one of the top level portals. // (Stencil cutting of the portal is also disabled) // Use gr_printportals to find the number to use. @@ -958,7 +961,15 @@ void CV_glpaletterendering_OnChange(void) } } -void CV_glpalettedepth_OnChange(void); +void CV_gllightdithering_OnChange(void) +{ + ONLY_IF_GL_LOADED + if (gl_shadersavailable) + { + HWR_CompileShaders(); + } +} + void CV_glpalettedepth_OnChange(void) { ONLY_IF_GL_LOADED @@ -1024,6 +1035,8 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glpaletterendering); CV_RegisterVar(&cv_glpalettedepth); + CV_RegisterVar(&cv_gllightdither); + COM_AddCommand("gr_printportals", Command_Glprintportals_f); CV_RegisterVar(&cv_gldebugportal); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index a32966f54..becec7e94 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -113,6 +113,7 @@ extern consvar_t cv_glsolvetjoin, cv_glpolytile, cv_glpolyshape; extern consvar_t cv_glbatching; extern consvar_t cv_glpaletterendering; extern consvar_t cv_glpalettedepth; +extern consvar_t cv_gllightdither; extern consvar_t cv_gldebugportal; extern consvar_t cv_glskydebug; diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index 2a4d71750..1763761b9 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -81,6 +81,7 @@ static shadertarget_t gl_shadertargets[NUMSHADERTARGETS]; #define MODEL_LIGHTING_DEFINE "#define SRB2_MODEL_LIGHTING" #define PALETTE_RENDERING_DEFINE "#define SRB2_PALETTE_RENDERING" +#define LIGHT_DITHERING_DEFINE "#define SRB2_LIGHT_DITHER" // Initialize shader variables and the backend's shader system. Load the base shaders. // Returns false if shaders cannot be used. @@ -284,6 +285,9 @@ static char *HWR_PreprocessShader(char *original) if (cv_glpaletterendering.value) ADD_TO_LEN(PALETTE_RENDERING_DEFINE) + if (cv_gllightdither.value) + ADD_TO_LEN(LIGHT_DITHERING_DEFINE) + #undef ADD_TO_LEN #define VERSION_PART "#version " @@ -329,6 +333,9 @@ static char *HWR_PreprocessShader(char *original) if (cv_glpaletterendering.value) WRITE_DEFINE(PALETTE_RENDERING_DEFINE) + if (cv_gllightdither.value) + WRITE_DEFINE(LIGHT_DITHERING_DEFINE) + #undef WRITE_DEFINE // Write a #line directive, so compiler errors will report line numbers from the diff --git a/src/hardware/hw_shaders.h b/src/hardware/hw_shaders.h index 06d3bc602..cadd9944c 100644 --- a/src/hardware/hw_shaders.h +++ b/src/hardware/hw_shaders.h @@ -76,15 +76,53 @@ // // Include GLSL_FLOOR_FUDGES or GLSL_WALL_FUDGES or define the fudges in shaders that use this macro. +#define GLSL_DOOM_COLORMAP_DITHER \ + "float baseValue = max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \ + "float endResolutionx = scr_resolution.x;\n" \ + "float endResolutiony = scr_resolution.y;\n" \ + "if (scr_resolution.x > 1280.0) {\n" \ + "endResolutionx = scr_resolution.x * 0.5;\n" \ + "}\n" \ + "if (scr_resolution.y > 720.0) {\n" \ + "endResolutiony = scr_resolution.y * 0.5;\n" \ + "}\n" \ + "float zFactor = clamp((z - 192.0) / (6144.0 - 192.0), 0.0, 1.0);\n" \ + "int scaleFactor = int(mix(1.0, 8.0, zFactor));\n" \ + "endResolutionx = endResolutionx * scaleFactor;\n" \ + "endResolutiony = endResolutiony * scaleFactor;\n" \ + "vec2 normalizedPosition = position * vec2(endResolutionx / scr_resolution.x, endResolutiony / scr_resolution.y);\n" \ + "int x = int(mod(normalizedPosition.x, 4.0));\n" \ + "int y = int(mod(normalizedPosition.y, 4.0));\n" \ + "float bayerMatrix[4*4] = float[4*4](\n" \ + "0.0, 8.0, 2.0, 10.0,\n" \ + "12.0, 4.0, 14.0, 6.0,\n" \ + "3.0, 11.0, 1.0, 9.0,\n" \ + "15.0, 7.0, 13.0, 5.0\n" \ + ");\n" \ + "#ifdef SRB2_PALETTE_RENDERING\n" \ + "float threshold = (1.0 - pow(zFactor, 2.0)) * (bayerMatrix[y*4 + x] / 11.0);\n" \ + "#else\n" \ + "float threshold = (1.0 - pow(zFactor, 2.0)) * (bayerMatrix[y*4 + x] / 16.0);\n" \ + "#endif\n" \ + "return mix(baseValue + threshold - 0.5 / 16.0, baseValue, zFactor);\n" + +#define GLSL_DOOM_COLORMAP_NODITHER \ + "return max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \ + #define GLSL_DOOM_COLORMAP \ - "float R_DoomColormap(float light, float z)\n" \ + "uniform vec2 scr_resolution;\n" \ + "float R_DoomColormap(float light, float z, vec2 position)\n" \ "{\n" \ "float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \ "float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \ "float startmap = (15.0 - lightnum) * 4.0;\n" \ "float scale = 160.0 / (lightz + 1.0);\n" \ "float cap = (155.0 - light) * 0.26;\n" \ - "return max(startmap * STARTMAP_FUDGE - scale * 0.5 * SCALE_FUDGE, cap);\n" \ + "#ifdef SRB2_LIGHT_DITHER\n" \ + GLSL_DOOM_COLORMAP_DITHER \ + "#else\n" \ + GLSL_DOOM_COLORMAP_NODITHER \ + "#endif\n" \ "}\n" // lighting cap adjustment: // first num (155.0), increase to make it start to go dark sooner @@ -94,7 +132,7 @@ "float R_DoomLightingEquation(float light)\n" \ "{\n" \ "float z = gl_FragCoord.z / gl_FragCoord.w;\n" \ - "float colormap = floor(R_DoomColormap(light, z)) + 0.5;\n" \ + "float colormap = floor(R_DoomColormap(light, z, gl_FragCoord.xy)) + 0.5;\n" \ "return clamp(colormap, 0.0, 31.0) / 32.0;\n" \ "}\n" @@ -157,7 +195,7 @@ #define GLSL_PALETTE_RENDERING \ "float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \ "float z = gl_FragCoord.z / gl_FragCoord.w;\n" \ - "float light_y = clamp(floor(R_DoomColormap(final_lighting, z)), 0.0, 31.0);\n" \ + "float light_y = clamp(floor(R_DoomColormap(final_lighting, z, gl_FragCoord.xy)), 0.0, 31.0);\n" \ "vec2 lighttable_coord = vec2((tex_pal_idx + 0.5) / 256.0, (light_y + 0.5) / 32.0);\n" \ "vec4 final_color = texture2D(lighttable_tex, lighttable_coord);\n" \ "final_color.a = texel.a * poly_color.a;\n" \ diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6da624800..fbb7ed1cd 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -654,6 +654,8 @@ typedef enum // misc. gluniform_leveltime, + gluniform_scr_resolution, + gluniform_max, } gluniform_t; @@ -1935,6 +1937,8 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF UNIFORM_1(shader->uniforms[gluniform_leveltime], shader_leveltime, pglUniform1f); + UNIFORM_2(shader->uniforms[gluniform_scr_resolution], (GLfloat)vid.width, (GLfloat)vid.height, pglUniform2f); + #undef UNIFORM_1 #undef UNIFORM_2 #undef UNIFORM_3 @@ -2050,24 +2054,26 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i) shader->uniforms[gluniform_brightmap] = GETUNI("brightmap"); // lighting - shader->uniforms[gluniform_poly_color] = GETUNI("poly_color"); - shader->uniforms[gluniform_tint_color] = GETUNI("tint_color"); - shader->uniforms[gluniform_fade_color] = GETUNI("fade_color"); - shader->uniforms[gluniform_lighting] = GETUNI("lighting"); - shader->uniforms[gluniform_fade_start] = GETUNI("fade_start"); - shader->uniforms[gluniform_fade_end] = GETUNI("fade_end"); - shader->uniforms[gluniform_newfade] = GETUNI("newfade"); - shader->uniforms[gluniform_light_dir] = GETUNI("light_dir"); - shader->uniforms[gluniform_light_contrast] = GETUNI("light_contrast"); - shader->uniforms[gluniform_light_backlight] = GETUNI("light_backlight"); + shader->uniforms[gluniform_poly_color] = GETUNI("poly_color"); + shader->uniforms[gluniform_tint_color] = GETUNI("tint_color"); + shader->uniforms[gluniform_fade_color] = GETUNI("fade_color"); + shader->uniforms[gluniform_lighting] = GETUNI("lighting"); + shader->uniforms[gluniform_fade_start] = GETUNI("fade_start"); + shader->uniforms[gluniform_fade_end] = GETUNI("fade_end"); + shader->uniforms[gluniform_newfade] = GETUNI("newfade"); + shader->uniforms[gluniform_light_dir] = GETUNI("light_dir"); + shader->uniforms[gluniform_light_contrast] = GETUNI("light_contrast"); + shader->uniforms[gluniform_light_backlight] = GETUNI("light_backlight"); // palette rendering - shader->uniforms[gluniform_palette_tex] = GETUNI("palette_tex"); - shader->uniforms[gluniform_palette_lookup_tex] = GETUNI("palette_lookup_tex"); - shader->uniforms[gluniform_lighttable_tex] = GETUNI("lighttable_tex"); + shader->uniforms[gluniform_palette_tex] = GETUNI("palette_tex"); + shader->uniforms[gluniform_palette_lookup_tex] = GETUNI("palette_lookup_tex"); + shader->uniforms[gluniform_lighttable_tex] = GETUNI("lighttable_tex"); + + shader->uniforms[gluniform_scr_resolution] = GETUNI("scr_resolution"); // misc. (custom shaders) - shader->uniforms[gluniform_leveltime] = GETUNI("leveltime"); + shader->uniforms[gluniform_leveltime] = GETUNI("leveltime"); #undef GETUNI