Blend Modes
The Smudge API is still changing pretty often. Code on this post is out of date.
Smudge now has initial support for per-channel masking and per-buffer blend modes.
Channel masking allows you to prevent data from being written to a channel by setting the material’s channel value to undefined
.
// draw 1.0 to the red and green channel but leave the blue channel alone
let example_mat = new Material(1.0, 1.0, undefined, 1.0);
Blend modes control how material properties are composited. You can set a different blend mode for each major buffer: albedo
, metallic
, smoothness
, height
, emissive
. Currently Smudge supports normal alpha blending, additive blending, and subtractive blending. Multiply, min, and max are up next.
These two features make some powerful effects much easier to achieve. For example in my earlier paint-splatter sketch, the paint had a fixed height regardless of what was under it. By setting the paint material to use additive blending for the height channel and normal blending for color, a natural looking paint build up can achieved.
let example_mat = new Material(1.0, 1.0, 1.0, 1.0);
example_mat.height = .1;
example_mat.height_blending = Material.AdditiveBlending;
//pollock2.png
import PBR from '../pbr2';
import { Material } from '../pbr2';
export default function draw() {
let pbr = new PBR(undefined, 1024, 1024, 1);
const clear_mat = new Material(0.6, 0.6, 0.7, 1.0, 0.0, 0.4, 0.0);
pbr.clear(clear_mat);
const paint = new Material(1.0, 1.0, 0.9, 1.0);
paint.metallic = .2;
paint.smoothness = .7;
paint.height = .002;
paint.height_blending = Material.AdditiveBlending;
for (let line = 0; line < 10; line++) {
let x = pbr.width * .5;
let y = pbr.height * .5;
let a = Math.random(0, 6.28);
let deltaA = 0;
for (let i = 0; i < 5000; i++) {
x += Math.sin(a) * 1;
y += Math.cos(a) * 1;
a += deltaA;
deltaA += random(-.002, .002);
pbr.rect(x, y, 10, 10, paint);
pbr.rect(x+1, y+1, 8, 8, paint);
pbr.rect(x+2, y+2, 6, 6, paint);
}
}
pbr.show();
}
function random(min = 0, max = 1) {
return Math.random() * (max - min) + min;
}
function randomMiddle(min, max) {
let r = Math.random() + Math.random() + Math.random();
r /= 3;
return min + r * (max - min);
}