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];
}
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
#endif // SHADER_PROGRAM_HPP

View File

@ -139,6 +139,13 @@ void MyGlWindow::multipassSetup()
_multipassManager.bindToFrameBuffer(GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, "depth_tex");
_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()
@ -235,7 +242,7 @@ void MyGlWindow::draw()
for (auto it = meshes.begin(); it != meshes.end(); it++)
(*it).second->draw(_scnctx);
_multipassManager.shader.addUniform("sobel", true);
_multipassManager.shader.enableSubroutine("sobel_filter");
_multipassManager.drawResultToScreen(_scnctx);
//skybox.draw(shaders["Skybox"], _scnctx);
}

View File

@ -19,6 +19,16 @@ void Shader::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)
{
if ((uniformFlags & ShaderFlags::KA_FLAG) == ShaderFlags::KA_FLAG)

View File

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

View File

@ -5,12 +5,10 @@ in vec2 uv;
out vec4 final_color;
uniform sampler2D tex;
uniform bool depth;
uniform bool blur;
uniform bool sharpen;
uniform bool sepia;
uniform bool grayscale;
uniform bool sobel;
subroutine vec4 shading_t(vec4 color);
subroutine uniform shading_t Shading;
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)
);
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
);
subroutine(shading_t)
vec4 sepia(vec4 color)
{
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[](
-1, -1, -1,
-1, 9, -1,
-1, -1, -1
);
subroutine(shading_t)
vec4 grayscale(vec4 color)
{
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 zFar = 2000.0f; // zFar of your perspective projection
float depth = texture(tex, uv).x;
return (2.0 * zNear) / (zFar + zNear - depth * (zFar - zNear));
float depth = color.x;
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);
for (int i = 0; i < 9; 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++)
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[](
-1, 0, 1,
@ -81,42 +99,45 @@ vec3 sobel_filter(vec3 color)
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()
{
//rrra because depth textures are not usual textures, they have only one channel
final_color = (depth) ? texture(tex, uv).rrra : texture(tex, uv).rgba;
if (depth) {
float d;
d = LinearizeDepth(uv);
final_color = vec4(d,d,d,1.0);
}
else if (blur)
{
final_color = vec4(blurring_func(uv), 1);
}
else if (sharpen)
{
final_color = vec4(sharpening_func(uv));
}
else if (sepia)
{
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,
final_color.r * .272 + final_color.g * .534 + final_color.b * .131, 1.0);
}
else if (grayscale)
{
float average = final_color.r * 0.2126 + final_color.g * 0.7152 + final_color.b * 0.0722;
final_color = vec4(average, average, average, 1.0);
}
else if (sobel)
{
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);
}
final_color = texture(tex, uv).rgba;
final_color = Shading(final_color);
// if (depth) {
// float d;
// d = LinearizeDepth(uv);
// final_color = vec4(d,d,d,1.0);
// }
// else if (blur)
// {
// final_color = vec4(blurring_func(uv), 1);
// }
// else if (sharpen)
// {
// final_color = vec4(sharpening_func(uv));
// }
// else if (sepia)
// {
// 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,
// final_color.r * .272 + final_color.g * .534 + final_color.b * .131, 1.0);
// }
// else if (grayscale)
// {
// float average = final_color.r * 0.2126 + final_color.g * 0.7152 + final_color.b * 0.0722;
// final_color = vec4(average, average, average, 1.0);
// }
// else if (sobel)
// {
// 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);
// }
}