mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-08 16:59:59 +01:00
New Blending with pre-multiplied alpha
Finally found how to improve blending modes by pre-multiplying color by alpha in the shader, so that the blending equations can be applied on top of the apha manipulation.
This commit is contained in:
@@ -171,7 +171,7 @@ void ImGuiVisitor::visit(Shader &n)
|
||||
// ImGui::SameLine(0, 5);
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
int mode = n.blending;
|
||||
if (ImGui::Combo("Blending", &mode, "Normal\0Screen\0Inverse\0Addition\0Subtract\0") ) {
|
||||
if (ImGui::Combo("Blending", &mode, "Normal\0Screen\0Subtract\0Multiply\0Soft light\0Soft subtract\0") ) {
|
||||
n.blending = Shader::BlendMode(mode);
|
||||
|
||||
std::ostringstream oss;
|
||||
@@ -180,18 +180,21 @@ void ImGuiVisitor::visit(Shader &n)
|
||||
case Shader::BLEND_OPACITY:
|
||||
oss<<"Normal";
|
||||
break;
|
||||
case Shader::BLEND_ADD:
|
||||
case Shader::BLEND_SCREEN:
|
||||
oss<<"Screen";
|
||||
break;
|
||||
case Shader::BLEND_SUBSTRACT:
|
||||
oss<<"Inverse";
|
||||
break;
|
||||
case Shader::BLEND_LAYER_ADD:
|
||||
oss<<"Addition";
|
||||
break;
|
||||
case Shader::BLEND_LAYER_SUBSTRACT:
|
||||
oss<<"Subtract";
|
||||
break;
|
||||
case Shader::BLEND_MULTIPLY:
|
||||
oss<<"Multiply";
|
||||
break;
|
||||
case Shader::BLEND_SOFT_LIGHT:
|
||||
oss<<"Soft light";
|
||||
break;
|
||||
case Shader::BLEND_SOFT_SUBTRACT:
|
||||
oss<<"Soft subtract";
|
||||
break;
|
||||
case Shader::BLEND_CUSTOM:
|
||||
oss<<"Custom";
|
||||
break;
|
||||
|
||||
@@ -274,7 +274,7 @@ void SessionGroupSource::init()
|
||||
{
|
||||
if ( resolution_.x > 0.f && resolution_.y > 0.f ) {
|
||||
|
||||
session_->setResolution( resolution_ );
|
||||
session_->setResolution( resolution_, true );
|
||||
|
||||
// update to draw framebuffer
|
||||
session_->update( dt_ );
|
||||
@@ -283,7 +283,7 @@ void SessionGroupSource::init()
|
||||
texturesurface_->setTextureIndex( session_->frame()->texture() );
|
||||
|
||||
// create Frame buffer matching size of session
|
||||
FrameBuffer *renderbuffer = new FrameBuffer( session_->frame()->resolution() );
|
||||
FrameBuffer *renderbuffer = new FrameBuffer( session_->frame()->resolution(), true );
|
||||
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
49
Shader.cpp
49
Shader.cpp
@@ -23,11 +23,32 @@
|
||||
ShadingProgram *ShadingProgram::currentProgram_ = nullptr;
|
||||
ShadingProgram simpleShadingProgram("shaders/simple.vs", "shaders/simple.fs");
|
||||
|
||||
// Blending presets for matching with Shader::BlendMode
|
||||
GLenum blending_equation[6] = { GL_FUNC_ADD, GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD};
|
||||
GLenum blending_source_function[6] = { GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA};
|
||||
GLenum blending_destination_function[6] = {GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE, GL_DST_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA};
|
||||
// Blending presets for matching with Shader::BlendModes:
|
||||
GLenum blending_equation[7] = { GL_FUNC_ADD, // normal
|
||||
GL_FUNC_ADD, // screen
|
||||
GL_FUNC_REVERSE_SUBTRACT, // subtract
|
||||
GL_FUNC_ADD, // multiply
|
||||
GL_FUNC_ADD, // soft light
|
||||
GL_FUNC_REVERSE_SUBTRACT, // soft subtract
|
||||
GL_FUNC_ADD};
|
||||
GLenum blending_source_function[7] = { GL_ONE, // normal
|
||||
GL_ONE, // screen
|
||||
GL_SRC_COLOR, // subtract (can be GL_ONE)
|
||||
GL_DST_COLOR, // multiply : src x dst color
|
||||
GL_DST_COLOR, // soft light : src x dst color
|
||||
GL_DST_COLOR, // soft subtract
|
||||
GL_ONE};
|
||||
GLenum blending_destination_function[7] = {GL_ONE_MINUS_SRC_ALPHA,// normal
|
||||
GL_ONE, // screen
|
||||
GL_ONE, // subtract
|
||||
GL_ONE_MINUS_SRC_ALPHA, // multiply
|
||||
GL_ONE, // soft light
|
||||
GL_ONE, // soft subtract
|
||||
GL_ONE_MINUS_SRC_ALPHA};
|
||||
|
||||
//GLenum blending_equation[6] = { GL_FUNC_ADD, GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD};
|
||||
//GLenum blending_source_function[6] = { GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA};
|
||||
//GLenum blending_destination_function[6] = {GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE, GL_DST_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA};
|
||||
|
||||
|
||||
ShadingProgram::ShadingProgram(const std::string& vertex_file, const std::string& fragment_file) : vertex_id_(0), fragment_id_(0), id_(0)
|
||||
@@ -223,18 +244,28 @@ void Shader::use()
|
||||
glEnable(GL_BLEND);
|
||||
// glBlendEquation(blending_equation[BLEND_OPACITY]);
|
||||
// glBlendFunc(blending_source_function[BLEND_OPACITY], blending_destination_function[BLEND_OPACITY]);
|
||||
glBlendEquationSeparate(blending_equation[BLEND_OPACITY], GL_MAX);
|
||||
glBlendFuncSeparate(blending_source_function[BLEND_OPACITY], blending_destination_function[BLEND_OPACITY], GL_SRC_ALPHA, GL_ONE);
|
||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
||||
glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
|
||||
}
|
||||
else if ( blending != BLEND_CUSTOM ) {
|
||||
glEnable(GL_BLEND);
|
||||
// glBlendEquation(blending_equation[blending]);
|
||||
// glBlendFunc(blending_source_function[blending], blending_destination_function[blending]);
|
||||
// different blending for alpha and color
|
||||
glBlendEquationSeparate(blending_equation[blending], GL_MAX);
|
||||
glBlendFuncSeparate(blending_source_function[blending], blending_destination_function[blending], GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
// different blending for alpha and color
|
||||
// glBlendColor(1.f, 1.f, 1.f, 1.f);
|
||||
glBlendEquationSeparate(blending_equation[blending], GL_FUNC_ADD);
|
||||
glBlendFuncSeparate(blending_source_function[blending], blending_destination_function[blending], GL_ONE, GL_ZERO);
|
||||
// glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
||||
// glBlendFuncSeparate( GL_SRC_ALPHA, GL_CONSTANT_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// glBlendEquation(GL_FUNC_ADD);
|
||||
// glBlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||
|
||||
|
||||
// glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
||||
// glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
}
|
||||
else
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
7
Shader.h
7
Shader.h
@@ -60,10 +60,11 @@ public:
|
||||
|
||||
typedef enum {
|
||||
BLEND_OPACITY = 0,
|
||||
BLEND_ADD,
|
||||
BLEND_SCREEN,
|
||||
BLEND_SUBSTRACT,
|
||||
BLEND_LAYER_ADD,
|
||||
BLEND_LAYER_SUBSTRACT,
|
||||
BLEND_MULTIPLY,
|
||||
BLEND_SOFT_LIGHT,
|
||||
BLEND_SOFT_SUBTRACT,
|
||||
BLEND_CUSTOM
|
||||
} BlendMode;
|
||||
BlendMode blending;
|
||||
|
||||
2
View.cpp
2
View.cpp
@@ -257,7 +257,7 @@ MixingView::MixingView() : View(MIXING), limbo_scale_(1.3f)
|
||||
// Mixing scene background
|
||||
Mesh *tmp = new Mesh("mesh/disk.ply");
|
||||
tmp->scale_ = glm::vec3(limbo_scale_, limbo_scale_, 1.f);
|
||||
tmp->shader()->color = glm::vec4( COLOR_LIMBO_CIRCLE, 0.6f );
|
||||
tmp->shader()->color = glm::vec4( COLOR_LIMBO_CIRCLE, 0.7f );
|
||||
scene.bg()->attach(tmp);
|
||||
|
||||
mixingCircle_ = new Mesh("mesh/disk.ply");
|
||||
|
||||
@@ -31,8 +31,9 @@ void main()
|
||||
// alpha is a mix of texture alpha, vertex alpha, and uniform alpha affected by stippling
|
||||
float A = textureColor.a * vertexColor.a * color.a * maskIntensity;
|
||||
A += textureColor.a * stipple * ( int(gl_FragCoord.x + gl_FragCoord.y) % 2 );
|
||||
A = clamp(A, 0.0, 1.0);
|
||||
|
||||
// output RGBA
|
||||
FragColor = vec4(RGB, clamp(A, 0.0, 1.0) );
|
||||
FragColor = vec4(RGB * A, A);
|
||||
// FragColor = texture(iChannel1, vertexUV);
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ void main(void)
|
||||
transformedRGB = LevelsControl(transformedRGB, levels.x, gamma.rgb * gamma.a, levels.y, levels.z, levels.w);
|
||||
|
||||
// apply base color and alpha for final fragment color
|
||||
FragColor = vec4(transformedRGB * vertexColor.rgb * color.rgb, clamp(alpha, 0.0, 1.0) );
|
||||
FragColor = vec4(transformedRGB * vertexColor.rgb * color.rgb * alpha, clamp(alpha, 0.0, 1.0) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user