参考:https://spite.github.io/sketch/
这里想做的漫画风格后处理主要元素有三点:排线,网点以及描边。此外还有一定的三色偏移效果。
几个Pass
主要包含3个pass,第一个pass梯度化场景中的颜色,第二个pass描边,排线以及网点,最后一个pass三色偏移。



梯度化颜色
获得场景中的亮度


利用亮度采样一张梯度变化LUT图:

利用此梯度变化改变场景diffuse color,同时可以利用custom stencil有选择的变化:

漫画感
首先利用sobel算子处理场景法线纹理。
float normalEdge = 1.0 - length(sobel(normalTexture, uv, textureSize, contour)); // contour:轮廓宽度(纹理尺寸变化)

smoothstep调整轮廓:
normalEdge = smoothstep(0.5-thickness, 0.5+thickness, normalEdge);
获得调整后的场景颜色灰度,根据灰度的不同区分暗部,灰部以及亮部,前两者排线(灰部更细,角度不同),亮部放置亮色网点。
if(l<dark) {
vec2 uv = scale * vUv;
float k = lines(l/dark, rot(uv, 45.), size, thickness);
rgbscreen = mix(rgbscreen, mix(rgbscreen, inkColor/255., .5), 1.-k);
}
if(l<mid) {
vec2 uv = scale * vUv;
float k = lines(l/mid, rot(uv, 15.), size, thickness);
rgbscreen = mix(rgbscreen, mix(rgbscreen, inkColor/255., .5), 1.-k);
}
if(l>light){
vec2 uv = vUv * size;
float frequency = .05;
// adapted from https://github.com/libretro/glsl-shaders/blob/master/misc/cmyk-halftone-dot.glsl
float w = mix(0., 1., thickness);
mat2 k_matrix = mat2(0.707, 0.707, -0.707, 0.707);
vec2 Kst = frequency * scale * mul(k_matrix , uv);
vec2 Kuv = w * (2. * fract(Kst) - 1.);
float k = step(0.0, sqrt(l-light) - length(Kuv));
rgbscreen = blendScreen(rgbscreen, vec3(1.), k);
}
lines方法:
float lines( in float l, in vec2 uv, in vec2 resolution, in float thickness){
vec2 center = .5 * resolution;
uv *= resolution;
float c = .5 + .5 * sin(uv.x*.5);
float f = (c+thickness)*l;
float e = 1. * length(vec2(dFdx(uv.x), dFdy(uv.y)));
f = smoothstep(.5-e, .5+e, f);
return f;
}
三色偏移
基于纹理空间中心点的uv方向偏移uv,采样3次叠加效果。
vec2 dir = vUv - vec2( .5 );
float d = .7 * length( dir );
normalize( dir );
vec2 value = d * dir * delta;
vec2 resolution = vec2(textureSize(colorTexture, 0));
vec4 c1 = texture(colorTexture, vUv - value / resolution.x );
vec4 c2 = texture(colorTexture, vUv );
vec4 c3 = texture(colorTexture, vUv + value / resolution.y );
fragColor = vec4( c1.r, c2.g, c3.b, c1.a + c2.a + c3.b );
结果

网友评论