1 Oct 2021
~ Made Shaders now able to use Defines. ~ Moved complete Bloom-shader code in a single file (not working at the moment)
This commit is contained in:
parent
443877019b
commit
8a84182563
15 changed files with 325 additions and 44 deletions
|
|
@ -17,6 +17,14 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SM.Base.PostEffects
|
namespace SM.Base.PostEffects
|
||||||
{
|
{
|
||||||
|
enum BloomEffectShaderType
|
||||||
|
{
|
||||||
|
Filtering,
|
||||||
|
Downsampling,
|
||||||
|
Upsampling,
|
||||||
|
Combine
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The recommended bloom effect, that looks way better than the old one.
|
/// The recommended bloom effect, that looks way better than the old one.
|
||||||
/// <para>Based on Blender's implermentation, which is based on COD: Infinite Warfare.</para>
|
/// <para>Based on Blender's implermentation, which is based on COD: Infinite Warfare.</para>
|
||||||
|
|
@ -45,6 +53,40 @@ namespace SM.Base.PostEffects
|
||||||
_combineShader.ShaderFiles.Fragment[0].GLSLExtensions.Add(samplingFile);
|
_combineShader.ShaderFiles.Fragment[0].GLSLExtensions.Add(samplingFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
private static readonly string bloomFile = AssemblyUtility.ReadAssemblyFile(SMRenderer.PostProcessPath + ".bloom.frag");
|
||||||
|
private static readonly ShaderFile combineVertex = new ShaderFile(AssemblyUtility.ReadAssemblyFile(SMRenderer.PostProcessPath + ".bloom.combine.vert"));
|
||||||
|
|
||||||
|
static Dictionary<bool, PostProcessShader[]> _ppShaders = new Dictionary<bool, PostProcessShader[]>(2);
|
||||||
|
|
||||||
|
static PostProcessShader[] GetShaders(bool high)
|
||||||
|
{
|
||||||
|
if (_ppShaders.ContainsKey(high)) return _ppShaders[high];
|
||||||
|
|
||||||
|
PostProcessShader[] shaders;
|
||||||
|
_ppShaders.Add(high, shaders = new PostProcessShader[4]);
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
ShaderFile file = new ShaderFile(bloomFile)
|
||||||
|
{
|
||||||
|
Defines =
|
||||||
|
{
|
||||||
|
"ACTION_"+((BloomEffectShaderType)i).ToString().ToUpper(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (high) file.Defines.Add("HIGH");
|
||||||
|
|
||||||
|
PostProcessShader shader;
|
||||||
|
if (i == 3) shader = new PostProcessShader(vertex: combineVertex, file);
|
||||||
|
else shader = new PostProcessShader(file);
|
||||||
|
|
||||||
|
shaders[i] = shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
return shaders;
|
||||||
|
}*/
|
||||||
|
|
||||||
const int MAXBLOOMSTEPS = 8;
|
const int MAXBLOOMSTEPS = 8;
|
||||||
const float INTENSITY = .1f;
|
const float INTENSITY = .1f;
|
||||||
|
|
||||||
|
|
@ -52,6 +94,7 @@ namespace SM.Base.PostEffects
|
||||||
|
|
||||||
private List<Framebuffer> _downsampler;
|
private List<Framebuffer> _downsampler;
|
||||||
private List<Framebuffer> _upsample;
|
private List<Framebuffer> _upsample;
|
||||||
|
private PostProcessShader[] shaders;
|
||||||
|
|
||||||
private int _iterations;
|
private int _iterations;
|
||||||
private float _sampleSize;
|
private float _sampleSize;
|
||||||
|
|
@ -98,9 +141,12 @@ namespace SM.Base.PostEffects
|
||||||
/// This creates a more prettier bloom effect.
|
/// This creates a more prettier bloom effect.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hdr">This allows to enable hdr returns.</param>
|
/// <param name="hdr">This allows to enable hdr returns.</param>
|
||||||
public BloomEffect(bool hdr = false)
|
/// <param name="highSetting">If set true, it will use the high quality settings.</param>
|
||||||
|
public BloomEffect(bool hdr = false, bool highSetting = true)
|
||||||
{
|
{
|
||||||
_hdr = hdr;
|
_hdr = hdr;
|
||||||
|
//shaders = GetShaders(highSetting);
|
||||||
|
shaders = new[] { _filterShader, _downsampleShader, _upsampleShader, _combineShader };
|
||||||
}
|
}
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override void InitProcess() => CreateFramebuffers();
|
protected override void InitProcess() => CreateFramebuffers();
|
||||||
|
|
@ -168,7 +214,7 @@ namespace SM.Base.PostEffects
|
||||||
|
|
||||||
// Filtering
|
// Filtering
|
||||||
_downsampler[0].Activate(true);
|
_downsampler[0].Activate(true);
|
||||||
_filterShader.Draw(source, col =>
|
shaders[0].Draw(source, col =>
|
||||||
{
|
{
|
||||||
col["ThresholdCurve"].SetVector4(_thresholdCurve);
|
col["ThresholdCurve"].SetVector4(_thresholdCurve);
|
||||||
});
|
});
|
||||||
|
|
@ -180,7 +226,7 @@ namespace SM.Base.PostEffects
|
||||||
ColorAttachment downsampleSource = last;
|
ColorAttachment downsampleSource = last;
|
||||||
Framebuffer downsampleTarget = _downsampler[i];
|
Framebuffer downsampleTarget = _downsampler[i];
|
||||||
downsampleTarget.Activate(true);
|
downsampleTarget.Activate(true);
|
||||||
_downsampleShader.Draw(downsampleSource);
|
shaders[1].Draw(downsampleSource);
|
||||||
|
|
||||||
last = downsampleTarget["0"];
|
last = downsampleTarget["0"];
|
||||||
}
|
}
|
||||||
|
|
@ -193,7 +239,7 @@ namespace SM.Base.PostEffects
|
||||||
|
|
||||||
upsampleTarget.Activate(true);
|
upsampleTarget.Activate(true);
|
||||||
|
|
||||||
_upsampleShader.Draw(last, (a) =>
|
shaders[2].Draw(last, (a) =>
|
||||||
{
|
{
|
||||||
if (last != null) a["baseBuffer"].SetTexture(downsampleSource);
|
if (last != null) a["baseBuffer"].SetTexture(downsampleSource);
|
||||||
a["sampleSize"].SetFloat(_sampleSize);
|
a["sampleSize"].SetFloat(_sampleSize);
|
||||||
|
|
@ -204,7 +250,7 @@ namespace SM.Base.PostEffects
|
||||||
|
|
||||||
// combine
|
// combine
|
||||||
target.Activate(true);
|
target.Activate(true);
|
||||||
_combineShader.Draw(last, (a) =>
|
shaders[3].Draw(last, (a) =>
|
||||||
{
|
{
|
||||||
a["sampleSize"].SetFloat(_sampleSize);
|
a["sampleSize"].SetFloat(_sampleSize);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,14 @@ namespace SM.Base.PostEffects
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class PostProcessUtility
|
public static class PostProcessUtility
|
||||||
{
|
{
|
||||||
|
public static readonly ShaderFile HDRCurves = new ShaderFile(AssemblyUtility.ReadAssemblyFile(SMRenderer.PostProcessPath + ".hdr_curves.frag"));
|
||||||
private static readonly string _finalizeHdrCode = AssemblyUtility.ReadAssemblyFile(SMRenderer.PostProcessPath + ".finalize_hdr.glsl");
|
private static readonly string _finalizeHdrCode = AssemblyUtility.ReadAssemblyFile(SMRenderer.PostProcessPath + ".finalize_hdr.glsl");
|
||||||
|
|
||||||
private static readonly Dictionary<HDRColorCurve, PostProcessShader> _hdrExposureShader = new Dictionary<HDRColorCurve, PostProcessShader>()
|
private static readonly Dictionary<HDRColorCurve, PostProcessShader> _hdrExposureShader = new Dictionary<HDRColorCurve, PostProcessShader>()
|
||||||
{
|
{
|
||||||
{ HDRColorCurve.OnlyExposure, new PostProcessShader(new ShaderFile(_finalizeHdrCode) { StringOverrides = { { "TYPE", "0" } } }) },
|
{ HDRColorCurve.OnlyExposure, new PostProcessShader(new ShaderFile(_finalizeHdrCode) {GLSLExtensions = { HDRCurves } }) },
|
||||||
{ HDRColorCurve.Reinhard, new PostProcessShader(new ShaderFile(_finalizeHdrCode) { StringOverrides = { { "TYPE", "1" } } }) },
|
{ HDRColorCurve.Reinhard, new PostProcessShader(new ShaderFile(_finalizeHdrCode) { GLSLExtensions = { HDRCurves }, Defines = { "TYPE_REINHARD" } }) },
|
||||||
{ HDRColorCurve.ACES, new PostProcessShader(new ShaderFile(_finalizeHdrCode) { StringOverrides = { { "TYPE", "2" } } }) },
|
{ HDRColorCurve.ACES, new PostProcessShader(new ShaderFile(_finalizeHdrCode) { GLSLExtensions = { HDRCurves }, Defines = { "TYPE_ACES" } }) },
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly PostProcessShader _gammaShader =
|
private static readonly PostProcessShader _gammaShader =
|
||||||
|
|
|
||||||
188
src/renderer/SM.Base/PostEffects/Shaders/bloom.frag
Normal file
188
src/renderer/SM.Base/PostEffects/Shaders/bloom.frag
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
#version 330 core
|
||||||
|
/* ACTIONS:
|
||||||
|
0 = Filtering
|
||||||
|
1 = Downsamping
|
||||||
|
2 = Upsampling
|
||||||
|
3 = Combine
|
||||||
|
*/
|
||||||
|
|
||||||
|
in vec2 vTexture;
|
||||||
|
|
||||||
|
uniform vec2 renderedTextureTexelSize;
|
||||||
|
// Uniforms
|
||||||
|
uniform vec4 ThresholdCurve;
|
||||||
|
|
||||||
|
|
||||||
|
// Downsampling
|
||||||
|
|
||||||
|
uniform float sampleSize;
|
||||||
|
uniform sampler2D baseBuffer;
|
||||||
|
|
||||||
|
in vec2 amountUV;
|
||||||
|
|
||||||
|
uniform sampler2D scene;
|
||||||
|
uniform vec4 bloomColor;
|
||||||
|
uniform bool HDR;
|
||||||
|
|
||||||
|
uniform bool hasAmountMap;
|
||||||
|
uniform sampler2D amountMap;
|
||||||
|
uniform vec2 amountLimit;
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 color;
|
||||||
|
layout(location = 1) out vec4 sceneOutput;
|
||||||
|
|
||||||
|
vec4 GetRenderColorOffset(vec2);
|
||||||
|
vec3 reinhardTone(vec3);
|
||||||
|
|
||||||
|
// ---- Utils ----
|
||||||
|
vec3 safe_color(vec3 c) {
|
||||||
|
return clamp(c, vec3(0.0), vec3(1e20));
|
||||||
|
}
|
||||||
|
vec3 median(vec3 a, vec3 b, vec3 c)
|
||||||
|
{
|
||||||
|
return a + b + c - min(min(a, b), c) - max(max(a, b), c);
|
||||||
|
}
|
||||||
|
float getBrightness(vec3 col) {
|
||||||
|
return max(col.r, max(col.g, col.b));
|
||||||
|
return (col.r + col.r + col.b + col.g + col.g + col.g) / 6.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Functions ----
|
||||||
|
vec3 simpleBoxFilter() {
|
||||||
|
#if defined (ACTION_DOWNSAMPLING)
|
||||||
|
vec4 d = renderedTextureTexelSize.xyxy * vec4(-1,-1,1,1);
|
||||||
|
#else
|
||||||
|
vec4 d = renderedTextureTexelSize.xyxy * vec4(-1,-1,1,1) * (sampleSize * 0.5);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 s;
|
||||||
|
s = GetRenderColorOffset(d.xy).rgb;
|
||||||
|
s += GetRenderColorOffset(d.zy).rgb;
|
||||||
|
s += GetRenderColorOffset(d.xw).rgb;
|
||||||
|
s += GetRenderColorOffset(d.zw).rgb;
|
||||||
|
|
||||||
|
return s * 0.25; // 1 / 4 = 0.25
|
||||||
|
}
|
||||||
|
|
||||||
|
// Downsampling:
|
||||||
|
vec3 downsample_high() {
|
||||||
|
vec4 d = renderedTextureTexelSize.xyxy * vec4(-1,-1, +1, +1);
|
||||||
|
vec3 s1 = GetRenderColorOffset(d.xy).rgb; // - -
|
||||||
|
// X -
|
||||||
|
|
||||||
|
vec3 s2 = GetRenderColorOffset(d.zy).rgb; // - -
|
||||||
|
// - X
|
||||||
|
|
||||||
|
vec3 s3 = GetRenderColorOffset(d.xw).rgb; // X -
|
||||||
|
// - -
|
||||||
|
|
||||||
|
vec3 s4 = GetRenderColorOffset(d.zw).rgb; // X -
|
||||||
|
// - -
|
||||||
|
|
||||||
|
float s1w = 1.0 / (getBrightness(s1) + 1.0);
|
||||||
|
float s2w = 1.0 / (getBrightness(s2) + 1.0);
|
||||||
|
float s3w = 1.0 / (getBrightness(s3) + 1.0);
|
||||||
|
float s4w = 1.0 / (getBrightness(s4) + 1.0);
|
||||||
|
float one_div = 1.0 / (s1w + s2w + s3w + s4w);
|
||||||
|
|
||||||
|
return (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * one_div;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upsampling:
|
||||||
|
vec3 upsample_high() {
|
||||||
|
vec4 d = renderedTextureTexelSize.xyxy * vec4(1, 1,-1,0) * sampleSize;
|
||||||
|
|
||||||
|
vec3 s;
|
||||||
|
// Line + 1
|
||||||
|
s = GetRenderColorOffset(d.zy).rgb; // x - -
|
||||||
|
s += GetRenderColorOffset(d.wy).rgb * 2; // - X -
|
||||||
|
s += GetRenderColorOffset(d.xy).rgb; // - - X
|
||||||
|
|
||||||
|
// Line 0
|
||||||
|
s += GetRenderColorOffset(d.zw).rgb * 2; // X - -
|
||||||
|
s += GetRenderColorOffset(vec2(0)).rgb * 4; // - X -
|
||||||
|
s += GetRenderColorOffset(d.xw).rgb * 2; // - - X
|
||||||
|
|
||||||
|
// Line - 1
|
||||||
|
s += GetRenderColorOffset(d.zz).rgb; // X - -
|
||||||
|
s += GetRenderColorOffset(d.wz).rgb * 2; // - X -
|
||||||
|
s += GetRenderColorOffset(d.xz).rgb; // - - X
|
||||||
|
|
||||||
|
return texture2D(baseBuffer, vTexture).rgb + s * 0.0625; // 1 / 16 = 0.0625
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Actions ----
|
||||||
|
vec3 filtering() {
|
||||||
|
|
||||||
|
|
||||||
|
vec3 col = safe_color(GetRenderColorOffset(vec2(0)).rgb);
|
||||||
|
sceneOutput = vec4(col, 1);
|
||||||
|
return sceneOutput.rgb;
|
||||||
|
|
||||||
|
#ifdef HIGH
|
||||||
|
vec3 d = renderedTextureTexelSize.xyx * vec3(1,1,0);
|
||||||
|
vec3 s0 = col + vec3(.1);
|
||||||
|
vec3 s1 = safe_color(GetRenderColorOffset(-d.xz).rgb) + vec3(.1);
|
||||||
|
vec3 s2 = safe_color(GetRenderColorOffset(+d.xz).rgb) + vec3(.1);
|
||||||
|
vec3 s3 = safe_color(GetRenderColorOffset(-d.zy).rgb) + vec3(.1);
|
||||||
|
vec3 s4 = safe_color(GetRenderColorOffset(+d.zy).rgb) + vec3(.1);
|
||||||
|
vec3 col = median(median(s0, s1, s2), s3, s4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float br = getBrightness(col);
|
||||||
|
|
||||||
|
float rq = clamp(br - ThresholdCurve.x, 0, ThresholdCurve.y);
|
||||||
|
rq = ThresholdCurve.z * rq * rq;
|
||||||
|
|
||||||
|
float resultBr = max(rq, br - ThresholdCurve.w) / max(1e-5, br);
|
||||||
|
return col * resultBr;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 downsample() {
|
||||||
|
#ifdef HIGH
|
||||||
|
return downsample_high();
|
||||||
|
#else
|
||||||
|
return simpleBoxFilter();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 upsample() {
|
||||||
|
#ifdef HIGH
|
||||||
|
return upsample_high();
|
||||||
|
#else
|
||||||
|
return simpleBoxFilter();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 combine() {
|
||||||
|
vec3 scene = safe_color(texture2D(scene, vTexture).rgb);
|
||||||
|
vec3 blur = upsample() * bloomColor.rgb;
|
||||||
|
|
||||||
|
if (hasAmountMap) {
|
||||||
|
blur *= clamp(texture2D(amountMap, amountUV).r * (amountLimit.y - amountLimit.x) + amountLimit.x, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HDR) {
|
||||||
|
return scene + blur;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scene + reinhardTone(blur);
|
||||||
|
}
|
||||||
|
|
||||||
|
// main:
|
||||||
|
void main() {
|
||||||
|
vec3 col;
|
||||||
|
|
||||||
|
#if defined(ACTION_FILTERING)
|
||||||
|
col = filtering();
|
||||||
|
#elif defined(ACTION_DOWNSAMPLING)
|
||||||
|
col = downsample();
|
||||||
|
#elif defined(ACTION_UPSAMPLING)
|
||||||
|
col = upsample();
|
||||||
|
#else
|
||||||
|
col = combine();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
color = vec4(col, 1);
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
uniform vec2 renderedTextureTexelSize;
|
uniform vec2 renderedTextureTexelSize;
|
||||||
|
|
||||||
vec4 GetRenderColor();
|
|
||||||
vec4 GetRenderColorOffset(vec2);
|
vec4 GetRenderColorOffset(vec2);
|
||||||
|
|
||||||
float getBrightness(vec3 col) {
|
float getBrightness(vec3 col) {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ vec4 GetRenderColorOffset(vec2);
|
||||||
|
|
||||||
|
|
||||||
vec3 upsample_filter_high() {
|
vec3 upsample_filter_high() {
|
||||||
vec4 d = renderedTextureTexelSize.xyxy * vec4(1, 1,-1,0);
|
vec4 d = renderedTextureTexelSize.xyxy * vec4(1, 1,-1,0) * sampleSize;
|
||||||
|
|
||||||
vec3 s;
|
vec3 s;
|
||||||
// Line + 1
|
// Line + 1
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#version 330
|
#version 330
|
||||||
#define TYPE //!TYPE
|
|
||||||
|
|
||||||
in vec2 vTexture;
|
in vec2 vTexture;
|
||||||
|
|
||||||
|
|
@ -9,31 +8,19 @@ uniform float Gamma;
|
||||||
|
|
||||||
layout(location = 0) out vec4 color;
|
layout(location = 0) out vec4 color;
|
||||||
|
|
||||||
vec3 ACES(vec3 x) {
|
vec3 ACES(vec3);
|
||||||
const float a = 2.51;
|
|
||||||
const float b = 0.03;
|
|
||||||
const float c = 2.43;
|
|
||||||
const float d = 0.59;
|
|
||||||
const float e = 0.14;
|
|
||||||
|
|
||||||
return clamp((x * (a * x + b)) / (x * (c * x + d) + e), 0,1.0);
|
vec3 reinhardTone(vec3);
|
||||||
}
|
|
||||||
|
|
||||||
vec3 reinhardTone(vec3 col) {
|
vec3 exposure(vec3);
|
||||||
return col / (col + vec3(1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 exposure(vec3 scene) {
|
|
||||||
return vec3(1) - exp(-texture(Scene, vTexture).rgb * Exposure);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
vec3 scene = texture2D(Scene, vTexture).rgb;
|
vec3 scene = texture2D(Scene, vTexture).rgb;
|
||||||
vec3 result = exposure(scene);
|
vec3 result = exposure(scene);
|
||||||
#if (TYPE == 1)
|
#if defined(TYPE_REINHARD)
|
||||||
result = reinhardTone(result);
|
result = reinhardTone(result);
|
||||||
#elif (TYPE == 2)
|
#elif defined(TYPE_ACES)
|
||||||
result = ACES(result);
|
result = ACES(result);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
21
src/renderer/SM.Base/PostEffects/Shaders/hdr_curves.frag
Normal file
21
src/renderer/SM.Base/PostEffects/Shaders/hdr_curves.frag
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform float Exposure;
|
||||||
|
|
||||||
|
vec3 ACES(vec3 col) {
|
||||||
|
const float a = 2.51;
|
||||||
|
const float b = 0.03;
|
||||||
|
const float c = 2.43;
|
||||||
|
const float d = 0.59;
|
||||||
|
const float e = 0.14;
|
||||||
|
|
||||||
|
return clamp((col * (a * col + b)) / (col * (c * col + d) + e), 0.0,1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 reinhardTone(vec3 col) {
|
||||||
|
return col / (col + vec3(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 exposure(vec3 col) {
|
||||||
|
return vec3(1) - exp(-col * Exposure);
|
||||||
|
}
|
||||||
|
|
@ -113,6 +113,8 @@ namespace SM.Base.PostProcess
|
||||||
/// <param name="setUniformAction"></param>
|
/// <param name="setUniformAction"></param>
|
||||||
public void Draw(Action<UniformCollection> setUniformAction)
|
public void Draw(Action<UniformCollection> setUniformAction)
|
||||||
{
|
{
|
||||||
|
if (ErrorInShader) return;
|
||||||
|
|
||||||
Activate();
|
Activate();
|
||||||
Plate.Object.Activate();
|
Plate.Object.Activate();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,8 @@
|
||||||
<EmbeddedResource Include="PostEffects\Shaders\bloom\combine.frag" />
|
<EmbeddedResource Include="PostEffects\Shaders\bloom\combine.frag" />
|
||||||
<EmbeddedResource Include="PostEffects\Shaders\bloom\sampling.frag" />
|
<EmbeddedResource Include="PostEffects\Shaders\bloom\sampling.frag" />
|
||||||
<EmbeddedResource Include="PostEffects\Shaders\bloom\combine.vert" />
|
<EmbeddedResource Include="PostEffects\Shaders\bloom\combine.vert" />
|
||||||
|
<EmbeddedResource Include="PostEffects\Shaders\bloom.frag" />
|
||||||
|
<EmbeddedResource Include="PostEffects\Shaders\hdr_curves.frag" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ namespace SM.Base.Shaders
|
||||||
/// <param name="context">The context</param>
|
/// <param name="context">The context</param>
|
||||||
public virtual void Draw(DrawContext context)
|
public virtual void Draw(DrawContext context)
|
||||||
{
|
{
|
||||||
|
if (ErrorInShader) return;
|
||||||
context.Shader.Activate();
|
context.Shader.Activate();
|
||||||
|
|
||||||
context.Mesh.Activate();
|
context.Mesh.Activate();
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ namespace SM.OGL.Shaders
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override bool AutoCompile { get; set; } = true;
|
protected override bool AutoCompile { get; set; } = true;
|
||||||
|
|
||||||
|
public bool ErrorInShader { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains the different files for the shader.
|
/// Contains the different files for the shader.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -102,12 +104,17 @@ namespace SM.OGL.Shaders
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
_id = GL.CreateProgram();
|
_id = GL.CreateProgram();
|
||||||
|
Uniforms = new UniformCollection { ParentShader = this };
|
||||||
|
|
||||||
ShaderFiles.Append(this);
|
ErrorInShader = !ShaderFiles.Append(this);
|
||||||
|
if (ErrorInShader)
|
||||||
|
{
|
||||||
|
GL.DeleteProgram(_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
GL.LinkProgram(_id);
|
GL.LinkProgram(_id);
|
||||||
ShaderFiles.Detach(this);
|
ShaderFiles.Detach(this);
|
||||||
|
|
||||||
Uniforms = new UniformCollection {ParentShader = this};
|
|
||||||
Uniforms.Import(this);
|
Uniforms.Import(this);
|
||||||
|
|
||||||
GLDebugging.CheckGLErrors($"A error occured at shader creation for '{GetType()}': %code%");
|
GLDebugging.CheckGLErrors($"A error occured at shader creation for '{GetType()}': %code%");
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ namespace SM.OGL.Shaders
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<ShaderFile> GLSLExtensions = new List<ShaderFile>();
|
public List<ShaderFile> GLSLExtensions = new List<ShaderFile>();
|
||||||
|
|
||||||
|
public List<string> Defines = new List<string>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets/Sets the name for this shader file.
|
/// Gets/Sets the name for this shader file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -63,21 +65,44 @@ namespace SM.OGL.Shaders
|
||||||
_data = _data.Replace("//!" + kvp.Key, kvp.Value);
|
_data = _data.Replace("//!" + kvp.Key, kvp.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Compile(GenericShader shader, ShaderType type)
|
internal bool Compile(GenericShader shader, ShaderType type)
|
||||||
{
|
{
|
||||||
if (_id < 0)
|
if (_id < 0)
|
||||||
{
|
{
|
||||||
GenerateSource();
|
GenerateSource();
|
||||||
|
|
||||||
_id = GL.CreateShader(type);
|
_id = GL.CreateShader(type);
|
||||||
GL.ShaderSource(_id, _data);
|
if (Defines.Count > 0)
|
||||||
|
{
|
||||||
|
string defineString = "";
|
||||||
|
foreach(string define in Defines)
|
||||||
|
{
|
||||||
|
defineString += "#define " + define + Environment.NewLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.ShaderSource(_id, 2, new string[] { defineString, _data }, new int[] { defineString.Length, _data.Length });
|
||||||
|
} else GL.ShaderSource(_id, _data);
|
||||||
GL.CompileShader(_id);
|
GL.CompileShader(_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
GL.AttachShader(shader, _id);
|
GL.GetShader(_id, ShaderParameter.CompileStatus, out int compileStatus);
|
||||||
GLDebugging.CheckGLErrors($"Error at loading shader file: '{shader.GetType()}', '{type}', %code%");
|
if (compileStatus != 1)
|
||||||
|
{
|
||||||
|
GL.GetShader(_id, ShaderParameter.InfoLogLength, out int loglength);
|
||||||
|
|
||||||
for (var i = 0; i < GLSLExtensions.Count; i++) GLSLExtensions[i].Compile(shader, type);
|
GLCustomActions.AtWarning?.Invoke($"Shader '{ToString()}' doesn't compile correctly.\nReason:" + GL.GetShaderInfoLog(_id));
|
||||||
|
|
||||||
|
GL.DeleteShader(_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.AttachShader(shader, _id);
|
||||||
|
|
||||||
|
|
||||||
|
for (var i = 0; i < GLSLExtensions.Count; i++) {
|
||||||
|
if (!GLSLExtensions[i].Compile(shader, type)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
|
||||||
|
|
@ -68,17 +68,19 @@ namespace SM.OGL.Shaders
|
||||||
/// Appends the files to the shader.
|
/// Appends the files to the shader.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="shader"></param>
|
/// <param name="shader"></param>
|
||||||
internal void Append(GenericShader shader)
|
internal bool Append(GenericShader shader)
|
||||||
{
|
{
|
||||||
foreach (ShaderFile file in Vertex)
|
foreach (ShaderFile file in Vertex)
|
||||||
file.Compile(shader, ShaderType.VertexShader);
|
if (!file.Compile(shader, ShaderType.VertexShader)) return false;
|
||||||
|
|
||||||
if (Geometry != null)
|
if (Geometry != null)
|
||||||
foreach (ShaderFile file in Geometry)
|
foreach (ShaderFile file in Geometry)
|
||||||
file.Compile(shader, ShaderType.GeometryShader);
|
if (!file.Compile(shader, ShaderType.GeometryShader)) return false;
|
||||||
|
|
||||||
foreach (ShaderFile file in Fragment)
|
foreach (ShaderFile file in Fragment)
|
||||||
file.Compile(shader, ShaderType.FragmentShader);
|
if (!file.Compile(shader, ShaderType.FragmentShader)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ namespace SM_TEST
|
||||||
|
|
||||||
private static void Window_RenderFrame(object sender, FrameEventArgs e)
|
private static void Window_RenderFrame(object sender, FrameEventArgs e)
|
||||||
{
|
{
|
||||||
window.Title = Math.Floor(e.Time * 1000) + "ms";
|
window.Title = Math.Round(e.Time * 1000,2) + "ms";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -20,7 +20,7 @@ namespace SM_TEST
|
||||||
MainFramebuffer = CreateWindowFramebuffer(8, PixelInformation.RGBA_HDR, true);
|
MainFramebuffer = CreateWindowFramebuffer(8, PixelInformation.RGBA_HDR, true);
|
||||||
_postBuffer = CreateWindowFramebuffer(0, PixelInformation.RGB_HDR, false);
|
_postBuffer = CreateWindowFramebuffer(0, PixelInformation.RGB_HDR, false);
|
||||||
|
|
||||||
_bloom = new BloomEffect(true)
|
_bloom = new BloomEffect(true, true)
|
||||||
{
|
{
|
||||||
Radius = 20,
|
Radius = 20,
|
||||||
AmountMap = new Texture(new System.Drawing.Bitmap("bloom_amountMap.png"))
|
AmountMap = new Texture(new System.Drawing.Bitmap("bloom_amountMap.png"))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue