v4k-git-backup/demos/art/fx/fxTonemapIlford.fs

46 lines
1.5 KiB
Forth
Raw Normal View History

#define lerp(a,b,c) mix(a,b,c)
#define saturate(c) clamp(c, 0.0, 1.0)
// This function approximates the black and white film stock
// "Ilford FP4" pushed to 400 ISO. It is typical for noir style. This
// tonal transformation does not approximate gamma 2.2, so an explicit
// sRGB transform should be performed before display.
//
// vec3 hdr (IN): Color pixel in linear space
// vec2 uv (IN): Screen space UV for vignette
//
// returns Filmic remapped pixel in gamma 1.0 space
// src: pic.twitter.com/7ZSMM5RRMz
//
vec3 PostFilmic_IlfordFp4Push(vec3 c, vec2 uv) {
// film curve coefficients
const vec3 cb = vec3( 0.0307479, 0.00030400, -0.04458630);
const vec3 de = vec3(-0.0095000, -0.00162400, -0.01736670);
const vec3 df = vec3( 0.1493590, 0.21412400, 1.85780000);
const vec3 ef = vec3(-0.0636051, -0.00758438, -0.00934798);
c = c * c * 1.88; // quick approximation of skip bleach
// remap color channels
vec3 ax = vec3(2.36691,5.14272,0.49020)*c;
vec3 pn = (c*(ax+cb)+de);
vec3 pd = (c*(ax+vec3(0.022,0.004,-0.10543))+df);
// collapse color channels
float pr = dot(saturate(pn/pd),vec3(0.45,0.45,0.45));
// vignette
float pv = saturate(pow(1.0 - dot(uv-.5, uv-.5), -.758) + -.23);
float x = lerp(pr,pr*pr*pr,pv); // done
return vec3(x,x,x);
}
out vec4 color;
void main(void) {
vec2 uv = TEXCOORD.st;
vec4 src = texture2D(iChannel0, uv);
color = vec4( PostFilmic_IlfordFp4Push(src.xyz, uv), src.a);
}