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

Rendering updates (better alpha support) #396

Merged
merged 12 commits into from
Apr 2, 2024
97 changes: 97 additions & 0 deletions rsrc/shaders/final_frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#version 330 core

in vec2 texCoords;

uniform sampler2D screenTexture;
uniform int fxaa;
uniform vec2 texelStep;
uniform float lumaThreshold;
uniform float mulReduce;
uniform float minReduce;
uniform float maxSpan;

out vec4 color;

void main()
{
vec3 rgbM = texture(screenTexture, texCoords).rgb;

// Possibility to toggle FXAA on and off.
if (fxaa == 0)
{
color = vec4(rgbM, 1.0);

return;
}

// Sampling neighbour texels. Offsets are adapted to OpenGL texture coordinates.
vec3 rgbNW = textureOffset(screenTexture, texCoords, ivec2(-1, 1)).rgb;
vec3 rgbNE = textureOffset(screenTexture, texCoords, ivec2(1, 1)).rgb;
vec3 rgbSW = textureOffset(screenTexture, texCoords, ivec2(-1, -1)).rgb;
vec3 rgbSE = textureOffset(screenTexture, texCoords, ivec2(1, -1)).rgb;

// see http://en.wikipedia.org/wiki/Grayscale
const vec3 toLuma = vec3(0.299, 0.587, 0.114);

// Convert from RGB to luma.
float lumaNW = dot(rgbNW, toLuma);
float lumaNE = dot(rgbNE, toLuma);
float lumaSW = dot(rgbSW, toLuma);
float lumaSE = dot(rgbSE, toLuma);
float lumaM = dot(rgbM, toLuma);

// Gather minimum and maximum luma.
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));

// If contrast is lower than a maximum threshold ...
if (lumaMax - lumaMin <= lumaMax * lumaThreshold)
{
// ... do no AA and return.
color = vec4(rgbM, 1.0);

return;
}

// Sampling is done along the gradient.
vec2 samplingDirection;
samplingDirection.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
samplingDirection.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));

// Sampling step distance depends on the luma: The brighter the sampled texels, the smaller the final sampling step direction.
// This results, that brighter areas are less blurred/more sharper than dark areas.
float samplingDirectionReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * 0.25 * mulReduce, minReduce);

// Factor for norming the sampling direction plus adding the brightness influence.
float minSamplingDirectionFactor = 1.0 / (min(abs(samplingDirection.x), abs(samplingDirection.y)) + samplingDirectionReduce);

// Calculate final sampling direction vector by reducing, clamping to a range and finally adapting to the texture size.
samplingDirection = clamp(samplingDirection * minSamplingDirectionFactor, vec2(-maxSpan), vec2(maxSpan)) * texelStep;

// Inner samples on the tab.
vec3 rgbSampleNeg = texture(screenTexture, texCoords + samplingDirection * (1.0/3.0 - 0.5)).rgb;
vec3 rgbSamplePos = texture(screenTexture, texCoords + samplingDirection * (2.0/3.0 - 0.5)).rgb;

vec3 rgbTwoTab = (rgbSamplePos + rgbSampleNeg) * 0.5;

// Outer samples on the tab.
vec3 rgbSampleNegOuter = texture(screenTexture, texCoords + samplingDirection * (0.0/3.0 - 0.5)).rgb;
vec3 rgbSamplePosOuter = texture(screenTexture, texCoords + samplingDirection * (3.0/3.0 - 0.5)).rgb;

vec3 rgbFourTab = (rgbSamplePosOuter + rgbSampleNegOuter) * 0.25 + rgbTwoTab * 0.5;

// Calculate luma for checking against the minimum and maximum value.
float lumaFourTab = dot(rgbFourTab, toLuma);

// Are outer samples of the tab beyond the edge ...
if (lumaFourTab < lumaMin || lumaFourTab > lumaMax)
{
// ... yes, so use only two samples.
color = vec4(rgbTwoTab, 1.0);
}
else
{
// ... no, so use four samples.
color = vec4(rgbFourTab, 1.0);
}
}
12 changes: 12 additions & 0 deletions rsrc/shaders/final_vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#version 330 core

layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;

out vec2 texCoords;

void main()
{
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
texCoords = aTexCoords;
}
14 changes: 14 additions & 0 deletions rsrc/shaders/hudPost_frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#version 330 core

in vec2 texCoords;

uniform float hudAlpha = 1.0;
uniform sampler2D screenTexture;

out vec4 color;

void main()
{
color = texture(screenTexture, texCoords);
color[3] *= hudAlpha;
}
12 changes: 12 additions & 0 deletions rsrc/shaders/hudPost_vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#version 330 core

layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;

out vec2 texCoords;

void main()
{
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
texCoords = aTexCoords;
}
3 changes: 0 additions & 3 deletions rsrc/shaders/hud_frag.glsl
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#version 330 core

// in vec4 gl_FragCoord;
in vec4 fragmentColor;
in vec3 fragmentNormal;

uniform float ambient = 0.0;
uniform float hudAlpha = 1.0;
uniform float lightsActive = 1.0;

out vec4 color;
Expand Down Expand Up @@ -34,6 +32,5 @@ vec4 light_color() {

void main() {
color = light_color();
color[3] *= hudAlpha;
}

12 changes: 12 additions & 0 deletions rsrc/shaders/worldPost_frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#version 330 core

in vec2 texCoords;

uniform sampler2D screenTexture;

out vec4 color;

void main()
{
color = texture(screenTexture, texCoords);
}
12 changes: 12 additions & 0 deletions rsrc/shaders/worldPost_vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#version 330 core

layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;

out vec2 texCoords;

void main()
{
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
texCoords = aTexCoords;
}
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions src/bsp/CBSPPart.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class CBSPPart {
Boolean usesPrivateHither = 0;
Boolean usesPrivateYon = 0;
Boolean isTransparent = 0;
Boolean ignoreDepthTesting = false;
Boolean ignoreDirectionalLights = 0;
short userFlags = 0; // Can be used for various flags by user.

Expand Down
11 changes: 9 additions & 2 deletions src/game/CAbstractPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void CAbstractPlayer::LoadHUDParts() {
targetOns[i]->privateAmbient = SIGHTSAMBIENT;
targetOns[i]->yon = LONGYON * 2;
targetOns[i]->usesPrivateYon = true;
targetOns[i]->ignoreDepthTesting = true;
targetOns[i]->ignoreDirectionalLights = true;
targetOns[i]->isTransparent = true;
gRenderer->AddHUDPart(targetOns[i]);
Expand All @@ -73,6 +74,7 @@ void CAbstractPlayer::LoadHUDParts() {
targetOffs[i]->privateAmbient = SIGHTSAMBIENT;
targetOffs[i]->yon = LONGYON * 2;
targetOffs[i]->usesPrivateYon = true;
targetOffs[i]->ignoreDepthTesting = true;
targetOffs[i]->ignoreDirectionalLights = true;
targetOffs[i]->isTransparent = true;
gRenderer->AddHUDPart(targetOffs[i]);
Expand All @@ -81,6 +83,7 @@ void CAbstractPlayer::LoadHUDParts() {
dirArrowHeight = FIX3(750);
dirArrow = CBSPPart::Create(kDirIndBSP);
dirArrow->ReplaceColor(0xff000000, ColorManager::getLookForwardColor());
dirArrow->ignoreDepthTesting = true;
dirArrow->ignoreDirectionalLights = true;
dirArrow->privateAmbient = FIX1;
dirArrow->isTransparent = true;
Expand Down Expand Up @@ -539,8 +542,6 @@ void CAbstractPlayer::PlaceHUDParts() {
CScaledBSP* CAbstractPlayer::DashboardPart(uint16_t id, Fixed scale) {
CScaledBSP* bsp = new CScaledBSP(scale, id, this, 0);
bsp->ReplaceAllColors(ColorManager::getHUDColor());
bsp->privateAmbient = FIX1;
bsp->ignoreDirectionalLights = true;
bsp->isTransparent = true;
gRenderer->AddHUDPart(bsp);
return bsp;
Expand Down Expand Up @@ -623,15 +624,20 @@ void CAbstractPlayer::LoadDashboardParts() {

if (itsGame->itsApp->Get(kHUDShowMissileLock)) {
lockLight = DashboardPart(kLockLight, FIX3(600));
lockLight->ignoreDepthTesting = true;
}

groundDirArrow = DashboardPart(kGroundDirArrow, FIX3(1000 * arrowScale));
groundDirArrow->ignoreDepthTesting = true;
groundDirArrowSlow = DashboardPart(kGroundDirArrowSlow, FIX3(1000 * arrowScale));
groundDirArrowSlow->ignoreDepthTesting = true;
groundDirArrowFast = DashboardPart(kGroundDirArrowFast, FIX3(1000 * arrowScale));
groundDirArrowFast->ignoreDepthTesting = true;

// Shields
shieldLabel = DashboardPart(kShieldBSP, FIX3(70*layoutScale));
shieldGauge = DashboardPart(gaugeBSP);
shieldGauge->ignoreDepthTesting = true;
shieldGauge->isMorphable = true;

shieldGaugeBackLight = DashboardPart(gaugeBSP, ToFixed(layoutScale));
Expand All @@ -640,6 +646,7 @@ void CAbstractPlayer::LoadDashboardParts() {
// Energy
energyLabel = DashboardPart(kEnergyBSP, FIX3(170*layoutScale));
energyGauge = DashboardPart(gaugeBSP);
energyGauge->ignoreDepthTesting = true;
energyGauge->isMorphable = true;

energyGaugeBackLight = DashboardPart(gaugeBSP, ToFixed(layoutScale));
Expand Down
3 changes: 3 additions & 0 deletions src/game/CDepot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,16 +249,19 @@ void CDepot::ReloadParts() {
smartSight = CBSPPart::Create(208);
smartSight->ReplaceColor(0xfffffb00, ColorManager::getMissileSightPrimaryColor());
smartSight->ReplaceColor(0xffff2600, ColorManager::getMissileSightSecondaryColor());
smartSight->ignoreDepthTesting = true;
smartSight->ignoreDirectionalLights = true;
smartSight->privateAmbient = FIX1;

smartHairs = CBSPPart::Create(207);
smartHairs->ReplaceColor(0xffff2600, ColorManager::getMissileLockColor());
smartHairs->ignoreDepthTesting = true;
smartHairs->ignoreDirectionalLights = true;
smartHairs->privateAmbient = FIX1;

grenadeSight = CBSPPart::Create(200);
grenadeSight->ReplaceColor(0xfffffb00, ColorManager::getGrenadeSightPrimaryColor());
grenadeSight->ignoreDepthTesting = true;
grenadeSight->ignoreDirectionalLights = true;
grenadeSight->privateAmbient = FIX1;

Expand Down
2 changes: 1 addition & 1 deletion src/gui/CApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ json CApplication::_prefs = ReadPrefs();
json CApplication::_defaultPrefs = ReadDefaultPrefs();

CApplication::CApplication(std::string title) :
nanogui::Screen(nanogui::Vector2i(_prefs[kWindowWidth], _prefs[kWindowHeight]), title, true, _prefs[kFullScreenTag], 8, 8, 24, 8, _prefs[kMultiSamplesTag]) {
nanogui::Screen(nanogui::Vector2i(_prefs[kWindowWidth], _prefs[kWindowHeight]), title, true, _prefs[kFullScreenTag], 8, 8, 24, 8, 0) {
gApplication = this;
setResizeCallback([this](nanogui::Vector2i newSize) {
this->WindowResized(newSize.x, newSize.y);
Expand Down
4 changes: 2 additions & 2 deletions src/gui/Preferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ using json = nlohmann::json;
// GL stuff
#define kWindowWidth "windowWidth"
#define kWindowHeight "windowHeight"
#define kMultiSamplesTag "multiSamples"
#define kFullScreenTag "fullscreen"
#define kFOV "fov"
#define kFXAA "fxaa"

// Other graphics settings
#define kColorBlindMode "colorBlindMode"
Expand Down Expand Up @@ -142,11 +142,11 @@ static json defaultPrefs = {
{kPlayerHullTrimColorTag, "#2b2b2b"},
{kPlayerCockpitColorTag, "#0333ff"},
{kPlayerGunColorTag, "#929292"},
{kMultiSamplesTag, 0},
{kWindowWidth, 1024},
{kWindowHeight, 768},
{kFullScreenTag, false},
{kFOV, 50.0},
{kFXAA, true},
{kColorBlindMode, 0},
{kHUDColor, "#03f5f5"},
{kHUDPositiveColor, "#51e87e"},
Expand Down
Loading
Loading