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:
@@ -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";
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user