mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-13 11:19:58 +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::SameLine(0, 5);
|
||||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||||
int mode = n.blending;
|
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);
|
n.blending = Shader::BlendMode(mode);
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
@@ -180,18 +180,21 @@ void ImGuiVisitor::visit(Shader &n)
|
|||||||
case Shader::BLEND_OPACITY:
|
case Shader::BLEND_OPACITY:
|
||||||
oss<<"Normal";
|
oss<<"Normal";
|
||||||
break;
|
break;
|
||||||
case Shader::BLEND_ADD:
|
case Shader::BLEND_SCREEN:
|
||||||
oss<<"Screen";
|
oss<<"Screen";
|
||||||
break;
|
break;
|
||||||
case Shader::BLEND_SUBSTRACT:
|
case Shader::BLEND_SUBSTRACT:
|
||||||
oss<<"Inverse";
|
|
||||||
break;
|
|
||||||
case Shader::BLEND_LAYER_ADD:
|
|
||||||
oss<<"Addition";
|
|
||||||
break;
|
|
||||||
case Shader::BLEND_LAYER_SUBSTRACT:
|
|
||||||
oss<<"Subtract";
|
oss<<"Subtract";
|
||||||
break;
|
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:
|
case Shader::BLEND_CUSTOM:
|
||||||
oss<<"Custom";
|
oss<<"Custom";
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ void SessionGroupSource::init()
|
|||||||
{
|
{
|
||||||
if ( resolution_.x > 0.f && resolution_.y > 0.f ) {
|
if ( resolution_.x > 0.f && resolution_.y > 0.f ) {
|
||||||
|
|
||||||
session_->setResolution( resolution_ );
|
session_->setResolution( resolution_, true );
|
||||||
|
|
||||||
// update to draw framebuffer
|
// update to draw framebuffer
|
||||||
session_->update( dt_ );
|
session_->update( dt_ );
|
||||||
@@ -283,7 +283,7 @@ void SessionGroupSource::init()
|
|||||||
texturesurface_->setTextureIndex( session_->frame()->texture() );
|
texturesurface_->setTextureIndex( session_->frame()->texture() );
|
||||||
|
|
||||||
// create Frame buffer matching size of session
|
// 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
|
// set the renderbuffer of the source and attach rendering nodes
|
||||||
attach(renderbuffer);
|
attach(renderbuffer);
|
||||||
|
|||||||
49
Shader.cpp
49
Shader.cpp
@@ -23,11 +23,32 @@
|
|||||||
ShadingProgram *ShadingProgram::currentProgram_ = nullptr;
|
ShadingProgram *ShadingProgram::currentProgram_ = nullptr;
|
||||||
ShadingProgram simpleShadingProgram("shaders/simple.vs", "shaders/simple.fs");
|
ShadingProgram simpleShadingProgram("shaders/simple.vs", "shaders/simple.fs");
|
||||||
|
|
||||||
// Blending presets for matching with Shader::BlendMode
|
// Blending presets for matching with Shader::BlendModes:
|
||||||
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_equation[7] = { GL_FUNC_ADD, // normal
|
||||||
GLenum blending_source_function[6] = { GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA};
|
GL_FUNC_ADD, // screen
|
||||||
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};
|
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)
|
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);
|
glEnable(GL_BLEND);
|
||||||
// glBlendEquation(blending_equation[BLEND_OPACITY]);
|
// glBlendEquation(blending_equation[BLEND_OPACITY]);
|
||||||
// glBlendFunc(blending_source_function[BLEND_OPACITY], blending_destination_function[BLEND_OPACITY]);
|
// glBlendFunc(blending_source_function[BLEND_OPACITY], blending_destination_function[BLEND_OPACITY]);
|
||||||
glBlendEquationSeparate(blending_equation[BLEND_OPACITY], GL_MAX);
|
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
|
||||||
glBlendFuncSeparate(blending_source_function[BLEND_OPACITY], blending_destination_function[BLEND_OPACITY], GL_SRC_ALPHA, GL_ONE);
|
glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if ( blending != BLEND_CUSTOM ) {
|
else if ( blending != BLEND_CUSTOM ) {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
// glBlendEquation(blending_equation[blending]);
|
// glBlendEquation(blending_equation[blending]);
|
||||||
// glBlendFunc(blending_source_function[blending], blending_destination_function[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
|
else
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|||||||
7
Shader.h
7
Shader.h
@@ -60,10 +60,11 @@ public:
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
BLEND_OPACITY = 0,
|
BLEND_OPACITY = 0,
|
||||||
BLEND_ADD,
|
BLEND_SCREEN,
|
||||||
BLEND_SUBSTRACT,
|
BLEND_SUBSTRACT,
|
||||||
BLEND_LAYER_ADD,
|
BLEND_MULTIPLY,
|
||||||
BLEND_LAYER_SUBSTRACT,
|
BLEND_SOFT_LIGHT,
|
||||||
|
BLEND_SOFT_SUBTRACT,
|
||||||
BLEND_CUSTOM
|
BLEND_CUSTOM
|
||||||
} BlendMode;
|
} BlendMode;
|
||||||
BlendMode blending;
|
BlendMode blending;
|
||||||
|
|||||||
2
View.cpp
2
View.cpp
@@ -257,7 +257,7 @@ MixingView::MixingView() : View(MIXING), limbo_scale_(1.3f)
|
|||||||
// Mixing scene background
|
// Mixing scene background
|
||||||
Mesh *tmp = new Mesh("mesh/disk.ply");
|
Mesh *tmp = new Mesh("mesh/disk.ply");
|
||||||
tmp->scale_ = glm::vec3(limbo_scale_, limbo_scale_, 1.f);
|
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);
|
scene.bg()->attach(tmp);
|
||||||
|
|
||||||
mixingCircle_ = new Mesh("mesh/disk.ply");
|
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
|
// alpha is a mix of texture alpha, vertex alpha, and uniform alpha affected by stippling
|
||||||
float A = textureColor.a * vertexColor.a * color.a * maskIntensity;
|
float A = textureColor.a * vertexColor.a * color.a * maskIntensity;
|
||||||
A += textureColor.a * stipple * ( int(gl_FragCoord.x + gl_FragCoord.y) % 2 );
|
A += textureColor.a * stipple * ( int(gl_FragCoord.x + gl_FragCoord.y) % 2 );
|
||||||
|
A = clamp(A, 0.0, 1.0);
|
||||||
|
|
||||||
// output RGBA
|
// output RGBA
|
||||||
FragColor = vec4(RGB, clamp(A, 0.0, 1.0) );
|
FragColor = vec4(RGB * A, A);
|
||||||
// FragColor = texture(iChannel1, vertexUV);
|
// 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);
|
transformedRGB = LevelsControl(transformedRGB, levels.x, gamma.rgb * gamma.a, levels.y, levels.z, levels.w);
|
||||||
|
|
||||||
// apply base color and alpha for final fragment color
|
// 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