summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp82
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h3
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp13
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp19
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp2
-rw-r--r--drivers/gles3/shaders/tonemap.glsl448
6 files changed, 282 insertions, 285 deletions
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 6e451eabcd..ef7858b4ca 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -52,7 +52,9 @@ OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID
}
#endif
-Error AudioDriverCoreAudio::init_device() {
+Error AudioDriverCoreAudio::init() {
+ mutex = Mutex::create();
+
AudioComponentDescription desc;
zeromem(&desc, sizeof(desc));
desc.componentType = kAudioUnitType_Output;
@@ -69,6 +71,16 @@ Error AudioDriverCoreAudio::init_device() {
OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
+#ifdef OSX_ENABLED
+ AudioObjectPropertyAddress prop;
+ prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
+ prop.mScope = kAudioObjectPropertyScopeGlobal;
+ prop.mElement = kAudioObjectPropertyElementMaster;
+
+ result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+#endif
+
AudioStreamBasicDescription strdesc;
zeromem(&strdesc, sizeof(strdesc));
@@ -135,42 +147,6 @@ Error AudioDriverCoreAudio::init_device() {
return OK;
}
-Error AudioDriverCoreAudio::finish_device() {
- OSStatus result;
-
- if (active) {
- result = AudioOutputUnitStop(audio_unit);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- active = false;
- }
-
- result = AudioUnitUninitialize(audio_unit);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- return OK;
-}
-
-Error AudioDriverCoreAudio::init() {
- OSStatus result;
-
- mutex = Mutex::create();
- active = false;
- channels = 2;
-
-#ifdef OSX_ENABLED
- AudioObjectPropertyAddress prop;
- prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
- prop.mScope = kAudioObjectPropertyScopeGlobal;
- prop.mElement = kAudioObjectPropertyElementMaster;
-
- result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-#endif
-
- return init_device();
-};
-
OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
@@ -370,6 +346,7 @@ void AudioDriverCoreAudio::set_device(String device) {
}
if (!found) {
+ // If we haven't found the desired device get the system default one
UInt32 size = sizeof(AudioDeviceID);
AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
@@ -406,7 +383,28 @@ bool AudioDriverCoreAudio::try_lock() {
void AudioDriverCoreAudio::finish() {
OSStatus result;
- finish_device();
+ lock();
+
+ AURenderCallbackStruct callback;
+ zeromem(&callback, sizeof(AURenderCallbackStruct));
+ result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
+ if (result != noErr) {
+ ERR_PRINT("AudioUnitSetProperty failed");
+ }
+
+ if (active) {
+ result = AudioOutputUnitStop(audio_unit);
+ if (result != noErr) {
+ ERR_PRINT("AudioOutputUnitStop failed");
+ }
+
+ active = false;
+ }
+
+ result = AudioUnitUninitialize(audio_unit);
+ if (result != noErr) {
+ ERR_PRINT("AudioUnitUninitialize failed");
+ }
#ifdef OSX_ENABLED
AudioObjectPropertyAddress prop;
@@ -420,13 +418,13 @@ void AudioDriverCoreAudio::finish() {
}
#endif
- AURenderCallbackStruct callback;
- zeromem(&callback, sizeof(AURenderCallbackStruct));
- result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
+ result = AudioComponentInstanceDispose(audio_unit);
if (result != noErr) {
- ERR_PRINT("AudioUnitSetProperty failed");
+ ERR_PRINT("AudioComponentInstanceDispose failed");
}
+ unlock();
+
if (mutex) {
memdelete(mutex);
mutex = NULL;
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
index c44e225521..99c910498e 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.h
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -68,9 +68,6 @@ class AudioDriverCoreAudio : public AudioDriver {
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
- Error init_device();
- Error finish_device();
-
public:
const char *get_name() const {
return "CoreAudio";
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index cc8e3277b9..d5232a6511 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -733,6 +733,9 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
int w = current_clip->final_clip_rect.size.x;
int h = current_clip->final_clip_rect.size.y;
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP])
+ y = current_clip->final_clip_rect.position.y;
+
glScissor(x, y, w, h);
reclip = false;
@@ -821,7 +824,10 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
if (current_clip) {
glEnable(GL_SCISSOR_TEST);
- glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
+ int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y);
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP])
+ y = current_clip->final_clip_rect.position.y;
+ glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
} else {
glDisable(GL_SCISSOR_TEST);
}
@@ -969,7 +975,10 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
if (reclip) {
glEnable(GL_SCISSOR_TEST);
- glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
+ int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y);
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP])
+ y = current_clip->final_clip_rect.position.y;
+ glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
}
p_item_list = p_item_list->next;
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index c2377e0c3e..f214943bcf 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -1000,13 +1000,11 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
glEnable(GL_SCISSOR_TEST);
//glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
//current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
-
- int x = current_clip->final_clip_rect.position.x;
int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y);
- int w = current_clip->final_clip_rect.size.x;
- int h = current_clip->final_clip_rect.size.y;
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP])
+ y = current_clip->final_clip_rect.position.y;
- glScissor(x, y, w, h);
+ glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.x, current_clip->final_clip_rect.size.y);
reclip = false;
}
@@ -1141,7 +1139,11 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
if (current_clip) {
glEnable(GL_SCISSOR_TEST);
- glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
+ int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y);
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP])
+ y = current_clip->final_clip_rect.position.y;
+
+ glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.x, current_clip->final_clip_rect.size.y);
} else {
@@ -1518,7 +1520,10 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
if (reclip) {
glEnable(GL_SCISSOR_TEST);
- glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
+ int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y);
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP])
+ y = current_clip->final_clip_rect.position.y;
+ glScissor(current_clip->final_clip_rect.position.x, y, current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
}
p_item_list = p_item_list->next;
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 191c587d98..4a3ebf7a7c 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -3862,7 +3862,7 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
multimesh->data.resize(format_floats * p_instances);
- for (int i = 0; i < p_instances; i += format_floats) {
+ for (int i = 0; i < p_instances * format_floats; i += format_floats) {
int color_from = 0;
int custom_data_from = 0;
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl
index a75871f08e..63475c9039 100644
--- a/drivers/gles3/shaders/tonemap.glsl
+++ b/drivers/gles3/shaders/tonemap.glsl
@@ -1,28 +1,27 @@
[vertex]
-
-layout(location=0) in highp vec4 vertex_attrib;
-layout(location=4) in vec2 uv_in;
+layout (location = 0) in highp vec4 vertex_attrib;
+layout (location = 4) in vec2 uv_in;
out vec2 uv_interp;
-void main() {
-
+void main()
+{
gl_Position = vertex_attrib;
+
uv_interp = uv_in;
-#ifdef V_FLIP
- uv_interp.y = 1.0-uv_interp.y;
-#endif
+ #ifdef V_FLIP
+ uv_interp.y = 1.0f - uv_interp.y;
+ #endif
}
[fragment]
#if !defined(GLES_OVER_GL)
-precision mediump float;
+ precision mediump float;
#endif
-
in vec2 uv_interp;
uniform highp sampler2D source; //texunit:0
@@ -31,297 +30,286 @@ uniform float exposure;
uniform float white;
#ifdef USE_AUTO_EXPOSURE
-
-uniform highp sampler2D source_auto_exposure; //texunit:1
-uniform highp float auto_exposure_grey;
-
+ uniform highp sampler2D source_auto_exposure; //texunit:1
+ uniform highp float auto_exposure_grey;
#endif
#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7)
+ #define USING_GLOW // only use glow when at least one glow level is selected
-uniform highp sampler2D source_glow; //texunit:2
-uniform highp float glow_intensity;
-
+ uniform highp sampler2D source_glow; //texunit:2
+ uniform highp float glow_intensity;
#endif
#ifdef USE_BCS
-
-uniform vec3 bcs;
-
+ uniform vec3 bcs;
#endif
#ifdef USE_COLOR_CORRECTION
-
-uniform sampler2D color_correction; //texunit:3
-
+ uniform sampler2D color_correction; //texunit:3
#endif
-
-layout(location = 0) out vec4 frag_color;
+layout (location = 0) out vec4 frag_color;
#ifdef USE_GLOW_FILTER_BICUBIC
+ // w0, w1, w2, and w3 are the four cubic B-spline basis functions
+ float w0(float a)
+ {
+ return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f);
+ }
-// w0, w1, w2, and w3 are the four cubic B-spline basis functions
-float w0(float a)
-{
- return (1.0/6.0)*(a*(a*(-a + 3.0) - 3.0) + 1.0);
-}
-
-float w1(float a)
-{
- return (1.0/6.0)*(a*a*(3.0*a - 6.0) + 4.0);
-}
-
-float w2(float a)
-{
- return (1.0/6.0)*(a*(a*(-3.0*a + 3.0) + 3.0) + 1.0);
-}
-
-float w3(float a)
-{
- return (1.0/6.0)*(a*a*a);
-}
-
-// g0 and g1 are the two amplitude functions
-float g0(float a)
-{
- return w0(a) + w1(a);
-}
+ float w1(float a)
+ {
+ return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f);
+ }
-float g1(float a)
-{
- return w2(a) + w3(a);
-}
+ float w2(float a)
+ {
+ return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f);
+ }
-// h0 and h1 are the two offset functions
-float h0(float a)
-{
- return -1.0 + w1(a) / (w0(a) + w1(a));
-}
+ float w3(float a)
+ {
+ return (1.0f / 6.0f) * (a * a * a);
+ }
-float h1(float a)
-{
- return 1.0 + w3(a) / (w2(a) + w3(a));
-}
+ // g0 and g1 are the two amplitude functions
+ float g0(float a)
+ {
+ return w0(a) + w1(a);
+ }
-uniform ivec2 glow_texture_size;
+ float g1(float a)
+ {
+ return w2(a) + w3(a);
+ }
-vec4 texture2D_bicubic(sampler2D tex, vec2 uv,int p_lod)
-{
- float lod=float(p_lod);
- vec2 tex_size = vec2(glow_texture_size >> p_lod);
- vec2 pixel_size =1.0/tex_size;
- uv = uv*tex_size + 0.5;
- vec2 iuv = floor( uv );
- vec2 fuv = fract( uv );
-
- float g0x = g0(fuv.x);
- float g1x = g1(fuv.x);
- float h0x = h0(fuv.x);
- float h1x = h1(fuv.x);
- float h0y = h0(fuv.y);
- float h1y = h1(fuv.y);
-
- vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - 0.5) * pixel_size;
- vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - 0.5) * pixel_size;
- vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - 0.5) * pixel_size;
- vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - 0.5) * pixel_size;
-
- return g0(fuv.y) * (g0x * textureLod(tex, p0,lod) +
- g1x * textureLod(tex, p1,lod)) +
- g1(fuv.y) * (g0x * textureLod(tex, p2,lod) +
- g1x * textureLod(tex, p3,lod));
-}
+ // h0 and h1 are the two offset functions
+ float h0(float a)
+ {
+ return -1.0f + w1(a) / (w0(a) + w1(a));
+ }
+ float h1(float a)
+ {
+ return 1.0f + w3(a) / (w2(a) + w3(a));
+ }
+ uniform ivec2 glow_texture_size;
-#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) texture2D_bicubic(m_tex,m_uv,m_lod)
+ vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod)
+ {
+ float lod = float(p_lod);
+ vec2 tex_size = vec2(glow_texture_size >> p_lod);
+ vec2 pixel_size = vec2(1.0f) / tex_size;
+
+ uv = uv * tex_size + vec2(0.5f);
+
+ vec2 iuv = floor(uv);
+ vec2 fuv = fract(uv);
+
+ float g0x = g0(fuv.x);
+ float g1x = g1(fuv.x);
+ float h0x = h0(fuv.x);
+ float h1x = h1(fuv.x);
+ float h0y = h0(fuv.y);
+ float h1y = h1(fuv.y);
+
+ vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5f)) * pixel_size;
+ vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5f)) * pixel_size;
+ vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5f)) * pixel_size;
+ vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5f)) * pixel_size;
+
+ return g0(fuv.y) * (g0x * textureLod(tex, p0,lod) +
+ g1x * textureLod(tex, p1,lod)) +
+ g1(fuv.y) * (g0x * textureLod(tex, p2,lod) +
+ g1x * textureLod(tex, p3,lod));
+ }
+ #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2D_bicubic(m_tex, m_uv, m_lod)
#else
-
-#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) textureLod(m_tex,m_uv,float(m_lod))
-
+ #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) textureLod(m_tex, m_uv, float(m_lod))
#endif
+vec3 tonemap_filmic(vec3 color, float white)
+{
+ const float A = 0.15f;
+ const float B = 0.50f;
+ const float C = 0.10f;
+ const float D = 0.20f;
+ const float E = 0.02f;
+ const float F = 0.30f;
+ const float W = 11.2f;
+
+ vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F;
+ float white_tonemapped = ((white * (A * white + C * B) + D * E) / (white * (A * white + B) + D * F)) - E / F;
+
+ return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f));
+}
-vec3 tonemap_filmic(vec3 color,float white) {
-
- float A = 0.15;
- float B = 0.50;
- float C = 0.10;
- float D = 0.20;
- float E = 0.02;
- float F = 0.30;
- float W = 11.2;
-
- vec3 coltn = ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F;
- float whitetn = ((white*(A*white+C*B)+D*E)/(white*(A*white+B)+D*F))-E/F;
+vec3 tonemap_aces(vec3 color, float white)
+{
+ const float A = 2.51f;
+ const float B = 0.03f;
+ const float C = 2.43f;
+ const float D = 0.59f;
+ const float E = 0.14f;
- return coltn/whitetn;
+ vec3 color_tonemapped = (color * (A * color + B)) / (color * (C * color + D) + E);
+ float white_tonemapped = (white * (A * white + B)) / (white * (C * white + D) + E);
+ return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f));
}
-vec3 tonemap_aces(vec3 color) {
- float a = 2.51f;
- float b = 0.03f;
- float c = 2.43f;
- float d = 0.59f;
- float e = 0.14f;
- return color = clamp((color*(a*color+b))/(color*(c*color+d)+e),vec3(0.0),vec3(1.0));
+vec3 tonemap_reindhart(vec3 color, float white)
+{
+ return clamp((color) / (1.0f + color) * (1.0f + (color / (white))), vec3(0.0f), vec3(1.0f)); // whitepoint is probably not in linear space here!
}
-vec3 tonemap_reindhart(vec3 color,float white) {
-
- return ( color * ( 1.0 + ( color / ( white) ) ) ) / ( 1.0 + color );
+vec3 linear_to_srgb(vec3 color) // convert linear rgb to srgb, assumes clamped input in range [0;1]
+{
+ const vec3 a = vec3(0.055f);
+ return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
}
-void main() {
-
- vec4 color = textureLod(source, uv_interp, 0.0);
-
-#ifdef USE_AUTO_EXPOSURE
-
- color/=texelFetch(source_auto_exposure,ivec2(0,0),0).r/auto_exposure_grey;
-#endif
-
- color*=exposure;
-
-#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7)
-#define USING_GLOW
-#endif
-
-#if defined(USING_GLOW)
- vec3 glow = vec3(0.0);
-
-#ifdef USE_GLOW_LEVEL1
-
- glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,1).rgb;
-#endif
-
-#ifdef USE_GLOW_LEVEL2
- glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,2).rgb;
-#endif
-
-#ifdef USE_GLOW_LEVEL3
- glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,3).rgb;
-#endif
-
-#ifdef USE_GLOW_LEVEL4
- glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,4).rgb;
-#endif
-
-#ifdef USE_GLOW_LEVEL5
- glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,5).rgb;
-#endif
-
-#ifdef USE_GLOW_LEVEL6
- glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,6).rgb;
-#endif
-
-#ifdef USE_GLOW_LEVEL7
- glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,7).rgb;
-#endif
-
-
- glow *= glow_intensity;
+vec3 apply_tonemapping(vec3 color, float white) // inputs are LINEAR, always outputs clamped [0;1] color
+{
+ #ifdef USE_REINDHART_TONEMAPPER
+ return tonemap_reindhart(color, white);
+ #endif
-#endif
+ #ifdef USE_FILMIC_TONEMAPPER
+ return tonemap_filmic(color, white);
+ #endif
+ #ifdef USE_ACES_TONEMAPPER
+ return tonemap_aces(color, white);
+ #endif
-#ifdef USE_REINDHART_TONEMAPPER
+ return clamp(color, vec3(0.0f), vec3(1.0f)); // no other seleced -> linear
+}
- color.rgb = tonemap_reindhart(color.rgb,white);
+vec3 gather_glow(sampler2D tex, vec2 uv) // sample all selected glow levels
+{
+ vec3 glow = vec3(0.0f);
-# if defined(USING_GLOW)
- glow = tonemap_reindhart(glow,white);
-# endif
+ #ifdef USE_GLOW_LEVEL1
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 1).rgb;
+ #endif
-#endif
+ #ifdef USE_GLOW_LEVEL2
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 2).rgb;
+ #endif
-#ifdef USE_FILMIC_TONEMAPPER
+ #ifdef USE_GLOW_LEVEL3
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 3).rgb;
+ #endif
- color.rgb = tonemap_filmic(color.rgb,white);
+ #ifdef USE_GLOW_LEVEL4
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 4).rgb;
+ #endif
-# if defined(USING_GLOW)
- glow = tonemap_filmic(glow,white);
-# endif
+ #ifdef USE_GLOW_LEVEL5
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 5).rgb;
+ #endif
-#endif
+ #ifdef USE_GLOW_LEVEL6
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb;
+ #endif
-#ifdef USE_ACES_TONEMAPPER
+ #ifdef USE_GLOW_LEVEL7
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 7).rgb;
+ #endif
- color.rgb = tonemap_aces(color.rgb);
+ return glow;
+}
-# if defined(USING_GLOW)
- glow = tonemap_aces(glow);
-# endif
+vec3 apply_glow(vec3 color, vec3 glow) // apply glow using the selected blending mode
+{
+ #ifdef USE_GLOW_REPLACE
+ color = glow;
+ #endif
-#endif
+ #ifdef USE_GLOW_SCREEN
+ color = max((color + glow) - (color * glow), vec3(0.0));
+ #endif
-#ifdef KEEP_3D_LINEAR
- // leave color as is...
-#else
- //regular Linear -> SRGB conversion
- vec3 a = vec3(0.055);
- color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308)));
-#endif
+ #ifdef USE_GLOW_SOFTLIGHT
+ glow = glow * vec3(0.5f) + vec3(0.5f);
-#if defined(USING_GLOW)
- glow = mix( (vec3(1.0)+a)*pow(glow,vec3(1.0/2.4))-a , 12.92*glow , lessThan(glow,vec3(0.0031308)));
-#endif
+ color.r = (glow.r <= 0.5f) ? (color.r - (1.0f - 2.0f * glow.r) * color.r * (1.0f - color.r)) : (((glow.r > 0.5f) && (color.r <= 0.25f)) ? (color.r + (2.0f * glow.r - 1.0f) * (4.0f * color.r * (4.0f * color.r + 1.0f) * (color.r - 1.0f) + 7.0f * color.r)) : (color.r + (2.0f * glow.r - 1.0f) * (sqrt(color.r) - color.r)));
+ color.g = (glow.g <= 0.5f) ? (color.g - (1.0f - 2.0f * glow.g) * color.g * (1.0f - color.g)) : (((glow.g > 0.5f) && (color.g <= 0.25f)) ? (color.g + (2.0f * glow.g - 1.0f) * (4.0f * color.g * (4.0f * color.g + 1.0f) * (color.g - 1.0f) + 7.0f * color.g)) : (color.g + (2.0f * glow.g - 1.0f) * (sqrt(color.g) - color.g)));
+ color.b = (glow.b <= 0.5f) ? (color.b - (1.0f - 2.0f * glow.b) * color.b * (1.0f - color.b)) : (((glow.b > 0.5f) && (color.b <= 0.25f)) ? (color.b + (2.0f * glow.b - 1.0f) * (4.0f * color.b * (4.0f * color.b + 1.0f) * (color.b - 1.0f) + 7.0f * color.b)) : (color.b + (2.0f * glow.b - 1.0f) * (sqrt(color.b) - color.b)));
+ #endif
-//glow needs to be added in SRGB space (together with image space effects)
+ #if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) // no other selected -> additive
+ color += glow;
+ #endif
- color.rgb = clamp(color.rgb,0.0,1.0);
+ return color;
+}
-#if defined(USING_GLOW)
- glow = clamp(glow,0.0,1.0);
-#endif
+vec3 apply_bcs(vec3 color, vec3 bcs)
+{
+ color = mix(vec3(0.0f), color, bcs.x);
+ color = mix(vec3(0.5f), color, bcs.y);
+ color = mix(vec3(dot(vec3(1.0f), color) * 0.33333f), color, bcs.z);
-#ifdef USE_GLOW_REPLACE
+ return color;
+}
- color.rgb = glow;
+vec3 apply_color_correction(vec3 color, sampler2D correction_tex)
+{
+ color.r = texture(correction_tex, vec2(color.r, 0.0f)).r;
+ color.g = texture(correction_tex, vec2(color.g, 0.0f)).g;
+ color.b = texture(correction_tex, vec2(color.b, 0.0f)).b;
-#endif
+ return color;
+}
-#ifdef USE_GLOW_SCREEN
+void main()
+{
+ vec3 color = textureLod(source, uv_interp, 0.0f).rgb;
- color.rgb = max((color.rgb + glow) - (color.rgb * glow), vec3(0.0));
+ // Exposure
-#endif
+ #ifdef USE_AUTO_EXPOSURE
+ color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / auto_exposure_grey;
+ #endif
-#ifdef USE_GLOW_SOFTLIGHT
+ color *= exposure;
- {
+ // Early Tonemap & SRGB Conversion
- glow = (glow * 0.5) + 0.5;
- color.r = (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r)));
- color.g = (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g)));
- color.b = (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b)));
- }
+ color = apply_tonemapping(color, white);
-#endif
+ #ifdef KEEP_3D_LINEAR
+ // leave color as is (-> don't convert to SRGB)
+ #else
+ color = linear_to_srgb(color); // regular linear -> SRGB conversion
+ #endif
-#if defined(USING_GLOW) && !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE)
- //additive
- color.rgb+=glow;
-#endif
+ // Glow
-#ifdef USE_BCS
+ #ifdef USING_GLOW
+ vec3 glow = gather_glow(source_glow, uv_interp) * glow_intensity;
- color.rgb = mix(vec3(0.0),color.rgb,bcs.x);
- color.rgb = mix(vec3(0.5),color.rgb,bcs.y);
- color.rgb = mix(vec3(dot(vec3(1.0),color.rgb)*0.33333),color.rgb,bcs.z);
+ // high dynamic range -> SRGB
+ glow = apply_tonemapping(glow, white);
+ glow = linear_to_srgb(glow);
-#endif
+ color = apply_glow(color, glow);
+ #endif
-#ifdef USE_COLOR_CORRECTION
+ // Additional effects
- color.r = texture(color_correction,vec2(color.r,0.0)).r;
- color.g = texture(color_correction,vec2(color.g,0.0)).g;
- color.b = texture(color_correction,vec2(color.b,0.0)).b;
-#endif
+ #ifdef USE_BCS
+ color = apply_bcs(color, bcs);
+ #endif
+ #ifdef USE_COLOR_CORRECTION
+ color = apply_color_correction(color, color_correction);
+ #endif
- frag_color=vec4(color.rgb,1.0);
+ frag_color = vec4(color, 1.0f);
}