-
Notifications
You must be signed in to change notification settings - Fork 237
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added post-process effects (FXAA, Bloom, Auto-Exposure, Tonemapping) * Added `PostProcessStack` to manage effect settings and a new component (`CPostProcessStack`) to expose them * Updated Lua bindings * Added `Blit` method to the base renderer * Changed default framebuffer type to HDR (`RGBA32F`) * Added an option to render the whole scene to the stencil buffer (required for the grid to avoid drawing on top of an already rendered pixel) * Removed built-in tonemapping + gamma correction in PBR shader (since it's already performed as a post-processing effect)
- Loading branch information
1 parent
3eb4632
commit a4f6bd7
Showing
45 changed files
with
1,868 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#shader vertex | ||
#version 430 core | ||
|
||
layout(location = 0) in vec2 geo_Pos; | ||
layout(location = 1) in vec2 geo_TexCoords; | ||
|
||
out vec2 TexCoords; | ||
|
||
void main() | ||
{ | ||
TexCoords = geo_TexCoords; | ||
gl_Position = vec4(geo_Pos, 0.0, 1.0); | ||
} | ||
|
||
#shader fragment | ||
#version 430 core | ||
|
||
in vec2 TexCoords; | ||
out vec4 FRAGMENT_COLOR; | ||
|
||
uniform sampler2D _InputTexture; | ||
uniform sampler2D _ExposureTexture; | ||
|
||
void main() | ||
{ | ||
const float exposure = texture(_ExposureTexture, vec2(0.5)).r; | ||
vec3 color = texture(_InputTexture, TexCoords).rgb * exposure; | ||
FRAGMENT_COLOR = vec4(color, 1.0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#shader vertex | ||
#version 430 core | ||
|
||
layout(location = 0) in vec2 geo_Pos; | ||
layout(location = 1) in vec2 geo_TexCoords; | ||
|
||
out vec2 TexCoords; | ||
|
||
void main() | ||
{ | ||
TexCoords = geo_TexCoords; | ||
gl_Position = vec4(geo_Pos, 0.0, 1.0); | ||
} | ||
|
||
#shader fragment | ||
#version 430 core | ||
|
||
in vec2 TexCoords; | ||
out vec4 FRAGMENT_COLOR; | ||
|
||
uniform sampler2D _InputTexture; | ||
uniform sampler2D _LuminanceTexture; | ||
uniform float _MinLuminanceEV; | ||
uniform float _MaxLuminanceEV; | ||
uniform float _ExposureCompensationEV; | ||
uniform float _ElapsedTime; | ||
uniform float _SpeedUp; | ||
uniform float _SpeedDown; | ||
uniform int _Progressive; | ||
|
||
// Photographic Middle Gray Reference | ||
const float MIDDLE_GRAY = 0.18f; | ||
|
||
// To avoid division by zero and log2 of zero | ||
const float EPSILON = 0.0001f; | ||
|
||
float SafeLog2(float x) | ||
{ | ||
return log2(max(x, EPSILON)); | ||
} | ||
|
||
// Convert Luminance to Exposure Value (EV100) | ||
float LuminanceToEV100(float luminance) | ||
{ | ||
return SafeLog2(luminance / MIDDLE_GRAY) * 2.0f; | ||
} | ||
|
||
// Convert EV100 back to Luminance | ||
float EV100ToLuminance(float ev100) | ||
{ | ||
return exp2(ev100 * 0.5f) * MIDDLE_GRAY; | ||
} | ||
|
||
// Advanced Exposure Calculation | ||
float CalculateExposureMultiplier(float luminance, float minLuminanceEV, float maxLuminanceEV, float exposureCompensation) | ||
{ | ||
// Convert average luminance to EV100 | ||
float luminanceEV = LuminanceToEV100(luminance); | ||
|
||
// Clamp EV within specified range | ||
float clampedLuminanceEV = clamp(luminanceEV, minLuminanceEV, maxLuminanceEV); | ||
|
||
// Apply exposure compensation | ||
float compensatedEV = clampedLuminanceEV - exposureCompensation; | ||
|
||
// Calculate exposure multiplier | ||
// Using middle gray as reference, with protection against extreme values | ||
float exposureMultiplier = MIDDLE_GRAY / max(EV100ToLuminance(compensatedEV), EPSILON); | ||
|
||
return exposureMultiplier; | ||
} | ||
|
||
float InterpolateExposure(float newExposure, float oldExposure) | ||
{ | ||
if (_Progressive != 0) | ||
{ | ||
const float delta = newExposure - oldExposure; | ||
const float speed = delta > 0.0 ? _SpeedUp : _SpeedDown; | ||
return oldExposure + delta * (1.0 - exp2(-_ElapsedTime * speed)); | ||
} | ||
else | ||
{ | ||
return newExposure; | ||
} | ||
} | ||
|
||
void main() | ||
{ | ||
const float averageLuminance = textureLod(_LuminanceTexture, vec2(0.5), textureQueryLevels(_LuminanceTexture) - 1).r; | ||
const float newExposure = CalculateExposureMultiplier(averageLuminance, _MinLuminanceEV, _MaxLuminanceEV, _ExposureCompensationEV); | ||
const float previousExposure = max(texture(_InputTexture, vec2(0.5)).r, 0.0001); | ||
const float interpolatedExposure = InterpolateExposure(newExposure, previousExposure); | ||
FRAGMENT_COLOR = vec4(vec3(interpolatedExposure), 1.0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#shader vertex | ||
#version 430 core | ||
|
||
layout(location = 0) in vec2 geo_Pos; | ||
layout(location = 1) in vec2 geo_TexCoords; | ||
|
||
out vec2 TexCoords; | ||
|
||
void main() | ||
{ | ||
TexCoords = geo_TexCoords; | ||
gl_Position = vec4(geo_Pos, 0.0, 1.0); | ||
} | ||
|
||
#shader fragment | ||
#version 430 core | ||
|
||
in vec2 TexCoords; | ||
out vec4 FRAGMENT_COLOR; | ||
|
||
uniform sampler2D _InputTexture; | ||
|
||
void main() | ||
{ | ||
FRAGMENT_COLOR = texture(_InputTexture, TexCoords); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#shader vertex | ||
#version 430 core | ||
|
||
layout(location = 0) in vec2 geo_Pos; | ||
layout(location = 1) in vec2 geo_TexCoords; | ||
|
||
out vec2 TexCoords; | ||
|
||
void main() | ||
{ | ||
TexCoords = geo_TexCoords; | ||
gl_Position = vec4(geo_Pos, 0.0, 1.0); | ||
} | ||
|
||
#shader fragment | ||
#version 430 core | ||
|
||
in vec2 TexCoords; | ||
out vec4 FRAGMENT_COLOR; | ||
|
||
uniform sampler2D _InputTexture; | ||
uniform sampler2D _BloomTexture; | ||
uniform float _BloomIntensity; | ||
|
||
void main() | ||
{ | ||
const vec3 sceneColor = texture(_InputTexture, TexCoords).rgb; | ||
const vec3 bloomColor = texture(_BloomTexture, TexCoords).rgb; | ||
FRAGMENT_COLOR = vec4(sceneColor + _BloomIntensity * bloomColor, 1.0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#shader vertex | ||
#version 430 core | ||
|
||
layout(location = 0) in vec2 geo_Pos; | ||
layout(location = 1) in vec2 geo_TexCoords; | ||
|
||
out vec2 TexCoords; | ||
|
||
void main() | ||
{ | ||
TexCoords = geo_TexCoords; | ||
gl_Position = vec4(geo_Pos, 0.0, 1.0); | ||
} | ||
|
||
#shader fragment | ||
#version 430 core | ||
|
||
in vec2 TexCoords; | ||
out vec4 FRAGMENT_COLOR; | ||
|
||
uniform sampler2D _InputTexture; | ||
uniform bool _Horizontal; | ||
uniform float _BlurSize; | ||
uniform int _KernelSize; | ||
|
||
void main() | ||
{ | ||
const vec2 texelSize = 1.0 / textureSize(_InputTexture, 0); | ||
const vec2 direction = _Horizontal ? vec2(texelSize.x, 0.0) : vec2(0.0, texelSize.y); | ||
|
||
vec4 color = vec4(0.0); | ||
float totalWeight = 0.0; | ||
|
||
for (int i = -_KernelSize; i <= _KernelSize; i++) | ||
{ | ||
float weight = exp(-0.5 * (i * i) / (_BlurSize * _BlurSize)); | ||
vec2 offset = float(i) * direction; | ||
color += texture(_InputTexture, TexCoords + offset) * weight; | ||
totalWeight += weight; | ||
} | ||
|
||
FRAGMENT_COLOR = max(color / totalWeight, 0.0001f); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#shader vertex | ||
#version 430 core | ||
|
||
layout(location = 0) in vec2 geo_Pos; | ||
layout(location = 1) in vec2 geo_TexCoords; | ||
|
||
out vec2 TexCoords; | ||
|
||
void main() | ||
{ | ||
TexCoords = geo_TexCoords; | ||
gl_Position = vec4(geo_Pos, 0.0, 1.0); | ||
} | ||
|
||
#shader fragment | ||
#version 430 core | ||
|
||
in vec2 TexCoords; | ||
out vec4 FRAGMENT_COLOR; | ||
|
||
uniform sampler2D _InputTexture; | ||
uniform float _Threshold; | ||
|
||
float luminance(vec3 color) | ||
{ | ||
return dot(color, vec3(0.2126, 0.7152, 0.0722)); | ||
} | ||
|
||
void main() | ||
{ | ||
const vec3 color = texture(_InputTexture, TexCoords).rgb; | ||
float brightness = luminance(color); | ||
brightness = max(0.0, brightness - _Threshold); | ||
FRAGMENT_COLOR = vec4(color * sign(brightness), 1.0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#shader vertex | ||
#version 430 core | ||
|
||
layout(location = 0) in vec2 geo_Pos; | ||
layout(location = 1) in vec2 geo_TexCoords; | ||
|
||
out vec2 TexCoords; | ||
|
||
void main() | ||
{ | ||
TexCoords = geo_TexCoords; | ||
gl_Position = vec4(geo_Pos, 0.0, 1.0); | ||
} | ||
|
||
#shader fragment | ||
#version 430 core | ||
|
||
in vec2 TexCoords; | ||
out vec4 FRAGMENT_COLOR; | ||
|
||
uniform sampler2D _InputTexture; | ||
|
||
vec3 applyFXAA(sampler2D tex, vec2 uv) | ||
{ | ||
vec2 resolution = vec2(textureSize(tex, 0)); | ||
vec2 pixelSize = 1.0 / resolution; | ||
|
||
// Sample the neighborhood pixels | ||
vec3 rgbNW = texture(tex, uv + vec2(-1.0, -1.0) * pixelSize).rgb; | ||
vec3 rgbNE = texture(tex, uv + vec2(1.0, -1.0) * pixelSize).rgb; | ||
vec3 rgbSW = texture(tex, uv + vec2(-1.0, 1.0) * pixelSize).rgb; | ||
vec3 rgbSE = texture(tex, uv + vec2(1.0, 1.0) * pixelSize).rgb; | ||
vec3 rgbM = texture(tex, uv).rgb; | ||
|
||
// Luminance (perceived brightness) | ||
float lumaNW = dot(rgbNW, vec3(0.299, 0.587, 0.114)); | ||
float lumaNE = dot(rgbNE, vec3(0.299, 0.587, 0.114)); | ||
float lumaSW = dot(rgbSW, vec3(0.299, 0.587, 0.114)); | ||
float lumaSE = dot(rgbSE, vec3(0.299, 0.587, 0.114)); | ||
float lumaM = dot(rgbM, vec3(0.299, 0.587, 0.114)); | ||
|
||
// Edge detection | ||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); | ||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); | ||
float lumaRange = lumaMax - lumaMin; | ||
|
||
// Threshold for edge detection | ||
if (lumaRange < 0.1) | ||
{ | ||
return rgbM; // No significant edge, return original | ||
} | ||
|
||
// Direction of the edge | ||
vec2 dir; | ||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); | ||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); | ||
|
||
// Normalize the direction | ||
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * 0.25, 0.0001); | ||
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); | ||
dir = clamp(dir * rcpDirMin, -pixelSize, pixelSize); | ||
|
||
// Final FXAA sampling | ||
vec3 rgbA = 0.5 * ( | ||
texture(tex, uv + dir * (1.0 / 3.0 - 0.5)).rgb + | ||
texture(tex, uv + dir * (2.0 / 3.0 - 0.5)).rgb | ||
); | ||
|
||
vec3 rgbB = rgbA * 0.5 + 0.25 * ( | ||
texture(tex, uv + dir * -0.5).rgb + | ||
texture(tex, uv + dir * 0.5).rgb | ||
); | ||
|
||
// Choose between original and anti-aliased | ||
float lumaB = dot(rgbB, vec3(0.299, 0.587, 0.114)); | ||
return (lumaB < lumaMin || lumaB > lumaMax) ? rgbA : rgbB; | ||
} | ||
|
||
void main() | ||
{ | ||
FRAGMENT_COLOR = vec4(applyFXAA(_InputTexture, TexCoords), 1.0); | ||
} |
Oops, something went wrong.