opengl之vsh、fsh简易介绍+cocos2dx 3.0 shader 变灰
认识着色器
理解OpenGL渲染管线,对于学习OpenGL非常重要。下面是OpenGL渲染管线的示意图:(图中淡蓝色区域是可以编程的阶段) 此图是从wiki中拿过来的,OpenGL的渲染管线主要包括:
OpenGL Shader Language,简称GLSL,它是一种类似于C语言的专门为GPU设计的语言,它可以放在GPU里面被并行运行。
opengl es的着色器有.fsh和.vsh两个文件。这两个文件在被编译和链接后就可以产生可执行程序与GPU交互。
.vsh 是 vertex shader,用与顶点计算,可以理解控制顶点的位置,在这个文件中我们通常会传入当前顶点的位置,和纹理的坐标。
例如:
1 attribute vec4 position; 2 attribute vec4 inputTextureCoordinate; 3 4 varying vec2 textureCoordinate; 5 6 precision mediump float; 7 uniform float overTurn; 8 9 void main() 10 { 11 gl_Position = position; 12 if (overTurn>0.0) { 13 textureCoordinate = vec2(inputTextureCoordinate.x,overTurn-inputTextureCoordinate.y); 14 } 15 else 16 textureCoordinate = vec2(inputTextureCoordinate.x,inputTextureCoordinate.y); 17 } 首先,每一个Shader程序都有一个main函数,这一点和c语言是一样的。 这里面有两种类型的变量,一种是attribute,另一种是varying. attribute是从外部传进来的,每一个顶点都会有这两个属性,所以它也叫做vertex attribute(顶点属性)。 而varying类型的变量是在vertex shader和fragment shader之间传递数据用的。 这里的变量命名规则保持跟c一样就行了,注意gl_开头的变量名是系统内置的变量,所以大家在定义自己的变量名时,请不要以gl_开头。 而CC_MVPMatrix是一个mat4类型的变量,它是在cocos2d-x内部设置进来的。 即: attribute:外部传入vsh文件的变量 每帧的渲染的可变参数 变化率高 用于定义每个点。 varying:用于 vsh和fsh之间相互传递的参数。 precisionmediump float 定义中等精度的浮点数。 uniform 外部传入vsh文件的变量 变化率较低 对于可能在整个渲染过程没有改变 只是个常量。 在main()当overTurn大于0的时候,函数里面做的事情就是将纹理y轴反转。 vertex shader是作用于每一个顶点的,如果vertex有三个点,那么vertex shader会被执行三次。 .fsh 是片段shader。在这里面我可以对于每一个像素点进行重新计算。 1 varying highp vec2 textureCoordinate;
2 precision mediump 3 uniform sampler2D videoFrame;
4
5 vec4 memoryRender(vec4 color)
6 {
7 float gray;
8 gray = color.r*0.3+color.g*0.59+color.b*0.11;
9 color.r = gray;
10 color.g = gray;
11 color.b = gray;
12
13 color.r += color.r*1.5;
14 color.g = color.g*2.0;
15
16 if(color.r > 255.0)
17 color.r = 255.0;
18 if(color.g > 19 color.g = 20
21 return color;
22 }
23
24 25 {
26 vec4 pixelColor;
27
28 pixelColor = texture2D(videoFrame,textureCoordinate);
29
30 gl_FragColor = memoryRender(pixelColor);
31 }
varyinghighpvec2textureCoordinate就是从vsh中传过来了纹理坐标。 uniformsampler2DvideoFrame是我们真正的纹理贴图。 texture2D(videoFrame,textureCoordinate) 将纹理中的每个像素点颜色取出到pixelColor。 可以用memoryRender(pixelColor)将取到像素点重新加工。 fragment shader中也有一个main函数,同时我们看到这里也声明了一个与vertex shader相同的变量textureCoordinate。前面我们讲过,这个变量是用来在vertex shader和fragment shader之间传递数据用的。所以,它们的参数类型必须完全相同。如果一个是vec3,一个是vec4,shader编译的时候是会报错的。 而gl_FragColor我们知道它肯定是一个系统内置变量了,它的作用是定义最终画在屏幕上面的像素点的颜色。 总结: 对于着色器的编程并不是很困难,完全是C的语法。但是debug比较麻烦,对于类型的约束也很严格,必须是相同类型的才能进行算术运算。我们理解了这两个文件之后,就可以发挥我们的想象对纹理图片做出各种的处理。 另有人总结: vsh 负责搞定像素位置,填写gl_Posizion 变量,偶尔搞定一下点大小的问题,填写 gl_PixelSize。 程序的版本是cocos2dx 3.0.vs 2012. 代码如下: 1 #ifndef __GLTesting_H_ 2 #define __GLTesting_H_ 4 #include "cocos2d.h" 6 USING_NS_CC; 7 8 class GLTestingLayer : public cocos2d::Layer 9 { 10 public: 11 static cocos2d::Scene* createScene(); virtual bool init(); 13 void menuCloseCallback(cocos2d::Ref* pSender); 14 CREATE_FUNC(GLTestingLayer); void graySprite(Sprite * sprite); void visit( Renderer* renderer,const kmMat4 &parentTransform,255); line-height:1.5!important">bool parentTransformUpdated ) override; 17 void onDraw(); 18 private: 19 CustomCommand _command; 20 }; 21 #endif // ! __GLTesting_H_ 内有利用shader使得sprite变灰的代码。 下面是变灰所用到的vsh和fsh文件。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |