add color dodge and multiply blending modes shaders, change tmp framebuffer to RGBA32F for better precision and fix the blending problem for the stroke not reaching full opacity

This commit is contained in:
2017-11-11 16:54:21 +00:00
parent 71f18cb292
commit fa4e67617b
4 changed files with 17 additions and 14 deletions

View File

@@ -94,13 +94,15 @@ void App::initShaders()
" sum += textureOffset(t, uv, ivec2(-1, 0));\n"
" sum += textureOffset(t, uv, ivec2(-1, 1));\n"
" sum += textureOffset(t, uv, ivec2( 0, -1));\n"
" sum += textureOffset(t, uv, ivec2( 0, 1));\n"
" sum += textureOffset(t, uv, ivec2( 1, -1));\n"
" sum += textureOffset(t, uv, ivec2( 1, 0));\n"
" sum += textureOffset(t, uv, ivec2( 1, 1));\n"
" return sum / vec4(9.0);\n"
"}\n"
"vec3 blend_colorDodge(vec4 base, vec4 stroke, float alpha_tot) { return mix(stroke.rgb, mix(base.rgb, base.rgb / (1.0 - stroke.rgb), stroke.a / alpha_tot), base.a / alpha_tot); }\n"
"vec3 blend_multiply(vec4 base, vec4 stroke, float alpha_tot) { return mix(stroke.rgb, mix(base.rgb, base.rgb * stroke.rgb, stroke.a / alpha_tot), base.a / alpha_tot); }\n"
"vec3 blend_normal(vec4 base, vec4 stroke, float alpha_tot) { return mix(base.rgb, stroke.rgb, stroke.a / alpha_tot); }\n"
"void main(){\n"
" mediump vec2 uv2 = gl_FragCoord.st / vec2(2048) * 20.0;\n"
" mediump vec4 base = texture(tex, uv.xy);\n"
@@ -108,9 +110,10 @@ void App::initShaders()
" mediump float stencil = pow(texture(tex_stencil, uv2).r, 8.0);\n"
" stroke.a = mask ? stroke.a * alpha * blur(tex_mask, uv.xy).r : stroke.a * alpha;\n"
" if (base.a == 0.0) { frag = stroke; return; }\n"
" mediump float contribution = (1.0 - base.a) * stroke.a;\n"
" mediump float alpha_tot = base.a + contribution;"
" mediump vec3 rgb = mix(base.rgb, stroke.rgb, (stroke.a / alpha_tot));\n"
" mediump vec3 rgb = blend_multiply(base, stroke, alpha_tot);\n"
" frag = vec4(rgb, (lock ? base.a : alpha_tot));\n"
"}\n";
@@ -267,12 +270,12 @@ void App::initShaders()
#else
" mediump vec4 bg = texture(tex_bg, uv2);\n"
#endif
" if (fg.a < 1.0/255.0) { frag = bg; return; }\n"
" mediump float contribution = max((1.0 - bg.a) * fg.a, 1.0/255.0) * stencil;\n"
" if (fg.a == 0.0) discard;\n"
" mediump float contribution = (1.0 - bg.a) * fg.a * stencil;\n"
" mediump float alpha_tot = bg.a + contribution;"
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
" mediump vec4 frag_wet = vec4(rgb, mix(bg.a, max(bg.a, fg.a * stencil), fg.a));\n"
" mediump vec4 frag_dry = vec4(rgb, clamp(alpha_tot, 0.0, 1.0));\n"
" mediump vec4 frag_dry = vec4(rgb, alpha_tot);\n"
" frag = mix(frag_dry, frag_wet, wet);\n"
"}\n";

View File

@@ -710,9 +710,9 @@ void ui::Canvas::resize(int width, int height)
m_height = height;
for (int i = 0; i < 6; i++)
{
m_tmp[i].create(width, height);
m_tex[i].create(width, height);
m_tex2[i].create(width, height);
m_tmp[i].create(width, height, -1, GL_RGBA32F);
m_tex[i].create(width, height, GL_RGBA32F);
m_tex2[i].create(width, height, GL_RGBA8);
}
for (auto& l : m_layers)
{
@@ -725,9 +725,9 @@ bool ui::Canvas::create(int width, int height)
m_height = height;
for (int i = 0; i < 6; i++)
{
m_tmp[i].create(width, height);
m_tex[i].create(width, height);
m_tex2[i].create(width, height); // TODO: destroy before recreating
m_tmp[i].create(width, height, -1, GL_RGBA32F);
m_tex[i].create(width, height, GL_RGBA32F);
m_tex2[i].create(width, height, GL_RGBA8); // TODO: destroy before recreating
}
m_sampler.create(GL_NEAREST);
m_sampler_brush.create();

View File

@@ -40,7 +40,7 @@ void RTT::destroy()
// h = 0;
}
bool RTT::create(int width, int height, int tex/* = -1*/)
bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format)
{
// Destroy any previously created object
destroy();
@@ -60,7 +60,7 @@ bool RTT::create(int width, int height, int tex/* = -1*/)
glBindTexture(GL_TEXTURE_2D, texID);
if (tex == -1)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

View File

@@ -15,7 +15,7 @@ public:
~RTT();
void destroy();
bool create(int width, int height, int tex = -1);
bool create(int width, int height, int tex = -1, GLint internal_format = GL_RGBA8);
bool recreate() { return create(w, h); }
void clear(glm::vec4 color = glm::vec4(0));
void readTextureData(uint8_t* buffer);