我这里讲的shader是什么呢,通俗讲就是是获得图片的像素和操作图片的像素
比如我的原本颜色是这样的:

wo.png

void main()
{vec4 mycolor =  v_fragmentColor*texture2D(CC_Texture0, v_texCoord);//我的颜色.rgb就是这张图片的每个像素点的值,我的颜色.a就是这张图的透明度gl_FragColor =  mycolor;
}

那么cocos2d把我自己变成灰色是怎样呢?在ccShader_UI_Gray.frag文件下它是这么写的

void main()
{vec4 mycolor =  v_fragmentColor*texture2D(CC_Texture0, v_texCoord);//我的颜色向量点乘vec3(0.21,0.71,0.07),还我本来的透明度值float gray = dot(mycolor.rgb, vec3(0.2126, 0.7152, 0.0722));gl_FragColor =  vec4(gray);gl_FragColor.a = mycolor.a;
}

效果是这样的

wo2.png

好吧这是在模拟器上截的图,放了个背景就当衬托,Shader能干的事太多了,接下来我要引发图战了

wo3.png

这张是显示包围盒,平时碰撞检测的时候虽然心里有一个概念,但是还是不如这种直接把透明度<0.1的颜色设为0.5看的直接

    vec4 mycolor =  v_fragmentColor*texture2D(CC_Texture0, v_texCoord);if (mycolor.a < 0.1 ){mycolor = vec4(0.5);}gl_FragColor = mycolor;

wo4.png

vec4 mycolor =  v_fragmentColor*texture2D(CC_Texture0, v_texCoord);float average = mycolor.r + mycolor.g + mycolor.b;if (average < 1.4){gl_FragColor = mycolor; }else {gl_FragColor = vec4(0.);}

把我这张图片的rgb值相加,分值低于1.4的正常显示,高于的部分.rgb和透明度.a设为0.0,则出现上面的效果,怎么样像不像做了一个面具
我们换张图片来操作吧,换张美女图片

02.png

做demo或者示例就改拿网上看到的漂亮图片来操作嘛,这样就算随意修修改改也是一张美女图片

换个美女图片标题肯定要响亮些

03.jpg

我做了什么,我只是把美女的轮廓用浮雕凹显出来而已,好的现在开始进入Shader的基本介绍篇:

#ifdef GL_ES
precision mediump float;
#endif
uniform float PosX;
uniform float PosY;
uniform float waterwid;
uniform float deepwid;
//PosX是我传入的触控点X位置,PosY是触控点Y位置
uniform sampler2D CC_Texture0;
varying vec2 v_texCoord;
varying vec4 v_fragmentColor;
void main() {vec2 onePixel = vec2(waterwid/ 48.0, deepwid/ 32.0);vec4 color;color.rgb = vec3(0.5);color -= texture2D(CC_Texture0, v_texCoord - onePixel) * PosX;color += texture2D(CC_Texture0, v_texCoord + onePixel) * PosY;color.rgb = vec3((color.r + color.g + color.b) / 3.0);gl_FragColor = vec4(color.rgb, 1.);
}

这里的PosX和PosY是我从外部传进来的触控X和Y的点,当然值是被我换算成01,这样的值不管在什么分辨率情况下能保证我们写的代码是通用的,waterwid和deepwid就是下面的两个滑动条了滑动范围也是在01之间,创造shader的Program代码lua:

function M.Shader_Normal_Init(vs,fs)local program = GlUtils:createProgram(vs,fs)//顶点着色器和片段着色器GlUtils:programRetain(program)GlUtils:programAddAttribute(program, kCCAttributeNamePosition, kCCVertexAttrib_Position)GlUtils:programAddAttribute(program, kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords)GlUtils:programAddAttribute(program, kCCAttributeNameColor, kCCVertexAttrib_Color)//传入我这张图片的位置.纹理.颜色信息给gl这个进程GlUtils:programLink(program)//实时更新GlUtils:programUpdateUniforms(program)GlUtils:programUse(program)GlUtils:checkErrorDebug()return program
end
-- 创造浮雕
function M.CreateRelief(node)local program = M.Shader_Normal_Init("bingxue/normal.vs", "bingxue/bins.fs")-- 默认水坑在中心点,即Posx=0.5,Posy=0.5local amountLocx = GlUtils:programGetUniformLocationForName(program, "PosX")GlUtils:programSetUniformLocationWith1f(program, amountLocx, 480.0/960.0)local amountLocy = GlUtils:programGetUniformLocationForName(program, "PosY")GlUtils:programSetUniformLocationWith1f(program, amountLocy, 320.0/640.0)node:setShaderProgram(program)
end

这时候我话锋一转开始介绍起了shader最基本的一些参数

Shader常常自带的一些函数

shader在初始化的时候必然有如下几个默认值的引入
"uniform mat4 CC_PMatrix;\n"
"uniform mat4 CC_MVMatrix;\n"
"uniform mat4 CC_MVPMatrix;\n"
"uniform vec4 CC_Time;\n"
"uniform vec4 CC_SinTime;\n"
"uniform vec4 CC_CosTime;\n"
"uniform vec4 CC_Random01;\n"
"uniform sampler2D CC_Texture0;\n"
"uniform sampler2D CC_Texture1;\n"
"uniform sampler2D CC_Texture2;\n"
"uniform sampler2D CC_Texture3;\n"

-- 其中CC_PMatrix表示传入的是所用图片的原始纹理,即你缩放2倍后的图在shader里也是按照原图纹理来操作的,并且坐标原点在左下角
-- CC_MVPMatrix是我常用的,我们变换后是什么样传入就是什么样,坐标也是传入时候的值
-- CC_Time.x是每一帧刷新自增0.01 .y是每帧自增0.1 框架默认是定时刷新,所以大部分情况下有这就没必要在创建shader还在外面开定时器
我常用的顶点着色器通常写法是这样的
-- CC_Texture0就是默认操作这个Shader的Program的纹理,简单说就是这张图上每个像素点

#ifdef GL_ES                                        precision mediump float;varying mediump vec2 v_texCoord;
#elsevarying vec2 v_texCoord;
#endif
attribute vec2 a_texCoord;
attribute vec4 a_color;
attribute vec4 a_position;
varying vec4 v_fragmentColor;
void main()
{gl_Position = CC_MVPMatrix * a_position;  //gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color;                                                v_texCoord = a_texCoord;
}

这里的a_texCoord就是上面lua传入的默认的这张图片的纹理啦,a_color这张图片基本颜色a_position顶点信息,这里为什么还有个v_fragmentColor呢?这个是做什么用的
举个栗子:假如我在lua设置
我这张图片:setColor(红色)
这时候我这张图片应该是先被设置为红色图片再将纹理颜色值传入shader端,但是如果我们不用v_fragmentColor,在片段着色器:

gl_FragColor = texture2D(CC_Texture0, v_texCoord);

你就会发现显示的是这张图片该是什么颜色就是什么颜色,只有

gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);

这张图片显示的才是我们变成红色后的图片,所以我经常把“v_fragmentColor*”写在最后 。
我再贴一幅图:人物发光效果

wo5.png

这张图的术是什么呢?其实就是拿这张图往旁边移动一下绕自己的中心点绕一圈,外围的红色部分就是这偏移出去的部分,由于绕自己中心转的时候中间的不透明值会越加越高,而外围的部分alpha值肯定比较低,这样把两者区分开来,并且让偏移量随时间周期运动看起来就像人物在发光,这次贴上完整的片段着色器代码

#ifdef GL_ES
precision mediump float;
#endif//所需常量
uniform sampler2D CC_Texture0;
varying vec2 v_texCoord;
varying vec4 v_fragmentColor;#define outlineSize 10.*sin(2.*CC_Time.y)
// 描边宽度,直接以像素为单位会有分辨率不同大小不同的问题,所以就用比例吧
#define outlineColor vec3(abs(sin(outlineSize/10.)),0.,0.) // 描边颜色
#define textureSize vec2(215.0,299.0) // 纹理大小(宽和高),为了计算周围各点的纹理坐标,必须传入它,因为纹理坐标范围是0~1// 判断在这个角度上距离为outlineSize那一点是不是透明
int getIsStrokeWithAngel(float angel)
{int stroke = 0;float rad = angel * 0.01745329252; // 这个浮点数是 pi / 180,角度转弧度float a = texture2D(CC_Texture0, vec2(v_texCoord.x + outlineSize * cos(rad) / textureSize.x, v_texCoord.y + outlineSize * sin(rad) / textureSize.y)).a; // 我把alpha值大于0.5都视为不透明,小于0.5都视为透明if (a >= 0.01){stroke = 1;}return stroke;
}
void main() {// 我的颜色vec4 myC = texture2D(CC_Texture0, vec2(v_texCoord.x, v_texCoord.y)); if (myC.a >= 0.5) // 不透明,不管,直接返回{gl_FragColor =  v_fragmentColor*myC;return;}int strokeCount = 0;strokeCount += getIsStrokeWithAngel(0.0);strokeCount += getIsStrokeWithAngel(30.0);strokeCount += getIsStrokeWithAngel(60.0);strokeCount += getIsStrokeWithAngel(90.0);strokeCount += getIsStrokeWithAngel(120.0);strokeCount += getIsStrokeWithAngel(150.0);strokeCount += getIsStrokeWithAngel(180.0);strokeCount += getIsStrokeWithAngel(210.0);strokeCount += getIsStrokeWithAngel(240.0);strokeCount += getIsStrokeWithAngel(270.0);strokeCount += getIsStrokeWithAngel(300.0);strokeCount += getIsStrokeWithAngel(330.0);float dis = pow( pow(abs(v_texCoord.x-0.5),2.) + pow(abs(v_texCoord.y-0.5),2.) , 4.);// 四周围至少有一个点是不透明的,这个点要设成描边颜色if (strokeCount > 0) {myC.rgb = outlineColor;myC.a = 1.0*dis;}gl_FragColor = v_fragmentColor * myC;
}

现在再回过头来看看上面的浮雕,其实它的术就是:
1.布置一张灰色半透明画布 2.画布-图片往左移动onePixel
3.画布+图片往右移动onePixel 4.画布颜色值平均化
至于所谓Posx和Posy的作用就是控制+-的强度了,这两个值我交给屏幕的触控来调整,这样能轻易的看到调整所带来的改变

水坑

04.jpg

还是这个熟悉的漂亮妹子图片,所以说漂亮又皮肤好的人图片再如何扭曲还是漂亮啊!有点跑题了
看到上面代码的同学可能会问deepwid和waterwid是什么,这就不得不提我早时候做的一个模板了,一个水坑,对-当时假设的需求是上面有一辆车,这辆车经过的时候原地肯定会下陷一个坑再回来嘛,那么问题就来了,下陷是从哪里下陷,下陷的深度是多少,下陷最深处的宽是多少,于是我就带着这三个问题写了这个水坑

const float pi = 3.141592653589793;
//从哪里下陷
float midpoint = PosX;
//水宽范围
//float waterwid = keng;
//水最深处宽带
//float wid = 0.5;
float CountScale(float left,float right)
{//水深float depth = PosY;//防止怪异现象if (depth > 1.){depth = 1.;}else if (depth < 0.){depth = 0.;}//像素Y值缩放float scale = 1.-depth;float length = right - left;float mysca = pi/length;//向下弯曲的坐标值定在0.-1.之间float pos = (v_texCoord.x - left)/length;if (pos < (1.-deepwid)/2. ){pos = 1./(1.-deepwid)*(pos);scale = (1.-depth) + depth *(0.5001-0.5*(sin(-pi/2.+pos*2.*pi)) );}else if( pos > (1.+deepwid)/2.){pos = 1./(1.-deepwid)*(pos-deepwid);scale = (1.-depth)+ (depth)*(.5001-.5*( sin(-pi/2.+(pos)*2.*pi) ) );}return scale;
}void main() {float scale = 1.;float left  = midpoint - waterwid/2.;float right = midpoint + waterwid/2.;if (v_texCoord.x > left && v_texCoord.x < right ){scale = CountScale(left,right);}vec4 mycolor = vec4(0.0);if (1.-v_texCoord.y < scale ){mycolor = texture2D(CC_Texture0, vec2(v_texCoord.x,1./scale*(v_texCoord.y-1.+scale))  );}gl_FragColor = mycolor ;
}

水坑的术是什么:根据触控的中心点缩小那部分的Y纹理值waterwid就是水宽,也就是这个水坑最上面的宽度值在0~1之间,deepwid那就是水坑下面的宽度了
最后附上写Shader的时候常用的一些函数和一些不错的网址

-- 部分好的网站  -- cocos官网
http://store.cocos.com/stuff/category/12/score_count.html
-- 一些大师的分享地
http://www.effecthub.com/#userconsent#
-- 纯shader纹理
http://glslsandbox.com/#userconsent#
-- 游戏素材下载
http://www.6m5m.com/index.php#userconsent#
-- 博客,框架一些效果的来源
http://www.cnblogs.com/hcbin/archive/2012/08/03/2621267.html
-- 特效视频
http://i.youku.com/u/UNjE2NDAyODc2?qq-pf-to=pcqq.c2c
-- 一些基本效果,框架从这里下载过
http://www.oschina.net/code/snippet_1159242_38156
-- shader常用语法
abs                         计算输入值的绝对值。
acos                        返回输入值反余弦值。
all                           测试非0值。
any                         测试输入值中的任何非零值。
asin                         返回输入值的反正弦值。
atan                        返回输入值的反正切值。
atan2                       返回y/x的反正切值。
ceil                         返回大于或等于输入值的最小整数。
clamp                      把输入值限制在[min, max]范围内。
clip                         如果输入向量中的任何元素小于0,则丢弃当前像素。
cos                         返回输入值的余弦。
cosh                       返回输入值的双曲余弦。
cross                      返回两个3D向量的叉积。
ddx                         返回关于屏幕坐标x轴的偏导数。
ddy                         返回关于屏幕坐标y轴的偏导数。
degrees                   弧度到角度的转换
determinant              返回输入矩阵的值。
distance                   返回两个输入点间的距离。
dot                          返回两个向量的点积。
exp                         返回以e为底数,输入值为指数的指数函数值。
exp2                       返回以2为底数,输入值为指数的指数函数值。
faceforward             检测多边形是否位于正面。
floor                       返回小于等于x的最大整数。
fmod                       返回a / b的浮点余数。
frac                        返回输入值的小数部分。
frexp                       返回输入值的尾数和指数
fwidth                     返回 abs ( ddx (x) + abs ( ddy(x))。
isfinite                     如果输入值为有限值则返回true,否则返回false。
isinf                        如何输入值为无限的则返回true。
isnan                       如果输入值为NAN或QNAN则返回true。
ldexp                       frexp的逆运算,返回 x * 2 ^ exp。
len / lenth                返回输入向量的长度。
lerp                         对输入值进行插值计算。
lit                            返回光照向量(环境光,漫反射光,镜面高光,1)。
log                          返回以e为底的对数。
log10                      返回以10为底的对数。
log2                        返回以2为底的对数。
max                        返回两个输入值中较大的一个。
min                         返回两个输入值中较小的一个。
modf                       把输入值分解为整数和小数部分。
mul                         返回输入矩阵相乘的积。
normalize                 返回规范化的向量,定义为 x / length(x)。
pow                        返回输入值的指定次幂。
radians                    角度到弧度的转换。
reflect                     返回入射光线i对表面法线n的反射光线。
refract                     返回在入射光线i,表面法线n,折射率为eta下的折射光线v。
round                      返回最接近于输入值的整数。
rsqrt                       返回输入值平方根的倒数。
saturate                   把输入值限制到[0, 1]之间。
sign                        计算输入值的符号。
sin                          计算输入值的正弦值。
sincos                     返回输入值的正弦和余弦值。
sinh                        返回x的双曲正弦。
smoothstep              返回一个在输入值之间平稳变化的插值。
sqrt                         返回输入值的平方根。
step                        返回(x >= a)? 1 : 0。
tan                          返回输入值的正切值。
fanh                        返回输入值的双曲线切线。
transpose                 返回输入矩阵的转置。
tex1D*                    1D纹理查询。
tex2D*                    2D纹理查询。
tex3D*                    3D纹理查询。
texCUBE*                立方纹理查询。
-- 运用中添加
fract(x): 取小数部分

基于cocos2d-lua的shader入门玩转相关推荐

  1. Cocos2d Lua 入门小例子 一个记忆力游戏

    1.游戏说明 一个"记忆"类的比赛游戏.你和电脑对战,轮到谁的回合,谁翻两张牌,如果两张牌一样,就消掉这两张牌,得2分,可以继续翻牌,如果两张牌不一样,就换一个人.直到最后,看谁的 ...

  2. Unity Shader入门笔记

    学习资料:https://onevcat.com/2013/07/shader-tutorial-1/猫都能学会的Unity3D Shader入门指南(一)(二) 学习资料:http://98jy.n ...

  3. Shader入门指南

    Unity3D Shader入门指南(一) 分类: Unity3d2014-04-28 17:40 16人阅读 评论(0) 收藏 举报 unity3dShader3d渲染 目录(?)[+] 本文转载自 ...

  4. Unity3D Shader入门指南(二)

    关于本系列 这是Unity3D Shader入门指南系列的第二篇,本系列面向的对象是新接触Shader开发的Unity3D使用者,因为我本身自己也是Shader初学者,因此可能会存在错误或者疏漏,如果 ...

  5. 猫都能学会的Unity3D Shader入门指南(二)

    关于本系列 这是Unity3D Shader入门指南系列的第二篇,本系列面向的对象是新接触Shader开发的Unity3D使用者,因为我本身自己也是Shader初学者,因此可能会存在错误或者疏漏,如果 ...

  6. Unity3D Shader 入门

    什么是Shader Shader(着色器)是一段能够针对3D对象进行操作.并被GPU所执行的程序.Shader并不是一个统一的标准,不同的图形接口的Shader并不相同.OpenGL的着色语言是GLS ...

  7. 《Unity Shader入门精要》笔记02 第1章+第2章

    基础篇 第1章+第2章 --本系列是基于人民邮电出版社<Unity Shader入门精要>(冯乐乐著 )的自学Unity Shader笔记,如果您发现了本文的纰漏,还望不吝指正. 基础篇 ...

  8. 《Unity Shader入门精要》笔记01 前言

    <Unity Shader入门精要>笔记01 前言 --本系列是基于人民邮电出版社<Unity Shader入门精要>(冯乐乐著 )的自学Unity Shader笔记,如果您发 ...

  9. Unity Shader入门精要学习笔记 - 第14章 非真实感渲染

    Unity Shader入门精要学习笔记 - 第14章 非真实感渲染 本系列为UnityShader入门精要读书笔记总结, 原作者博客链接:http://blog.csdn.net/candycat1 ...

  10. Unity Shader入门精要学习笔记 - 第14章非真实感渲染

    转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...

最新文章

  1. BeautifulSoup库的使用
  2. 谷歌浏览器查询缓存视频图片
  3. MySQL cast()函数
  4. Python单元测试框架之unittest+requests+ddt+excel接口自动化测试
  5. Trie树(c++实现)
  6. Effective Java学习笔记之第6条 消除过期的引用对象
  7. 重新配对_国羽世界冠军组合重新配对!男方笑言“老夫老妻”,没什么感觉
  8. C# 语言规范_版本5.0 (第15章 委托)
  9. iso12233测试方法_ISO12233图像分辨率测试卡的使用方法
  10. Win11 在线安装QT5.15.2教程
  11. 计算机安装系统后鼠标无法使用,电脑重装系统后鼠标键盘不能用怎么办,鼠标键盘不能用解决方法...
  12. android 罗盘陀螺仪,电子罗盘和陀螺仪的区别以及工作原理介绍
  13. 魔兽地图编辑器使用自定义图标的方法
  14. 福师电子计算机主要以,福师《计算机应用基础》在线作业(6) 参考资料
  15. 罗格斯的计算机科学,罗格斯大学计算机
  16. 【遥感】常见国产卫星载荷分辨率汇总
  17. Springcloud config 出现Error occured cloning to base directory.
  18. UnityWebGL引用4399的Api
  19. 微信公众号网页授权--前端获取code及用户信息(vue)
  20. HDU - 1873 看病要排队(优先队列)

热门文章

  1. 支付宝支付流程 及简单实现
  2. 不平凡的2021,末流普本生秋招上岸大厂的历程
  3. Android图片轮播控件——Banner
  4. WMS系统-库位准确率与单位面积存储率-北京东勤科技
  5. [转]SAP模块一句话入门
  6. [转载]如何塑造个人品牌:张何个人网络品牌营销全攻略
  7. 怎样查找计算机死机日志,死机和日志错误
  8. 计算机开机最快,电脑开机速度,最快几秒?
  9. 如何鉴别虚拟主机好坏
  10. 三个表内连接查询创建视图