Add film grain and tonemap filters
This commit is contained in:
26
orx-fx/src/main/kotlin/grain/FilmGrain.kt
Normal file
26
orx-fx/src/main/kotlin/grain/FilmGrain.kt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import org.openrndr.draw.Filter
|
||||||
|
import org.openrndr.draw.Shader
|
||||||
|
import org.openrndr.extra.fx.filterFragmentCode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Film grain filter
|
||||||
|
*/
|
||||||
|
class FilmGrain : Filter(Shader.createFromCode(Filter.filterVertexCode, filterFragmentCode("grain/film-grain.frag"))) {
|
||||||
|
var useColor: Boolean by parameters
|
||||||
|
var time: Double by parameters;
|
||||||
|
var grainLiftRatio: Double by parameters
|
||||||
|
var grainStrength: Double by parameters
|
||||||
|
var grainRate: Double by parameters
|
||||||
|
var grainPitch: Double by parameters
|
||||||
|
var colorLevel: Double by parameters
|
||||||
|
|
||||||
|
init {
|
||||||
|
useColor = false
|
||||||
|
grainLiftRatio = 0.5
|
||||||
|
grainStrength = 1.0
|
||||||
|
grainRate = 1.0
|
||||||
|
grainPitch = 1.0
|
||||||
|
colorLevel = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
15
orx-fx/src/main/kotlin/tonemap/Uncharted2Tonemap.kt
Normal file
15
orx-fx/src/main/kotlin/tonemap/Uncharted2Tonemap.kt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package org.openrndr.extra.fx.tonemap
|
||||||
|
|
||||||
|
import org.openrndr.draw.Filter
|
||||||
|
import org.openrndr.draw.Shader
|
||||||
|
import org.openrndr.extra.fx.filterFragmentCode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uncharted 2 tonemap filter
|
||||||
|
*/
|
||||||
|
class Uncharted2Tonemap : Filter(Shader.createFromCode(filterVertexCode, filterFragmentCode("tonemap/uncharted2-tonemap.frag"))) {
|
||||||
|
var exposureBias by parameters
|
||||||
|
init {
|
||||||
|
exposureBias = 2.0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
// Licensed under the MIT license:
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
// Ad[a|o]pted from shader by "noby" https://www.shadertoy.com/view/3sGSWV
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
uniform sampler2D tex0;
|
||||||
|
in vec2 v_texCoord0;
|
||||||
|
|
||||||
|
uniform bool useColor;// false
|
||||||
|
uniform float time;
|
||||||
|
uniform float grainLiftRatio;// = 0.5;
|
||||||
|
uniform float grainStrength;//= 1.0;
|
||||||
|
uniform float grainRate;// = 1.0;
|
||||||
|
// Range: [0.5, 1.0].
|
||||||
|
uniform float grainPitch;// = 1.0;
|
||||||
|
|
||||||
|
uniform float colorLevel;// = 1.0;
|
||||||
|
|
||||||
|
out vec4 o_output;
|
||||||
|
|
||||||
|
|
||||||
|
// From Dave Hoskins: https://www.shadertoy.com/view/4djSRW.
|
||||||
|
float hash(vec3 p3){
|
||||||
|
p3 = fract(p3 * 0.1031);
|
||||||
|
p3 += dot(p3, p3.yzx + 19.19);
|
||||||
|
return fract((p3.x + p3.y) * p3.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// From iq: https://www.shadertoy.com/view/4sfGzS.
|
||||||
|
float noise(vec3 x){
|
||||||
|
vec3 i = floor(x);
|
||||||
|
vec3 f = fract(x);
|
||||||
|
f = f*f*(3.0-2.0*f);
|
||||||
|
return mix(mix(mix(hash(i+vec3(0, 0, 0)),
|
||||||
|
hash(i+vec3(1, 0, 0)), f.x),
|
||||||
|
mix(hash(i+vec3(0, 1, 0)),
|
||||||
|
hash(i+vec3(1, 1, 0)), f.x), f.y),
|
||||||
|
mix(mix(hash(i+vec3(0, 0, 1)),
|
||||||
|
hash(i+vec3(1, 0, 1)), f.x),
|
||||||
|
mix(hash(i+vec3(0, 1, 1)),
|
||||||
|
hash(i+vec3(1, 1, 1)), f.x), f.y), f.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slightly high-passed continuous value-noise.
|
||||||
|
float grain_source(vec3 x, float strength, float pitch){
|
||||||
|
float center = noise(x);
|
||||||
|
float v1 = center - noise(vec3(1, 0, 0)/pitch + x) + 0.5;
|
||||||
|
float v2 = center - noise(vec3(0, 1, 0)/pitch + x) + 0.5;
|
||||||
|
float v3 = center - noise(vec3(-1, 0, 0)/pitch + x) + 0.5;
|
||||||
|
float v4 = center - noise(vec3(0, -1, 0)/pitch + x) + 0.5;
|
||||||
|
|
||||||
|
float total = (v1 + v2 + v3 + v4) / 4.0;
|
||||||
|
return mix(1.0, 0.5 + total, strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = v_texCoord0;
|
||||||
|
vec2 x = gl_FragCoord.xy;
|
||||||
|
|
||||||
|
// Alternatively use iTime here instead and change the grain_rate
|
||||||
|
// parameter to correspond to frames-per-second.
|
||||||
|
float t = time;
|
||||||
|
vec4 colorAlpha = texture(tex0, uv);
|
||||||
|
vec3 color = colorAlpha.rgb;
|
||||||
|
vec3 grain = vec3(0);
|
||||||
|
|
||||||
|
if (useColor) {
|
||||||
|
float rg = grain_source(vec3(x, floor(grainRate*(t))), grainStrength, grainPitch);
|
||||||
|
float gg = grain_source(vec3(x, floor(grainRate*(t+9.0))), grainStrength, grainPitch);
|
||||||
|
float bg = grain_source(vec3(x, floor(grainRate*(t-9.0))), grainStrength, grainPitch);
|
||||||
|
|
||||||
|
// Consider using values outside the [0, 1] range as well
|
||||||
|
// to introduce interesting color shifts to the source.
|
||||||
|
|
||||||
|
vec3 color_grain = vec3(rg, gg, bg);
|
||||||
|
color_grain = mix(vec3(dot(color_grain, vec3(0.2126, 0.7152, 0.0722))), color_grain, colorLevel);
|
||||||
|
grain = color_grain;
|
||||||
|
} else {
|
||||||
|
const float neutral_grain_factor = sqrt(2.0);
|
||||||
|
grain = vec3(grain_source(vec3(x, floor(grainRate*t)), grainStrength/neutral_grain_factor, grainPitch));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Control whether to add or multiply or lift the source with the grain.
|
||||||
|
// Multiply (0.0) should be more true to life, but adjust to taste.
|
||||||
|
|
||||||
|
color = max(mix(color*grain, color+(grain-1.0), grainLiftRatio), 0.0);
|
||||||
|
|
||||||
|
// After this you would normally perform tone mapping,
|
||||||
|
// apply the grain before that.
|
||||||
|
o_output.rgb = color;
|
||||||
|
o_output.a = 1.0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// ad[a|o]pted from http://filmicworlds.com/blog/filmic-tonemapping-operators/
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
float A = 0.15;
|
||||||
|
float B = 0.50;
|
||||||
|
float C = 0.10;
|
||||||
|
float D = 0.20;
|
||||||
|
float E = 0.02;
|
||||||
|
float F = 0.30;
|
||||||
|
float W = 11.2;
|
||||||
|
|
||||||
|
uniform sampler2D tex0;
|
||||||
|
uniform float exposureBias;
|
||||||
|
in vec2 v_texCoord0;
|
||||||
|
out vec4 o_output;
|
||||||
|
|
||||||
|
vec3 Uncharted2Tonemap(vec3 x) {
|
||||||
|
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 texColor = texture(tex0,v_texCoord0).rgb;
|
||||||
|
vec3 curr = Uncharted2Tonemap(exposureBias*texColor);
|
||||||
|
vec3 whiteScale = 1.0f/Uncharted2Tonemap(vec3(W));
|
||||||
|
vec3 color = curr*whiteScale;
|
||||||
|
|
||||||
|
vec3 retColor = pow(color, vec3(1/2.2));
|
||||||
|
o_output = vec4(retColor, 1);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user