UE卡通渲染(二):漫画风格后处理

参考: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(llight){
    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 );

结果

你可能感兴趣的:(UE卡通渲染(二):漫画风格后处理)