cocos-2dx Shader 着色器和GLSL

在移动游戏中,GPU大部分时间都是闲着的,而我们很多时刻可以直接来操作 着色器 在屏幕上的显示来节约我们的图片资源,容量以及内存等等。 

着色器  
着色器(英语:shader)应用于计算机图形学领域,指一组供计算机图形资源在执行渲染任务时使用的指令。程序员将着色器应用于图形处理器(GPU)的可编程流水线,来实现三维应用程序。这样的图形处理器有别于传统的固定流水线处理器,为GPU编程带来更高的灵活性和适应性。 

用过opengl的同学对着色器应该不会陌生,作为移动游戏终端设备的开发者,对于图形图像的了解是必不可少的,对于opengl es 2.x才引入的着色器,WWDC的专题讲座有一节就是讲opengl es的新特性的,结合AVFoundation那一节,我们也能从中可以学到不少东西的。 

opengl es的着色器 有.fsh和.vsh两个文件 这两个文件在被编译和链接后就可以产生可执行程序 与GPU交互.vsh 是顶点shader 用与顶点计算 可以理解控制顶点的位置 在这个文件中我们通常会传入当前顶点的位置,和纹理的坐标. 

GLSL  
GLSL - OpenGL Shading Language 也称作 GLslang,是一个以C语言为基础的高阶着色语言。它是由 OpenGL ARB 所建立,提供开发者对绘图管线更多的直接控制,而无需使用汇编语言或硬件规格语言。 

随着近年来绘图卡的进步, 已在渲染管线中的顶点(vertex)和片断(fragment)层次中,加入更具弹性的新功能。 达到在这个层次中,使用片断和顶点着色器的可编程性。 


<pre name="code" class="GLSL 顶点着色器的简单范例"> 
void main(void) 

    gl_Position = ftransform(); 

</pre> 

<pre name="code" class="GLSL 片段着色器的简单范例"> 
void main(void) 

    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 

</pre> 

GLSL的函式和控制结构 
<pre name="code" class="GLSL"> 
类似于 C语言,GLSL 支援循环和分支,包括 if、else、if/else、for、do-while、break、continue 等。 

支援使用者定义函式,且各种常用的函式也已内建。这也就让绘图卡制造商,能够在硬件层次上最佳化这些内建的函式。许多函式与 C 语言相同,如 exp() 以及 abs(),其它绘图编程特有的,如 smoothstep() 以及 texture2D() 
</pre> 

OpenGL 着色语言规格定义了 22 个基本资料类型,有些用法与 C 相同,其它的是绘图处理器特有的。 
<pre name="code" class="GLSL 基本资料类型">. 
void – 用于没有返回值的函式 
bool – 条件类型,其值可以是真或假 
int – 带负号整数 
float – 浮点数 
vec2 – 2 个浮点数组成的向量 
vec3 – 3 个浮点数组成的向量 
vec4 – 4 个浮点数组成的向量 
bvec2 – 2 个布尔组成的向量 
bvec3 – 3 个布尔组成的向量 
bvec4 – 4 个布尔组成的向量 
ivec2 – 2 个整数组成的向量 
ivec3 – 3 个整数组成的向量 
ivec4 – 4 个整数组成的向量 
mat2 – 浮点数的 2X2 矩阵 
mat3 – 浮点数的 3X3 矩阵 
mat4 – 浮点数的 4X4 矩阵 
sampler1D – 用来存取一维纹理的句柄(handle)(或:操作,作名词解。) 
sampler2D – 用来存取二维纹理的句柄 
sampler3D – 用来存取三维纹理的句柄 
samplerCube – 用来存取立方映射纹理的句柄 
sampler1Dshadow – 用来存取一维深度纹理的句柄 
sampler2Dshadow – 用来存取二维深度纹理的句柄 
</pre> 


shader在处理资源上有很多种应用。 
比如按钮的变灰,角色的冰冻,石化,中毒等效果,再比如水波的滤镜实现


先来个类似于最近比较火的刀塔传奇里的中毒效果把。(ps:抽的亚龙不怎么给力。o(︶︿︶)o 唉)。 
资源我就拿天天酷跑里的loading男孩了。 

先来个对比效果图把~ 

 

Glsl代码实现代码   收藏代码
  1. #ifdef GL_ES   
  2. precision mediump float;   
  3. #endif   
  4. uniform sampler2D u_texture;   
  5. varying vec2 v_texCoord;   
  6. varying vec4 v_fragmentColor;   
  7. void main(void)   
  8. {   
  9.     gl_FragColor = texture2D(u_texture, v_texCoord) * v_fragmentColor;  
  10.     gl_FragColor.r *= 0.8;
  11.     gl_FragColor.r += 0.08 * gl_FragColor.a;  
  12.     gl_FragColor.g *= 0.8;  
  13.     gl_FragColor.b *= 0.8;  
  14.     gl_FragColor.g += 0.2 * gl_FragColor.a;  
  15.    //gl_FragColor= vec4(color.r,color.g, color.b,color.a) ;  
  16. }  




再来个冰冻效果, 
还是先上图: 

 


Glsl代码实现代码   收藏代码
  1. #ifdef GL_ES   
  2. precision mediump float;   
  3. #endif   
  4. uniform sampler2D u_texture;   
  5. varying vec2 v_texCoord;   
  6. varying vec4 v_fragmentColor;   
  7. void main(void)   
  8. {   
  9.     vec4 normalColor = v_fragmentColor * texture2D(u_texture, v_texCoord);  
  10.     normalColor *= vec4(0.80.80.81);  
  11.     normalColor.b += normalColor.a * 0.2;  
  12.     gl_FragColor = normalColor;  
  13. }  



实现都很简单,就是操作argb值,具体的语法可以看前一张有介绍。 

http://caiwb1990.iteye.com/blog/2064688 



Mark~  

HSV and HLS color systems are problematic for a number of reasons. I talked with a color scientist about this recently, and his recommendation was to convert to YIQ or YCbCr space and adjust the the chroma channels (I&Q, or Cb&Cr) accordingly. (You can learn how to do that here and here.) 

Once in one of those spaces, you can get the hue from the angle formed by the chroma channels, by doing hue = atan(cr/cb) (watching for cb == 0). This gives you a value in radians. Simply rotate it by adding the hue rotation amount. Once you've done that, you can calculate the magnitude of the chroma with chroma = sqrt(cr*cr+cb*cb). To get back to RGB, calculate the new Cb and Cr (or I & Q) using Cr = chroma * sin (hue), Cb = chroma * cos (hue). Then convert back to RGB as described on the above web pages. 

EDIT: Here's a solution that I've tested and seems to give me the same results as your reference. You can probably collapse some of the dot products into matrix multiplies: 

Glsl代码   收藏代码
  1. uniform sampler2DRect inputTexture;  
  2. uniform float   hueAdjust;  
  3. void main ()  
  4. {  
  5.     const vec4  kRGBToYPrime = vec4 (0.2990.5870.1140.0);  
  6.     const vec4  kRGBToI     = vec4 (0.596, -0.275, -0.3210.0);  
  7.     const vec4  kRGBToQ     = vec4 (0.212, -0.5230.3110.0);  
  8.   
  9.     const vec4  kYIQToR   = vec4 (1.00.9560.6210.0);  
  10.     const vec4  kYIQToG   = vec4 (1.0, -0.272, -0.6470.0);  
  11.     const vec4  kYIQToB   = vec4 (1.0, -1.1071.7040.0);  
  12.   
  13.     // Sample the input pixel  
  14.     vec4    color   = texture2DRect (inputTexture, gl_TexCoord [ 0 ].xy);  
  15.   
  16.     // Convert to YIQ  
  17.     float   YPrime  = dot (color, kRGBToYPrime);  
  18.     float   I      = dot (color, kRGBToI);  
  19.     float   Q      = dot (color, kRGBToQ);  
  20.   
  21.     // Calculate the hue and chroma  
  22.     float   hue     = atan (Q, I);  
  23.     float   chroma  = sqrt (I * I + Q * Q);  
  24.   
  25.     // Make the user's adjustments  
  26.     hue += hueAdjust;  
  27.   
  28.     // Convert back to YIQ  
  29.     Q = chroma * sin (hue);  
  30.     I = chroma * cos (hue);  
  31.   
  32.     // Convert back to RGB  
  33.     vec4    yIQ   = vec4 (YPrime, I, Q, 0.0);  
  34.     color.r = dot (yIQ, kYIQToR);  
  35.     color.g = dot (yIQ, kYIQToG);  
  36.     color.b = dot (yIQ, kYIQToB);  
  37.   
  38.     // Save the result  
  39.     gl_FragColor    = color;  
  40. }  



引用
http://stackoverflow.com/questions/9234724/how-to-change-hue-of-a-texture-with-glsl

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值