[ShaderStaff] Vignette Effect

操作系统:Windows8.1

显卡:Nivida GTX965M

开发工具:GLSL | C


 最近在看Cardboard实现,其中关于畸变的着色器代码中有加入 晕影Vignette 效果的实现,固在这里温习、总结一下。

直接上效果图:

未使用Vignette

使用Vignette滤镜效果图:

大概意思如图所示,增加了晕影效果后,使得边缘区域覆盖了厚重的颜色快,其目的是使得观看者更多的将目光聚焦在中心区域,该效果被大量运用到摄影、影视作品中。

比如:

How to implement


先给出全部代码具体解释说明,顶点着色器代码相对比较简单,仅仅是传递Mesh顶点数据及对应的UV数据。

static const char *vertex_shader_source =
        LINE("attribute vec4 aPosition;")
        LINE("attribute vec4 aTextureCoord;")
        LINE("varying highp vec2 vTextureCoord;")
        LINE("void main() {")
        LINE("gl_Position = aPosition;")
        LINE("vTextureCoord = aTextureCoord.xy;")
        LINE("}");

片段着色器代码:

static const char *fragment_shader_source =
        LINE("precision mediump float;")
        LINE("varying vec2 vTextureCoord;")
        LINE("uniform lowp sampler2D sTexture;")
        LINE("uniform lowp vec2 uVignetteCenter;")
        LINE("uniform lowp vec3 uVignetteColor;")
        LINE("uniform highp float uVignetteStart;")
        LINE("uniform highp float uVignetteEnd;")
        LINE("void main() {")
        LINE("lowp vec3 rgb = texture2D(sTexture, vTextureCoord).rgb;")
        LINE("lowp float d = distance(vTextureCoord, vec2(uVignetteCenter.x, uVignetteCenter.y));")
        LINE("lowp float percent = smoothstep(uVignetteStart, uVignetteEnd, d);")
        LINE("gl_FragColor = vec4(mix(rgb.x, uVignetteColor.x, percent), mix(rgb.y, uVignetteColor.y, percent), mix(rgb.z, uVignetteColor.z, percent), 1.0);")
        LINE("}");

该代码中设计带一些 uniform 系变量逐一说明:

  • uVignetteCenter 二维分量,用于确定晕影效果的中心点,用于逐像素计算距离中心点距离使用。考虑着色器坐标需要归一化 [0.0 - 1.0 ],固在上面的示例中定义为默认 [0.5, 0.5]
  • uVignetteColor   三维分量,用于确定晕影效果的颜色,一般情况下倾向于暗色调,在本例中为黑色 [1.0, 1.0, 1.0]
  • uVignetteStart | uVigntteEnd 均为二维分量,与上面提到的中心点组合使用,可以简单理解通过 smoothstep 插值计算当前像素晕影强度,越靠近 uVignetteStart 晕影效果越轻淡,反之越靠近边缘晕影效果越浓重

以下为示例所使用的参数值:

    filter->vignette_center_x = 0.5f;
    filter->vignette_center_y = 0.5f;
    filter->vignette_color[0] = 0.0f;
    filter->vignette_color[1] = 0.0f;
    filter->vignette_color[2] = 0.0f;
    filter->vignette_start = 0.2f;
    filter->vignette_end = 0.85f;

关于着色器中的 smoothstep 插值函数以参考 OpenGL Refpages 了解其实现原理,mix 混色函数参考 OpenGL Refpages。 

Summery


效果实现相对比较简单,具体应用环境可通过 fragment shader 任意调整参数,包括影晕形状。

posted @ 2017-12-25 21:33  黑桃花  阅读(712)  评论(0编辑  收藏  举报