赞
踩
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
float gray = rgb.r * 0.2125 + rgb.g * 0.7154 + rgb.b * 0.0721;
FragColor = vec4(gray,gray,gray, 1.0);
};
几行代码功夫,萌萌的动画片变得特别有时代感~
所谓的反色,就是其RGB颜色值与其相加和为255的对应颜色值
,将一幅图置为反色,看起来就有种拍X光的效果。常见的反色如下表格所示,左右项互为反色(来源于百度百科):
白色(255,255,255) | 黑色(0,0,0) |
---|---|
灰色-25%(195,195,195) | 灰度-80%(60,60,60) |
褐色(185,122,87) | 深灰蓝绿色(70,133,168) |
玫瑰色(粉红)(255,174,201) | 深绿色(0,81,54) |
金色(255,201,14) | 蓝色(0,54,241) |
浅黄色(239,228,176) | 墨蓝色(16,27,79) |
酸橙色(181,230,29) | 亮蓝色(74,25,226) |
淡青绿色(153,217,234) | 深红褐色(102,38,21) |
蓝灰色(112,146,190) | 咖啡色(143,109,65) |
淡蓝紫色(200,191,231) | 深苔藓色(55,64,24) |
黑色(0,0,0) | 白色(255,255,255) |
---|---|
灰色-50%(127,127,127) | 灰色-50%(127,127,127)(反色就是它本身) |
深红色(136,0,21) | 浅蓝绿色(119,255,234) |
红色(237,28,36) | 蓝绿色(18,227,219) |
橙色(255,127,39) | 暗青蓝色(0,128,216) |
黄色(255,242,0) | 靛蓝色(0,13,255) |
绿色(34,177,76) | 暗玫红色(221,78,179) |
青绿(0,162,232) | 鲜橙色(255,93,23) |
靛青(63,72,204) | 棕黄色(192,183,51) |
紫色(163,73,164) | 草绿色(92,182,91) |
这样片段着色器就很简单了:
#version 300 es
precision mediump float;
//纹理坐标
in vec2 vTextCoord;
//输入的yuv三个纹理
uniform sampler2D yTexture;//采样器
uniform sampler2D uTexture;//采样器
uniform sampler2D vTexture;//采样器
out vec4 FragColor;
void main() {
//采样到的yuv向量数据
vec3 yuv;
//yuv转化得到的rgb向量数据
vec3 rgb;
//分别取yuv各个分量的采样纹理
yuv.x = texture(yTexture, vTextCoord).r;
//直接将uv置为0.0即可(0.5-0.5)
yuv.y = 0.0;
yuv.z = 0.0;
rgb = mat3(
1.0, 1.0, 1.0,
0.0, -0.183, 1.816,
1.540, -0.459, 0.0
) * yuv;
//取反色
FragColor = vec4(vec3(1.0 - rgb.r, 1.0 - rgb.g, 1.0 - rgb.b), 1.0);
};
只要最后赋值的一行改为以下即可:
FragColor = vec4(vec3(1.0 - rgb.r, 1.0 - rgb.g, 1.0 - rgb.b), 1.0);
一行代码功夫,一切都”反了“。
白银级别难度当然有所提升,主要是不同区域的片段的处理方式不一样
了。
#version 300 es
precision mediump float;
//纹理坐标
in vec2 vTextCoord;
//输入的yuv三个纹理
uniform sampler2D yTexture;//采样器
uniform sampler2D uTexture;//采样器
uniform sampler2D vTexture;//采样器
out vec4 FragColor;
void main() {
//采样到的yuv向量数据
vec3 yuv;
//yuv转化得到的rgb向量数据
vec3 rgb;
//分别取yuv各个分量的采样纹理(r表示?)
yuv.x = texture(yTexture, vTextCoord).r;
yuv.y = texture(uTexture, vTextCoord).g - 0.5;
yuv.z = texture(vTexture, vTextCoord).b - 0.5;
rgb = mat3(
1.0, 1.0, 1.0,
0.0, -0.183, 1.816,
1.540, -0.459, 0.0
) * yuv;
//根据不同的纹理坐标区域,赋值不同颜色值给当前当前片段颜色值
if (vTextCoord.x < 0.5 && vTextCoord.y < 0.5) {
//左上角区域,反色滤镜
FragColor = vec4(vec3(1.0 - rgb.r, 1.0 - rgb.g, 1.0 - rgb.b), 1.0);
} else if (vTextCoord.x > 0.5 && vTextCoord.y > 0.5) {
//右下角区域,灰度滤镜
float gray = rgb.r * 0.2125 + rgb.g * 0.7154 + rgb.b * 0.0721;
FragColor = vec4(gray, gray, gray, 1.0);
} else {
FragColor = vec4(rgb, 1.0);
}
};
代码一出来,其实也是so easy~关键点就是对于纹理坐标所在区域的判断
,如果处于左上角,即x<0.5,y<0.5,则使用反色效果。如果处于右下角,即x>0.5,y>0.5,则使用灰度效果。其余区域不做额外处理
。
又是几行代码的功夫,就戴上了”有色眼镜“~
黄金级别对于刚接触的童鞋来说可能是一个小门槛,因为这里开始当前片段采样的纹素可能并非是片段本身对应的纹理坐标了,而是根据需要采样自己想要的纹理坐标位置的颜色值
。
二分屏,顾名思义,即将一个画面分为2个重复的画面在平均分的屏幕位置上渲染。这里的二分屏为了保证图像不变形,所以每个分屏都采样原来纹理图片的中间一半的区域。如下图所示,左边是被渲染的图元,右边是被采样的纹理:
该图显示的是针对片段在第一个分屏的情况,因为之前讲过纹理映射就是相当于将图元的顶点和纹理的顶点一一对上。
从这个图我们可以得出一个通用结论,假如当前片段坐标为(x,y),当y小于0.5的时候,则采样纹理图片对应位置为y+0.25的纹素
那么对于下方的分屏,就可以顺藤摸瓜推出以下结论:
当y大于0.5的时候,则采样纹理图片对应位置为y-0.25的纹素。
上片段着色器代码:
#version 300 es
precision mediump float;
//纹理坐标
in vec2 vTextCoord;
//输入的yuv三个纹理
uniform sampler2D yTexture;//采样器
uniform sampler2D uTexture;//采样器
uniform sampler2D vTexture;//采样器
out vec4 FragColor;
void main() {
//采样到的yuv向量数据
vec3 yuv;
//yuv转化得到的rgb向量数据
vec3 rgb;
vec2 uv = vTextCoord.xy;
float y;
//关键点,对渲染图元不同位置的点采样纹理的不同位置
if (uv.y >= 0.0 && uv.y <= 0.5) {
//当渲染图元的点位于上半部分的时候,采样比其纵坐标大于0.25部分
uv.y = uv.y + 0.25;
}else{
//当渲染图元的点位于下半部分的时候,采样比其纵坐标小于0.25部分
uv.y = uv.y - 0.25;
}
//分别取yuv各个分量的采样纹理
yuv.x = texture(yTexture, uv).r;
yuv.y = texture(uTexture, uv).g - 0.5;
yuv.z = texture(vTexture, uv).b - 0.5;
rgb = mat3(
1.0, 1.0, 1.0,
0.0, -0.183, 1.816,
1.540, -0.459, 0.0
) * yuv;
FragColor = vec4(rgb, 1.0);
};
四分屏就更好玩了,但是原理和二分屏是一样的。
如下图,左边是被渲染的图元,右边是被采样的纹理,像之前所说的,可以将纹理和图元的顶点一一对上,比如四分屏的第一个格子和纹理的对应关系如下图所示:
所以对于第一个分屏,假如此时需要渲染的片段为(x,y),则可以推出采样的通用关系:
当x<0.5,y<0.5的时候,采样(x*2,y*2)的纹素。
那么以此类推,就可以推出:
当x>0.5,y<0.5的时候,采样((x-0.5)*2,y*2)的纹素。
当x<0.5,y>0.5的时候,采样(x*2,(y-0.5)*2)的纹素。
当x>0.5,y>0.5的时候,采样((x-0.5)*2,(y-0.5)*2)的纹素。
片段着色器代码:
#version 300 es
precision mediump float;
//纹理坐标
in vec2 vTextCoord;
//输入的yuv三个纹理
uniform sampler2D yTexture;//采样器
uniform sampler2D uTexture;//采样器
uniform sampler2D vTexture;//采样器
out vec4 FragColor;
void main() {
//采样到的yuv向量数据
vec3 yuv;
//yuv转化得到的rgb向量数据
vec3 rgb;
vec2 uv = vTextCoord.xy;
if (uv.x <= 0.5) {
//当x小于0.5的时候,采样2倍x坐标的纹素颜色
uv.x = uv.x * 2.0;
}else{
//当x大于0.5的时候,采样2倍x坐标减0.5的纹素颜色
uv.x = (uv.x - 0.5) * 2.0;
}
if (uv.y <= 0.5) {
//当y小于0.5的时候,采样2倍y坐标的纹素颜色
uv.y = uv.y * 2.0;
}else{
//当y大于0.5的时候,采样2倍y坐标减0.5的纹素颜色
uv.y = (uv.y - 0.5) * 2.0;
}
//分别取yuv各个分量的采样纹理
yuv.x = texture(yTexture, uv).r;
yuv.y = texture(uTexture, uv).g - 0.5;
yuv.z = texture(vTexture, uv).b - 0.5;
rgb = mat3(
1.0, 1.0, 1.0,
0.0, -0.183, 1.816,
1.540, -0.459, 0.0
) * yuv;
FragColor = vec4(rgb, 1.0);
};
这么一看也没什么神奇的,你说呢?
本文详细叙述了几种常见的滤镜效果实现原理,让广大的程序员也有机会体验做一把画家艺术家的快感,当然段位仅仅进行到了黄金级别未免显得太菜鸡了吧,所以下一篇文章才是真正冲击王者宝座的时机。
欢迎点赞加关注,让我们一起早日上王者段位~
opengl-es-study-demo 不断更新中,欢迎各位来star~
体系化学习系列博文,请看音视频系统学习的浪漫马车之总目录
实践项目: 介绍一个自己刚出炉的安卓音视频播放录制开源项目
相关专栏:
轻松入门OpenGL系列
一看就懂的OpenGL ES教程——图形渲染管线的那些事
一看就懂的OpenGL ES教程——再谈OpenGL工作机制
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(一)
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(二)
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(三)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
L ES教程——这或许是你遇过最难画的三角形(三)]( )
[外链图片转存中…(img-wsLyNFQv-1715504013534)]
[外链图片转存中…(img-P9PxxCCe-1715504013534)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。