mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-23 04:12:42 +00:00
added r_alphaToCoverageMipBoost and did some other changes to A2C
- r_alphaToCoverageMipBoost scales the alpha value based on the current texture LoD this prevents the "fading with distance" effect - mip 0 dimensions are tested to decide whether contrast boosting around 0.5 is enabled this is to deal with high r_picmip configs - improved algorithm for excellent sharpness and minimized temporal artefacts - GLSL 4.00 is required for the GL3 backend to use A2C (for textureQueryLod)
This commit is contained in:
parent
180a0187b7
commit
7412c4b373
6 changed files with 64 additions and 18 deletions
|
@ -4,10 +4,18 @@ See the end of this file for known issues.
|
|||
|
||||
DD Mmm 20 - 1.53
|
||||
|
||||
add: r_alphaToCoverageMipBoost <0.0 to 0.5> (default: 0.125) boosts the alpha value of higher mip levels
|
||||
with A2C enabled, it prevents alpha-tested surfaces from fading (too much) in the distance
|
||||
|
||||
chg: with r_backend GL3, alpha to coverage now requires GLSL 4.00 at a minimum
|
||||
|
||||
fix: with alpha to coverage enabled, high r_picmip values should longer cause
|
||||
alpha-tested surfaces to become transparent in the distance (e.g. q3wcp14 corridor floors)
|
||||
|
||||
fix: with r_backend GL3, shader uniforms caching could break with fog-only shaders
|
||||
|
||||
fix: with r_backend D3D11, partial clears incorrectly affected entire render targets
|
||||
this was creating black views in CPMA multi-view with r_fastsky 1
|
||||
example: black views in CPMA multi-view with r_fastsky 1
|
||||
|
||||
|
||||
01 Jun 20 - 1.52
|
||||
|
|
|
@ -66,7 +66,7 @@ cbuffer PixelShaderBuffer
|
|||
float invGamma;
|
||||
float invBrightness;
|
||||
float noiseScale;
|
||||
float dummy;
|
||||
float alphaBoost;
|
||||
};
|
||||
|
||||
Texture2D texture0 : register(t0);
|
||||
|
@ -101,10 +101,12 @@ float CorrectAlpha(float threshold, float alpha, float2 tc)
|
|||
{
|
||||
float w, h;
|
||||
texture0.GetDimensions(w, h);
|
||||
float dx = max(abs(ddx(tc.x * w)), 0.001);
|
||||
float dy = max(abs(ddy(tc.y * h)), 0.001);
|
||||
float dxy = max(dx, dy); // apply the smallest boost
|
||||
float scale = max(1.0 / dxy, 1.0);
|
||||
if(min(w, h) <= 8.0)
|
||||
return alpha >= threshold ? 1.0 : 0.0;
|
||||
alpha *= 1.0 + alphaBoost * texture0.CalculateLevelOfDetail(sampler0, tc);
|
||||
float2 dtc = fwidth(tc * float2(w, h));
|
||||
float recScale = max(0.25 * (dtc.x + dtc.y), 1.0 / 16384.0);
|
||||
float scale = max(1.0 / recScale, 1.0);
|
||||
float ac = threshold + (alpha - threshold) * scale;
|
||||
|
||||
return ac;
|
||||
|
@ -132,10 +134,16 @@ float4 ps_main(VOut input) : SV_Target0
|
|||
#endif
|
||||
|
||||
#ifdef CNQ3_A2C
|
||||
// a < 0.5
|
||||
// - a > -0.5
|
||||
// 1.0 - a > 0.5
|
||||
// 1.0 - a >= NextFloatAbove(0.5)
|
||||
// 1.0 - a >= asfloat(0x3F000001)
|
||||
// asfloat(0x3F000001) is 0.5 * 1.0000001192092896
|
||||
if(alphaTest == 1)
|
||||
r.a = r.a > 0.0 ? 1.0 : 0.0;
|
||||
else if(alphaTest == 2)
|
||||
r.a = CorrectAlpha(0.5, 1.0 - r.a, input.texCoords);
|
||||
r.a = CorrectAlpha(asfloat(0x3F000001), 1.0 - r.a, input.texCoords);
|
||||
else if(alphaTest == 3)
|
||||
r.a = CorrectAlpha(0.5, r.a, input.texCoords);
|
||||
#else
|
||||
|
|
|
@ -188,7 +188,7 @@ struct GenericPSData
|
|||
float invGamma;
|
||||
float invBrightness;
|
||||
float noiseScale;
|
||||
float dummy;
|
||||
float alphaBoost;
|
||||
};
|
||||
|
||||
struct DepthFadeVSData
|
||||
|
@ -735,6 +735,7 @@ static void UploadPendingShaderData()
|
|||
psData.invGamma = 1.0f / r_gamma->value;
|
||||
psData.invBrightness = 1.0f / r_brightness->value;
|
||||
psData.noiseScale = backEnd.projection2D ? 0.0f : r_ditherStrength->value;
|
||||
psData.alphaBoost = r_alphaToCoverageMipBoost->value;
|
||||
ResetShaderData(pipeline->vertexBuffer, &vsData, sizeof(vsData));
|
||||
ResetShaderData(pipeline->pixelBuffer, &psData, sizeof(psData));
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ Current info:
|
|||
- fancy mip-map generations requires:
|
||||
- OpenGL 4.3 (or equivalent extensions)
|
||||
- GLSL 4.30
|
||||
- alpha to coverage requires GLSL 4.00
|
||||
|
||||
Vertex and index data streaming notes:
|
||||
- everyone: persistent coherent buffer mapping is the best option whenever available
|
||||
|
@ -149,7 +150,8 @@ enum GenericUniform
|
|||
GU_PROJECTION,
|
||||
GU_CLIP_PLANE,
|
||||
GU_ALPHA_TEX,
|
||||
GU_GAMMA_BRIGHT_NOISE_SEED, // @NOTE: not always defined
|
||||
GU_GAMMA_BRIGHT_NOISE_SEED, // only defined when dithering is enabled
|
||||
GU_A2C_ALPHA_BOOST, // only defined when alpha to coverage is enabled
|
||||
GU_COUNT
|
||||
};
|
||||
|
||||
|
@ -322,6 +324,9 @@ static const char* generic_fs =
|
|||
"#define noiseScale gammaBrightNoiseSeed.z\n"
|
||||
"#define seed gammaBrightNoiseSeed.w\n"
|
||||
"#endif\n"
|
||||
"#ifdef CNQ3_A2C\n"
|
||||
"uniform float alphaBoost;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"centroid in vec2 texCoords1FS;\n"
|
||||
"centroid in vec2 texCoords2FS;\n"
|
||||
|
@ -354,10 +359,12 @@ static const char* generic_fs =
|
|||
"float CorrectAlpha(float threshold, float alpha, vec2 tc)\n"
|
||||
"{\n"
|
||||
" vec2 size = vec2(textureSize(texture1, 0));\n"
|
||||
" float dx = max(abs(dFdx(tc.x * size.x)), 0.001);\n"
|
||||
" float dy = max(abs(dFdy(tc.y * size.y)), 0.001);\n"
|
||||
" float dxy = max(dx, dy); // apply the smallest boost\n"
|
||||
" float scale = max(1.0 / dxy, 1.0);\n"
|
||||
" if(min(size.x, size.y) <= 8.0)\n"
|
||||
" return alpha >= threshold ? 1.0 : 0.0;\n"
|
||||
" alpha *= 1.0 + alphaBoost * textureQueryLod(texture1, tc).x;"
|
||||
" vec2 dtc = fwidth(tc * size);\n"
|
||||
" float recScale = max(0.25 * (dtc.x + dtc.y), 1.0 / 16384.0);\n"
|
||||
" float scale = max(1.0 / recScale, 1.0);\n"
|
||||
" float ac = threshold + (alpha - threshold) * scale;\n"
|
||||
"\n"
|
||||
" return ac;\n"
|
||||
|
@ -388,7 +395,7 @@ static const char* generic_fs =
|
|||
" if(alphaTest == uint(1))\n"
|
||||
" r.a = r.a > 0.0 ? 1.0 : 0.0;\n"
|
||||
" if(alphaTest == uint(2))\n"
|
||||
" r.a = CorrectAlpha(0.5, 1.0 - r.a, texCoords1FS);\n"
|
||||
" r.a = CorrectAlpha(uintBitsToFloat(0x3F000001), 1.0 - r.a, texCoords1FS);\n"
|
||||
" else if(alphaTest == uint(3))\n"
|
||||
" r.a = CorrectAlpha(0.5, r.a, texCoords1FS);\n"
|
||||
"#else\n"
|
||||
|
@ -798,12 +805,21 @@ static const char* GetShaderTypeName(GLenum shaderType)
|
|||
|
||||
static qbool CreateShader(GLuint* shaderPtr, PipelineId pipelineId, GLenum shaderType, const char* shaderSource, const char* debugName)
|
||||
{
|
||||
// A2C now requires GLSL 4.00 for textureQueryLod
|
||||
const qbool enableA2C =
|
||||
pipelineId == PID_GENERIC &&
|
||||
shaderType == GL_FRAGMENT_SHADER &&
|
||||
glInfo.alphaToCoverageSupport;
|
||||
const qbool enableDithering =
|
||||
pipelineId == PID_GENERIC &&
|
||||
shaderType == GL_FRAGMENT_SHADER &&
|
||||
r_dither->integer;
|
||||
const char* sourceArray[] =
|
||||
{
|
||||
shaderType == GL_COMPUTE_SHADER ? "#version 430\n" : "#version 140\n",
|
||||
shaderType == GL_COMPUTE_SHADER ? "#version 430\n" : (enableA2C ? "#version 400\n" : "#version 140\n"),
|
||||
"\n",
|
||||
pipelineId == PID_GENERIC && glInfo.alphaToCoverageSupport && shaderType == GL_FRAGMENT_SHADER ? "#define CNQ3_A2C 1\n" : "#define CNQ3_A2C 0\n",
|
||||
pipelineId == PID_GENERIC && r_dither->integer && shaderType == GL_FRAGMENT_SHADER ? "#define CNQ3_DITHER 1\n" : "#define CNQ3_DITHER 0\n",
|
||||
enableA2C ? "#define CNQ3_A2C 1\n" : "#define CNQ3_A2C 0\n",
|
||||
enableDithering ? "#define CNQ3_DITHER 1\n" : "#define CNQ3_DITHER 0\n",
|
||||
shaderSource
|
||||
};
|
||||
|
||||
|
@ -1904,6 +1920,7 @@ static void Init()
|
|||
gl.pipelines[PID_GENERIC].uniformNames[GU_CLIP_PLANE] = "clipPlane";
|
||||
gl.pipelines[PID_GENERIC].uniformNames[GU_ALPHA_TEX] = "alphaTex";
|
||||
gl.pipelines[PID_GENERIC].uniformNames[GU_GAMMA_BRIGHT_NOISE_SEED] = "gammaBrightNoiseSeed";
|
||||
gl.pipelines[PID_GENERIC].uniformNames[GU_A2C_ALPHA_BOOST] = "alphaBoost";
|
||||
|
||||
gl.pipelines[PID_DYNAMIC_LIGHT].arrayBuffers[VB_POSITION].enabled = qtrue;
|
||||
gl.pipelines[PID_DYNAMIC_LIGHT].arrayBuffers[VB_POSITION].attribName = "position";
|
||||
|
@ -1964,7 +1981,8 @@ static void Init()
|
|||
{
|
||||
pipeline->uniformLocations[i] = glGetUniformLocation(pipeline->program.program, pipeline->uniformNames[i]);
|
||||
#if defined(_DEBUG)
|
||||
if(!(r_dither->integer == 0 && p == PID_GENERIC && i == GU_GAMMA_BRIGHT_NOISE_SEED))
|
||||
if(!(r_dither->integer == 0 && p == PID_GENERIC && i == GU_GAMMA_BRIGHT_NOISE_SEED) &&
|
||||
!(r_alphaToCoverage->integer == 0 && p == PID_GENERIC && i == GU_A2C_ALPHA_BOOST))
|
||||
{
|
||||
assert(pipeline->uniformLocations[i] != -1);
|
||||
}
|
||||
|
@ -2168,6 +2186,12 @@ static void DrawGeneric()
|
|||
(float)rand() / (float)RAND_MAX);
|
||||
pipeline->uniformsDirty[GU_GAMMA_BRIGHT_NOISE_SEED] = qfalse;
|
||||
}
|
||||
if(pipeline->uniformsDirty[GU_A2C_ALPHA_BOOST] &&
|
||||
pipeline->uniformLocations[GU_A2C_ALPHA_BOOST] != -1)
|
||||
{
|
||||
glUniform1f(pipeline->uniformLocations[GU_A2C_ALPHA_BOOST], r_alphaToCoverageMipBoost->value);
|
||||
pipeline->uniformsDirty[GU_A2C_ALPHA_BOOST] = qfalse;
|
||||
}
|
||||
|
||||
UploadVertexArray(VB_POSITION, tess.xyz);
|
||||
UploadIndices(tess.indexes, tess.numIndexes);
|
||||
|
|
|
@ -104,6 +104,8 @@ cvar_t *r_portalOnly;
|
|||
cvar_t *r_subdivisions;
|
||||
cvar_t *r_lodCurveError;
|
||||
|
||||
cvar_t *r_alphaToCoverageMipBoost;
|
||||
|
||||
cvar_t *r_width;
|
||||
cvar_t *r_height;
|
||||
cvar_t *r_customaspect;
|
||||
|
@ -411,6 +413,7 @@ static const cvarTableItem_t r_cvars[] =
|
|||
{ &r_ditherStrength, "r_ditherStrength", "1.0", CVAR_ARCHIVE, CVART_FLOAT, "0.125", "8.0", help_r_ditherStrength },
|
||||
{ &r_transpSort, "r_transpSort", "0", CVAR_ARCHIVE, CVART_BOOL, NULL, NULL, help_r_transpSort },
|
||||
{ &r_lodCurveError, "r_lodCurveError", "2000", CVAR_ARCHIVE, CVART_FLOAT, "250", "10000", "curved surfaces LOD scale" },
|
||||
{ &r_alphaToCoverageMipBoost, "r_alphaToCoverageMipBoost", "0.125", CVAR_ARCHIVE, CVART_FLOAT, "0", "0.5", "increases the alpha value of higher mip levels" },
|
||||
|
||||
//
|
||||
// temporary variables that can change at any time
|
||||
|
|
|
@ -1051,6 +1051,8 @@ extern cvar_t *r_portalOnly;
|
|||
extern cvar_t *r_subdivisions;
|
||||
extern cvar_t *r_lodCurveError;
|
||||
|
||||
extern cvar_t *r_alphaToCoverageMipBoost; // increases the alpha value of higher mip levels
|
||||
|
||||
extern cvar_t *r_ignoreGLErrors;
|
||||
|
||||
extern cvar_t *r_brightness;
|
||||
|
|
Loading…
Reference in a new issue