Added shader subroutine basic handling

This commit is contained in:
Hugo Willaume 2019-04-17 09:40:28 +09:00
parent c4776edba1
commit 615d58e12f
5 changed files with 117 additions and 62 deletions

View File

@ -390,6 +390,21 @@ public:
return uniformMap[uniformName]; return uniformMap[uniformName];
} }
std::map<std::string, GLuint> _subroutine_map;
int addSubroutine(GLenum shadertype, const std::string uniformName)
{
_subroutine_map[uniformName] = glGetSubroutineIndex(programId, shadertype, uniformName.c_str());
return _subroutine_map[uniformName];
}
void enableSubroutine(const std::string uniformName)
{
use();
glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &_subroutine_map[uniformName]);
disable();
}
}; // End of class }; // End of class
#endif // SHADER_PROGRAM_HPP #endif // SHADER_PROGRAM_HPP

View File

@ -139,6 +139,13 @@ void MyGlWindow::multipassSetup()
_multipassManager.bindToFrameBuffer(GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, "depth_tex"); _multipassManager.bindToFrameBuffer(GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, "depth_tex");
_multipassManager.setDrawBuffers(); _multipassManager.setDrawBuffers();
_multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "depthing");
_multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "blurring");
_multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "sharpening");
_multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "sepia");
_multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "grayscale");
_multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "sobel_filter");
} }
void MyGlWindow::setup() void MyGlWindow::setup()
@ -235,7 +242,7 @@ void MyGlWindow::draw()
for (auto it = meshes.begin(); it != meshes.end(); it++) for (auto it = meshes.begin(); it != meshes.end(); it++)
(*it).second->draw(_scnctx); (*it).second->draw(_scnctx);
_multipassManager.shader.addUniform("sobel", true); _multipassManager.shader.enableSubroutine("sobel_filter");
_multipassManager.drawResultToScreen(_scnctx); _multipassManager.drawResultToScreen(_scnctx);
//skybox.draw(shaders["Skybox"], _scnctx); //skybox.draw(shaders["Skybox"], _scnctx);
} }

View File

@ -19,6 +19,16 @@ void Shader::disable()
_program.disable(); _program.disable();
} }
int Shader::addSubroutine(GLenum shadertype, const std::string uniformName)
{
return _program.addSubroutine(shadertype, uniformName);
}
void Shader::enableSubroutine(const std::string uniformName)
{
return _program.enableSubroutine(uniformName);
}
void Shader::setMaterial(SceneContext ctx) void Shader::setMaterial(SceneContext ctx)
{ {
if ((uniformFlags & ShaderFlags::KA_FLAG) == ShaderFlags::KA_FLAG) if ((uniformFlags & ShaderFlags::KA_FLAG) == ShaderFlags::KA_FLAG)

View File

@ -40,6 +40,9 @@ public:
void enable(); void enable();
void disable(); void disable();
int addSubroutine(GLenum shadertype, const std::string uniformName);
void enableSubroutine(const std::string uniformName);
public: public:
void setUniforms(SceneContext ctx); void setUniforms(SceneContext ctx);
@ -78,7 +81,6 @@ private:
void setMaterial(SceneContext ctx); void setMaterial(SceneContext ctx);
void setCamera(SceneContext ctx); void setCamera(SceneContext ctx);
void setLights(SceneContext ctx); void setLights(SceneContext ctx);
private:
ShaderProgram _program; ShaderProgram _program;
}; };

View File

@ -5,12 +5,10 @@ in vec2 uv;
out vec4 final_color; out vec4 final_color;
uniform sampler2D tex; uniform sampler2D tex;
uniform bool depth;
uniform bool blur;
uniform bool sharpen; subroutine vec4 shading_t(vec4 color);
uniform bool sepia; subroutine uniform shading_t Shading;
uniform bool grayscale;
uniform bool sobel;
const float f = 1.0 / 300.0; const float f = 1.0 / 300.0;
@ -20,45 +18,65 @@ vec2 offsets[9] = vec2[](
vec2(-f, -f), vec2(0.0, -f), vec2(f, -f) vec2(-f, -f), vec2(0.0, -f), vec2(f, -f)
); );
float blur_kernel[9] = float[]( subroutine(shading_t)
1.0 / 16, 2.0 / 16, 1.0 / 16, vec4 sepia(vec4 color)
2.0 / 16, 4.0 / 16, 2.0 / 16, {
1.0 / 16, 2.0 / 16, 1.0 / 16 return vec4(color.r * .393 + color.g * .769 + color.b * .189,
); color.r * .349 + color.g * .686 + color.b * .168,
color.r * .272 + color.g * .534 + color.b * .131, 1.0);
}
float sharp_kernel[9] = float[]( subroutine(shading_t)
-1, -1, -1, vec4 grayscale(vec4 color)
-1, 9, -1, {
-1, -1, -1 float average = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;
); return vec4(average, average, average, 1);
}
float LinearizeDepth(in vec2 uv) subroutine(shading_t)
vec4 depthing(vec4 color)
{ {
float zNear = 0.1f; // zNear of your perspective projection float zNear = 0.1f; // zNear of your perspective projection
float zFar = 2000.0f; // zFar of your perspective projection float zFar = 2000.0f; // zFar of your perspective projection
float depth = texture(tex, uv).x; float depth = color.x;
return (2.0 * zNear) / (zFar + zNear - depth * (zFar - zNear)); float r = (2.0 * zNear) / (zFar + zNear - depth * (zFar - zNear));
return vec4(r, r, r, 1);
} }
vec3 blurring_func(in vec2 uv) subroutine(shading_t)
vec4 blurring(vec4 color)
{ {
float blur_kernel[9] = float[](
1.0 / 16, 2.0 / 16, 1.0 / 16,
2.0 / 16, 4.0 / 16, 2.0 / 16,
1.0 / 16, 2.0 / 16, 1.0 / 16
);
vec3 texblur = vec3(0,0,0); vec3 texblur = vec3(0,0,0);
for (int i = 0; i < 9; i++) for (int i = 0; i < 9; i++)
texblur += vec3(texture(tex, uv + offsets[i]).rgb * blur_kernel[i]); texblur += vec3(texture(tex, uv + offsets[i]).rgb * blur_kernel[i]);
return texblur; return vec4(texblur, 1);
} }
vec4 sharpening_func(in vec2 uv) subroutine(shading_t)
vec4 sharpening(vec4 color)
{ {
vec4 texsharp = vec4(0,0,0,0); float sharp_kernel[9] = float[](
-1, -1, -1,
-1, 9, -1,
-1, -1, -1
);
vec3 texsharp = vec3(0,0,0);
for (uint i = 0; i < 9; i++) for (uint i = 0; i < 9; i++)
texsharp += texture(tex, uv + offsets[i]).rgba * sharp_kernel[i]; texsharp += texture(tex, uv + offsets[i]).rgb * sharp_kernel[i];
return texsharp; return vec4(texsharp, 1);
} }
vec3 sobel_filter(vec3 color) subroutine(shading_t)
vec4 sobel_filter(vec4 color)
{ {
float sobel_x[9] = float[]( float sobel_x[9] = float[](
-1, 0, 1, -1, 0, 1,
@ -81,42 +99,45 @@ vec3 sobel_filter(vec3 color)
vec_y += texture(tex, uv + offsets[i]).rgb * sobel_y[i]; vec_y += texture(tex, uv + offsets[i]).rgb * sobel_y[i];
} }
return sqrt(vec_x * vec_x + vec_y * vec_y); vec4 sobeled = vec4(sqrt(vec_x * vec_x + vec_y * vec_y), 1);
return grayscale(sobeled);
} }
void main() void main()
{ {
//rrra because depth textures are not usual textures, they have only one channel //rrra because depth textures are not usual textures, they have only one channel
final_color = (depth) ? texture(tex, uv).rrra : texture(tex, uv).rgba; final_color = texture(tex, uv).rgba;
if (depth) { final_color = Shading(final_color);
float d;
d = LinearizeDepth(uv); // if (depth) {
final_color = vec4(d,d,d,1.0); // float d;
} // d = LinearizeDepth(uv);
else if (blur) // final_color = vec4(d,d,d,1.0);
{ // }
final_color = vec4(blurring_func(uv), 1); // else if (blur)
} // {
else if (sharpen) // final_color = vec4(blurring_func(uv), 1);
{ // }
final_color = vec4(sharpening_func(uv)); // else if (sharpen)
} // {
else if (sepia) // final_color = vec4(sharpening_func(uv));
{ // }
final_color = vec4(final_color.r * .393 + final_color.g * .769 + final_color.b * .189, // else if (sepia)
final_color.r * .349 + final_color.g * .686 + final_color.b * .168, // {
final_color.r * .272 + final_color.g * .534 + final_color.b * .131, 1.0); // final_color = vec4(final_color.r * .393 + final_color.g * .769 + final_color.b * .189,
} // final_color.r * .349 + final_color.g * .686 + final_color.b * .168,
else if (grayscale) // final_color.r * .272 + final_color.g * .534 + final_color.b * .131, 1.0);
{ // }
float average = final_color.r * 0.2126 + final_color.g * 0.7152 + final_color.b * 0.0722; // else if (grayscale)
final_color = vec4(average, average, average, 1.0); // {
} // float average = final_color.r * 0.2126 + final_color.g * 0.7152 + final_color.b * 0.0722;
else if (sobel) // final_color = vec4(average, average, average, 1.0);
{ // }
vec3 sobeled = sobel_filter(final_color.rgb); // else if (sobel)
float average = sobeled.r * 0.2126 + sobeled.g * 0.7152 + sobeled.b * 0.0722; // {
final_color = vec4(average, average, average, 1.0); // vec3 sobeled = sobel_filter(final_color.rgb);
} // float average = sobeled.r * 0.2126 + sobeled.g * 0.7152 + sobeled.b * 0.0722;
// final_color = vec4(average, average, average, 1.0);
// }
} }