From e55f79ccb21e8c1be3d86f127e3ec1583e58ce92 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 18 Nov 2016 23:45:00 +0200 Subject: [PATCH] Move postprocessor shaders to the builtin shaderlib --- shaderlib/ambientocclusion.glsl | 9 ++++ shaderlib/ambientocclusion_combine.glsl | 23 ++++++++ shaderlib/ambientocclusion_occlude.glsl | 23 ++++++++ shaderlib/bloom.glsl | 8 +++ shaderlib/bloom_blur.glsl | 10 ++++ shaderlib/bloom_combine.glsl | 8 +++ shaderlib/colorcurve.glsl | 29 ++++++++++ shaderlib/postprocess.glsl | 12 +++++ source/ambientocclusion.cpp | 72 ++----------------------- source/bloom.cpp | 39 +------------- source/colorcurve.cpp | 38 +------------ source/postprocessor.h | 4 +- source/program.cpp | 11 +++- source/programcompiler.cpp | 5 +- source/resources.cpp | 3 +- source/resources.h | 5 +- 16 files changed, 147 insertions(+), 152 deletions(-) create mode 100644 shaderlib/ambientocclusion.glsl create mode 100644 shaderlib/ambientocclusion_combine.glsl create mode 100644 shaderlib/ambientocclusion_occlude.glsl create mode 100644 shaderlib/bloom.glsl create mode 100644 shaderlib/bloom_blur.glsl create mode 100644 shaderlib/bloom_combine.glsl create mode 100644 shaderlib/colorcurve.glsl create mode 100644 shaderlib/postprocess.glsl diff --git a/shaderlib/ambientocclusion.glsl b/shaderlib/ambientocclusion.glsl new file mode 100644 index 00000000..0ca81a40 --- /dev/null +++ b/shaderlib/ambientocclusion.glsl @@ -0,0 +1,9 @@ +uniform sampler2D depth; +uniform sampler2D occlusion; +uniform sampler2D rotate; +uniform AmbientOcclusionParams +{ + vec2 screen_size; + vec2 depth_ratio; + float darkness; +}; diff --git a/shaderlib/ambientocclusion_combine.glsl b/shaderlib/ambientocclusion_combine.glsl new file mode 100644 index 00000000..572ba2f1 --- /dev/null +++ b/shaderlib/ambientocclusion_combine.glsl @@ -0,0 +1,23 @@ +import postprocess; +import ambientocclusion; + +////// fragment +void main() +{ + float sample = depth_ratio.x/(texture(depth, texcoord).r-depth_ratio.y); + float sum = 1.0; + float count = 1.0; + for(int i=0; i<=3; ++i) + for(int j=0; j<=3; ++j) + { + vec2 offs = vec2(float(i)-1.5, float(j)-1.5)/screen_size; + float dxy = length(offs)*-sample; + float dz = depth_ratio.x/(texture(depth, texcoord+offs).r-depth_ratio.y)-sample; + if(abs(dz)<3.0*dxy) + { + sum += texture(occlusion, texcoord+offs).r; + count += 1.0; + } + } + frag_color = texture(source, texcoord)*sum/count; +} diff --git a/shaderlib/ambientocclusion_occlude.glsl b/shaderlib/ambientocclusion_occlude.glsl new file mode 100644 index 00000000..f9b755c9 --- /dev/null +++ b/shaderlib/ambientocclusion_occlude.glsl @@ -0,0 +1,23 @@ +import postprocess; +import ambientocclusion; + +////// fragment +void main() +{ + mat2 transform = mat2(texture(rotate, texcoord*screen_size/4.0)*2.0-1.0) + *mat2(screen_size.y/screen_size.x, 0.0, 0.0, 1.0)*3.0/screen_size.y; + float sample = depth_ratio.x/(texture(depth, texcoord).r-depth_ratio.y); + float sum = 0.0; + for(int i=0; i<=3; ++i) + for(int j=0; j<=3; ++j) + { + vec2 offs = transform*vec2(float(i)-1.5, float(j)-1.5); + float dxy = length(offs)*-sample; + float dz = depth_ratio.x/(texture(depth, texcoord+offs).r-depth_ratio.y)-sample; + if(abs(dz)<3.0*dxy) + sum += atan(dz/dxy)/1.570796; + else if(dz<0.0) + sum -= 0.8; + } + frag_color = vec4(min(1.0-sum*darkness/16.0, 1.0), 0.0, 0.0, 1.0); +} diff --git a/shaderlib/bloom.glsl b/shaderlib/bloom.glsl new file mode 100644 index 00000000..9b63d2ef --- /dev/null +++ b/shaderlib/bloom.glsl @@ -0,0 +1,8 @@ +uniform sampler2D blurred; +uniform BloomParams +{ + vec2 delta; + float factors[19]; + int size; + float strength; +}; diff --git a/shaderlib/bloom_blur.glsl b/shaderlib/bloom_blur.glsl new file mode 100644 index 00000000..958a5301 --- /dev/null +++ b/shaderlib/bloom_blur.glsl @@ -0,0 +1,10 @@ +import postprocess; +import bloom; + +////// fragment +void main() +{ + frag_color = vec4(0.0, 0.0, 0.0, 0.0); + for(int i=0; i<=size*2; ++i) + frag_color += texture(source, texcoord+delta*float(i-size))*factors[i]; +} diff --git a/shaderlib/bloom_combine.glsl b/shaderlib/bloom_combine.glsl new file mode 100644 index 00000000..4e46776d --- /dev/null +++ b/shaderlib/bloom_combine.glsl @@ -0,0 +1,8 @@ +import postprocess; +import bloom; + +////// fragment +void main() +{ + frag_color = mix(texture(source, texcoord), texture(blurred, texcoord), strength); +} diff --git a/shaderlib/colorcurve.glsl b/shaderlib/colorcurve.glsl new file mode 100644 index 00000000..fa3ba510 --- /dev/null +++ b/shaderlib/colorcurve.glsl @@ -0,0 +1,29 @@ +import postprocess; + +uniform sampler1D curve; +uniform ToneMapping +{ + float peak; + float brightness; +}; + +////// fragment +void main() +{ + vec4 sample = texture(source, texcoord); + float maxc = max(sample.r, max(sample.g, sample.b)); + if(maxc>1.0-peak) + { + vec3 saturated = sample.rgb/maxc; + if(maxc>1.0+peak) + { + sample.rgb = mix(vec3(1.0), saturated, 1.0/pow(brightness, maxc-1.0-peak)); + } + else + { + float x = (1.0+peak-maxc)/(2.0*peak); + sample.rgb = saturated.rgb*(1.0-peak+(1.0-x*x)*peak); + } + } + frag_color = vec4(texture(curve, sample.r).r, texture(curve, sample.g).r, texture(curve, sample.b).r, sample.a); +} diff --git a/shaderlib/postprocess.glsl b/shaderlib/postprocess.glsl new file mode 100644 index 00000000..cb657947 --- /dev/null +++ b/shaderlib/postprocess.glsl @@ -0,0 +1,12 @@ +uniform sampler2D source; + +////// vertex +in vec4 vertex; +void main() +{ + gl_Position = vertex; + out vec2 texcoord = vertex.xy*0.5+0.5; +} + +////// fragment +out vec4 frag_color; diff --git a/source/ambientocclusion.cpp b/source/ambientocclusion.cpp index 444b18b8..bad204a9 100644 --- a/source/ambientocclusion.cpp +++ b/source/ambientocclusion.cpp @@ -5,80 +5,14 @@ #include "shader.h" #include "tests.h" -namespace { - -const char occlude_fs[] = - "uniform sampler2D depth;\n" - "uniform sampler2D rotate;\n" - "uniform vec2 screen_size;\n" - "uniform vec2 depth_ratio;\n" - "uniform float darkness;\n" - "varying vec2 texcoord;\n" - "void main()\n" - "{\n" - " mat2 transform = mat2(texture2D(rotate, texcoord*screen_size/4.0)*2.0-1.0)\n" - " *mat2(screen_size.y/screen_size.x, 0.0, 0.0, 1.0)*3.0/screen_size.y;\n" - " float sample = depth_ratio.x/(texture2D(depth, texcoord).r-depth_ratio.y);\n" - " float sum = 0.0;\n" - " for(int i=0; i<=3; ++i)\n" - " for(int j=0; j<=3; ++j)\n" - " {\n" - " vec2 offs = transform*vec2(float(i)-1.5, float(j)-1.5);\n" - " float dxy = length(offs)*-sample;\n" - " float dz = depth_ratio.x/(texture2D(depth, texcoord+offs).r-depth_ratio.y)-sample;\n" - " if(abs(dz)<3.0*dxy)\n" - " sum += atan(dz/dxy)/1.570796;\n" - " else if(dz<0.0)\n" - " sum -= 0.8;\n" - " }\n" - " gl_FragColor = vec4(min(1.0-sum*darkness/16.0, 1.0), 0.0, 0.0, 1.0);\n" - "}\n"; - -const char combine_fs[] = - "uniform sampler2D color;\n" - "uniform sampler2D depth;\n" - "uniform sampler2D occlusion;\n" - "uniform vec2 screen_size;\n" - "uniform vec2 depth_ratio;\n" - "varying vec2 texcoord;\n" - "void main()\n" - "{\n" - " float sample = depth_ratio.x/(texture2D(depth, texcoord).r-depth_ratio.y);\n" - " float sum = 1.0;\n" - " float count = 1.0;\n" - " for(int i=0; i<=3; ++i)\n" - " for(int j=0; j<=3; ++j)\n" - " {\n" - " vec2 offs = vec2(float(i)-1.5, float(j)-1.5)/screen_size;\n" - " float dxy = length(offs)*-sample;\n" - " float dz = depth_ratio.x/(texture2D(depth, texcoord+offs).r-depth_ratio.y)-sample;\n" - " if(abs(dz)<3.0*dxy)\n" - " {\n" - " sum += texture2D(occlusion, texcoord+offs).r;\n" - " count += 1.0;\n" - " }\n" - " }\n" - " gl_FragColor = texture2D(color, texcoord)*sum/count;\n" - "}\n"; - -} - namespace Msp { namespace GL { AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float depth_ratio): + occlude_shader("ambientocclusion_occlude.glsl"), + combine_shader("ambientocclusion_combine.glsl"), quad(get_fullscreen_quad()) { - occlude_shader.attach_shader(get_fullscreen_vertex_shader()); - occlude_shader.attach_shader_owned(new FragmentShader(occlude_fs)); - occlude_shader.bind_attribute(get_component_type(VERTEX2), "vertex"); - occlude_shader.link(); - - combine_shader.attach_shader(get_fullscreen_vertex_shader()); - combine_shader.attach_shader_owned(new FragmentShader(combine_fs)); - combine_shader.bind_attribute(get_component_type(VERTEX2), "vertex"); - combine_shader.link(); - occlusion.storage(RGB, w, h); occlusion.set_min_filter(NEAREST); occlusion.set_mag_filter(NEAREST); @@ -110,7 +44,7 @@ AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float depth_ratio): occlude_shdata.uniform("rotate", 1); occlude_shdata.uniform("screen_size", static_cast(w), static_cast(h)); - combine_shdata.uniform("color", 1); + combine_shdata.uniform("source", 1); combine_shdata.uniform("depth", 0); combine_shdata.uniform("occlusion", 2); combine_shdata.uniform("screen_size", static_cast(w), static_cast(h)); diff --git a/source/bloom.cpp b/source/bloom.cpp index 286730b9..58edc65d 100644 --- a/source/bloom.cpp +++ b/source/bloom.cpp @@ -9,49 +9,14 @@ using namespace std; -namespace { - -static const char blur_fs[]= - "uniform sampler2D source;\n" - "uniform vec2 delta;\n" - "uniform float factors[19];\n" - "uniform int size;\n" - "varying vec2 texcoord;\n" - "void main()\n" - "{\n" - " gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" - " for(int i=0; i<=size*2; ++i)\n" - " gl_FragColor += texture2D(source, texcoord+delta*float(i-size))*factors[i];\n" - "}"; - -static const char combine_fs[]= - "uniform sampler2D source;\n" - "uniform sampler2D blurred;\n" - "uniform float strength;\n" - "varying vec2 texcoord;\n" - "void main()\n" - "{\n" - " gl_FragColor = mix(texture2D(source, texcoord), texture2D(blurred, texcoord), strength);\n" - "}"; - -} - namespace Msp { namespace GL { Bloom::Bloom(unsigned w, unsigned h): + blur_shader("bloom_blur.glsl"), + combine_shader("bloom_combine.glsl"), quad(get_fullscreen_quad()) { - blur_shader.attach_shader(get_fullscreen_vertex_shader()); - blur_shader.attach_shader_owned(new FragmentShader(blur_fs)); - blur_shader.bind_attribute(get_component_type(VERTEX2), "vertex"); - blur_shader.link(); - - combine_shader.attach_shader(get_fullscreen_vertex_shader()); - combine_shader.attach_shader_owned(new FragmentShader(combine_fs)); - combine_shader.bind_attribute(get_component_type(VERTEX2), "vertex"); - combine_shader.link(); - blur_shdata[0].uniform("delta", 1.0f/w, 0.0f); blur_shdata[1].uniform("delta", 0.0f, 1.0f/h); diff --git a/source/colorcurve.cpp b/source/colorcurve.cpp index 1c76e1eb..ad2c51ca 100644 --- a/source/colorcurve.cpp +++ b/source/colorcurve.cpp @@ -7,48 +7,14 @@ using namespace std; -namespace { - -static const char fragment_src[] = - "uniform sampler2D texture;\n" - "uniform sampler1D curve;\n" - "uniform float peak;\n" - "uniform float brightness;\n" - "varying vec2 texcoord;\n" - "void main()\n" - "{\n" - " vec4 sample = texture2D(texture, texcoord);\n" - " float maxc = max(sample.r, max(sample.g, sample.b));\n" - " if(maxc>1.0-peak)\n" - " {\n" - " vec3 saturated = sample.rgb/maxc;\n" - " if(maxc>1.0+peak)\n" - " {\n" - " sample.rgb = mix(vec3(1.0), saturated, 1.0/pow(brightness, maxc-1.0-peak));\n" - " }\n" - " else\n" - " {\n" - " float x = (1.0+peak-maxc)/(2.0*peak);\n" - " sample.rgb = saturated.rgb*(1.0-peak+(1.0-x*x)*peak);\n" - " }\n" - " }\n" - " gl_FragColor = vec4(texture1D(curve, sample.r).r, texture1D(curve, sample.g).r, texture1D(curve, sample.b).r, sample.a);\n" - "}"; - -} - namespace Msp { namespace GL { ColorCurve::ColorCurve(): + shprog("colorcurve.glsl"), quad(get_fullscreen_quad()) { - shprog.attach_shader(get_fullscreen_vertex_shader()); - shprog.attach_shader_owned(new FragmentShader(fragment_src)); - shprog.bind_attribute(get_component_type(VERTEX2), "vertex"); - shprog.link(); - - shdata.uniform("texture", 0); + shdata.uniform("source", 0); shdata.uniform("curve", 1); curve.storage(LUMINANCE, 256); diff --git a/source/postprocessor.h b/source/postprocessor.h index 0666dd46..ffc9045d 100644 --- a/source/postprocessor.h +++ b/source/postprocessor.h @@ -27,7 +27,9 @@ protected: /** Returns a vertex shader suitable for rendering a full-screen quad. Input vertices are assumed to be in normalized device coordinates; no transform is performed. The shader provides a varying vec2 texcoord for - a fragment shader to access textures. */ + a fragment shader to access textures. + + Deprecated in favor of the builtin postprocess.glsl module. */ static Shader &get_fullscreen_vertex_shader(); /** Returns a mesh consisting of a single quad, covering the entire screen. diff --git a/source/program.cpp b/source/program.cpp index 2d298e82..11ab151b 100644 --- a/source/program.cpp +++ b/source/program.cpp @@ -15,6 +15,7 @@ #include "misc.h" #include "program.h" #include "programcompiler.h" +#include "resources.h" #include "shader.h" using namespace std; @@ -41,7 +42,15 @@ Program::Program(const std::string &source) init(); ProgramCompiler compiler; - compiler.compile(source); + if(source.find(';')==string::npos && source.size()>5 && !source.compare(source.size()-5, 5, ".glsl")) + { + if(RefPtr io = Resources::get_builtins().open(source)) + compiler.compile(*io); + else + throw IO::file_not_found(source); + } + else + compiler.compile(source); compiler.add_shaders(*this); link(); } diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index d6586931..13c73e4a 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -123,9 +123,8 @@ void ProgramCompiler::process() void ProgramCompiler::import(const string &name) { - if(!resources) - throw runtime_error("no resources"); - RefPtr io = resources->open_raw(name+".glsl"); + string fn = name+".glsl"; + RefPtr io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn)); if(!io) throw runtime_error(format("module %s not found", name)); ProgramParser import_parser; diff --git a/source/resources.cpp b/source/resources.cpp index 8f3b4b8b..6f5b0712 100644 --- a/source/resources.cpp +++ b/source/resources.cpp @@ -1,3 +1,4 @@ +#include #include #include #include "animation.h" @@ -49,7 +50,7 @@ Resources::Resources(): add_source(get_builtins()); } -DataFile::BuiltinSource &Resources::get_builtins() +const DataFile::CollectionSource &Resources::get_builtins() { static DataFile::BuiltinSource builtins; bool init_done = false; diff --git a/source/resources.h b/source/resources.h index 838b0229..c0529b58 100644 --- a/source/resources.h +++ b/source/resources.h @@ -1,7 +1,6 @@ #ifndef MSP_GL_RESOURCES_H_ #define MSP_GL_RESOURCES_H_ -#include #include #include "texture.h" @@ -27,10 +26,8 @@ private: public: Resources(); -private: - static DataFile::BuiltinSource &get_builtins(); + static const DataFile::CollectionSource &get_builtins(); -public: void set_default_texture_filter(TextureFilter); /** Enables or disables sRGB conversion. If enabled, textures and material -- 2.45.2