OpenGL实现图片边缘暗角效果(1)

在进行VR视频播放开发的时候,看到如下一段opengl代码,一开始不知道为什么这样做,会产生什么效果。

首先是创建了一个纹理,该纹理除了边缘为半透明(58/255=0.23)外其它像素都是1:

void createVigTex() {
        static const int scale = 6;
        static const int width = 16 * scale;
        static const int height = 9 * scale;
        unsigned char buffer[width * height];
        memset(buffer, 255, sizeof(buffer));
        for ( int i = 0; i < width; i++ ){
            buffer[i] = 58;
            buffer[width*height - 1 - i] = 58;
        }
        for ( int i = 0; i < height; i++ ){
            buffer[i * width] = 58;
            buffer[i * width + width - 1] = 58;
        }

        CreateTexture2D(mTexVig, GL_LUMINANCE, GL_LUMINANCE, width, height, buffer);
    }

然后使用如下fragment shader来绘制视频:

const char* vigTexFragShader =
        "uniform sampler2D sampler0;\n"             // video
        "uniform sampler2D sampler1;\n"             // edge vignette
        "uniform vec2 resolution;\n"
        "varying vec2 oTexCoord;\n"
        "void main()\n"
        "{\n"
        "   gl_FragColor = texture2D( sampler0, oTexCoord ) *  texture2D( sampler1, oTexCoord );\n"
        "}\n";


最后的效果大致如下,原来就是在图像的边缘出现了一圈阴影,这样可以让视频画面与周围的场景过渡自然,如果不加,则边缘会很尖锐。熟悉opengl的人也大概能明白其中的原理,在绘制时,遮罩纹理sample1的边缘会进行线性插值,值的范围就会变成从0.23~1.0,再与视频图像相乘,就会出现如图这样的渐变阴影效果了。


搜索了一下vignette这个单词,大概是暗角效果的意思,百度百科上有解释:

[暗角一词属于摄影术语。对着亮度均匀景物,画面四角有变暗的现象,叫做“失光”,俗称“暗角”。]

Photoshop上也是有专门的技巧来产生这种效果的:


这不就是遮罩效果吗?在射击游戏中,经常出现的狙击镜效果,跟这个也有点类似,只是边缘是圆形的:


使用上面的shader代码同样能实现这种效果,只需要把纹理替换成一个圆形遮罩的图像就可以了。当然,用不同形状的遮罩纹理就能实现不同的遮罩效果,这种方法具有很大的灵活性。


发布了90 篇原创文章 · 获赞 1 · 访问量 7万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览