1. Coloring

Coloring #

1. Introducción #

En este parte del taller se busca implimentar distintos modos de mezcla de colores mediante el uso de fragment shaders.

2. Revisión bibligráfica #

Color blending #

Existen distitas formas de realizar un color blending o mezcla de colores, los cuales son usados en distintos softwares de edición de gráficos como Adobe Photoshop.

a y b son vectores de 3 posiciones, donde cada una de estas corresponde al valor en el espacio de color RGB.

\(a = (R_1, G_1, B_1), b = (R_2, G_2, B_2)\)

Los modos usados en esta implementación son:

Multiplicación #

  • \(f = ab\)

Adición \(f = a + b\) #

  • \(f = a + b\)

Diferencia #

  • \(f = max(a,b) - min(a,b)\)

Más oscuro #

  • \(f = min(a,b)\)

Más claro #

  • \(f = max(a,b)\)

3. Métodos #

Para la realización de este tema hicimos uso de los conceptos anteriormente expuestos, de tal forma que se presenta una implementación de distintos modos de color blending o mezcla de colores, junto con la variación del brillo para el color resultante de la operación.

4. Resultados #

Shader
precision mediump float;

uniform float brightness;
uniform vec4 uMaterial1;
uniform vec4 uMaterial2;
uniform int blendTool;

void main() {
  if(blendTool == 0){
    gl_FragColor = brightness * (uMaterial1 * uMaterial2);
  }
  else if(blendTool == 1){
    gl_FragColor = brightness * (uMaterial1 + uMaterial2);
  }
  else if(blendTool == 2){
    gl_FragColor = brightness * (max(uMaterial1, uMaterial2) - min(uMaterial1, uMaterial2));
  }
  /*else if(blendTool == 3){
    gl_FragColor = brightness * (uMaterial1 / uMaterial2);
  }*/
  else if(blendTool == 3){
    gl_FragColor = brightness * min(uMaterial1, uMaterial2);
  }
  else{
    gl_FragColor = brightness * max(uMaterial1, uMaterial2);
  }

}
colorBlend.js
let blendShader;
let brightness;
let color1, color2;
let radius;

const blendingMode = {
  "Multiply": 0,
  "Addition": 1,
  "Difference": 2,
  //"Divide": 3,
  "Darken": 3,
  "Lighten": 4,
}

// This values allow that the original colors (from color pickers) 
// to be unaffected from the color blending operation.
//
// These are the neutral elements of the operation.
const neutral = {
  "Multiply": [1.0, 1.0, 1.0, 1.0],
  "Addition": [0.0, 0.0, 0.0, 0.0],
  "Difference": [0.0, 0.0, 0.0, 0.0],
  //"Divide": [1.0, 1.0, 1.0, 1.0],
  "Darken": [1.0, 1.0, 1.0, 1.0],
  "Lighten": [0.0, 0.0, 0.0, 0.0],
}

let blendingModeSelection;

function preload() {
  blendShader = readShader(
    '/VisualComputing2022_2/sketches/Taller3/Coloring/colorBlend.frag', 
    { matrices: Tree.NONE, varyings: Tree.NONE }
  );
}

function setup() {
  createCanvas(500, 500, WEBGL);
  colorMode(RGB, 1);
  rectMode(RADIUS);
  radius = width / 5;
  noStroke();

  color1 = createColorPicker(color('#2a65b4'));
  color1.position(10, 10);
  color2 = createColorPicker(color('#cc0a30'));
  color2.position(width / 2 + 10, 10);

  brightness = createSlider(0, 1, 1, 0.05);
  brightness.position(width / 2 + 30, height / 2);
  brightness.style('width', '80px');

  shader(blendShader);

  blendingModeSelection = createSelect();
  blendingModeSelection.position(width / 2 - 90, height / 2);
  blendingModeSelection.option('Multiply');
  blendingModeSelection.option('Addition');
  blendingModeSelection.option('Difference');
  blendingModeSelection.option('Darken');
  blendingModeSelection.option('Lighten');

  blendingModeSelection.changed(() => {
      let option = blendingMode[blendingModeSelection.value()];
      blendShader.setUniform("blendTool", option)
  });

  
}

function draw() {
  let l = 0.8;
  let offset = (1 - l) / 2;
  let color1Color = color1.color();
  let color2Color = color2.color();
  background(0);

  let indentityColor = neutral[blendingModeSelection.value()];

  blendShader.setUniform('uMaterial1', [red(color1Color), green(color1Color), blue(color1Color), 1.0]);
  blendShader.setUniform('uMaterial2', indentityColor);
  blendShader.setUniform('brightness', 1.0);

  beginShape();
  vertex(-offset - l, +offset, 0);
  vertex(-offset, +offset, 0);
  vertex(-offset, +offset + l, 0);
  vertex(-offset - l, +offset + l, 0);
  endShape();

  blendShader.setUniform('uMaterial1', indentityColor);
  blendShader.setUniform('uMaterial2', [red(color2Color), green(color2Color), blue(color2Color), 1.0]);
  blendShader.setUniform('brightness', 1.0);
  
  beginShape();
  vertex(+offset, +offset, 0);
  vertex(+offset + l, +offset, 0);
  vertex(+offset + l, +offset + l, 0);
  vertex(+offset, +offset + l, 0);
  endShape();
  
  blendShader.setUniform('uMaterial1', [red(color1Color), green(color1Color), blue(color1Color), 1.0]);
  blendShader.setUniform('uMaterial2', [red(color2Color), green(color2Color), blue(color2Color), 1.0]);
  blendShader.setUniform('brightness', brightness.value());
  
  beginShape();
  vertex(-l / 2, -offset - l, 0);
  vertex(+l / 2, -offset - l, 0);
  vertex(+l / 2, -offset, 0);
  vertex(-l / 2, -offset, 0);
  endShape();
}

5. Conclusiones #

  • El color blending es una tecnica usada en distintos softwares de edición de gráficos como Adobe Photoshop, por lo que hay gran cantidad modos distintos a los implementados en este ejercicio, es por esto que se pueden llegar a ampliar la cantidad de modos en este ejercicio.

Referencias #