Multiple blending fixes & improvements by JakubValtar · Pull Request #2921 · processing/processing
Alpha 80 (other modes than REPLACE, BLEND, ADD and SUBTRACT are not comparable as JAVA2D uses SRC alpha to interpolate between DST and OUTPUT, OpenGL just uses OUTPUT)

PGraphics java2d; PGraphics p2d; int[] blendModes = {REPLACE, BLEND, ADD, SUBTRACT, LIGHTEST, DARKEST, EXCLUSION, MULTIPLY, SCREEN}; String[] blendLabels = {"REPLACE", "BLEND", "ADD", "SUBTRACT", "LIGHTEST", "DARKEST", "EXCLUSION", "MULTIPLY", "SCREEN"}; public void setup() { size(900,900, P2D); frame.setAlwaysOnTop(true); java2d = createGraphics(300, 800 / blendModes.length); p2d = createGraphics(300, 800 / blendModes.length, P2D); } public void draw() { background(0xFF000000); stroke(100); for (int x = 0; x < width; x += 20) { line(x, 0, x, height); } for (int y = 0; y < width; y += 20) { line(0, y, width, y); } blendMode(BLEND); textSize(25); text("JAVA2D", 350, 30); text("P2D", 655, 30); for (int i = 0; i < blendModes.length; i++) { text(blendLabels[i], 50, 50 + (i + 0.5f) * (java2d.height + 5)); drawPG(java2d, blendModes[i]); image(java2d, 250, 50 + i * (java2d.height + 5)); flush(); drawPG(p2d, blendModes[i]); image(p2d, 555, 50 + i * (p2d.height + 5)); flush(); } } void drawPG(PGraphics pg, int blendMode) { pg.beginDraw(); pg.noStroke(); pg.blendMode(blendMode); switch (blendMode) { case ADD: case LIGHTEST: case SCREEN: pg.background(0); break; default: pg.background(255); } int alpha = 80; int green1 = blendMode == DARKEST ? 255 : 0; int green2 = blendMode == DARKEST ? 0 : 255; for (int x = 0; x < pg.width; x += 12) { for(int y = 0; y < pg.height; y += 12) { int red = (int) map(x, 0, pg.width, 0, 255); int green = (int) map(y*x, 0, pg.height * pg.width, green1, green2); int blue = (int) map(x, 0, pg.height, 0, 255) % 255; pg.fill(red, green, blue, alpha); pg.rect(x, y, 12, pg.height - y); } } pg.flush(); pg.endDraw(); }