认识着色器

理解OpenGL渲染管线,对于学习OpenGL非常重要。下面是OpenGL渲染管线的示意图:(图中淡蓝色区域是可以编程的阶段)

此图是从wiki中拿过来的,OpenGL的渲染管线主要包括:

  1. 准备顶点数据(通过VBO、VAO和Vertex attribute来传递数据给OpenGL)

  2. 顶点处理(这里主要由Vertex Shader来完成,从上图中可以看出,它还包括可选的tessellation和Geometry shader阶段)

  3. 顶点后处理(主要包括Clipping,顶点坐标归一化和viewport变换)

  4. Primitive组装(比如3点组装成一个3角形)

  5. 光栅化成一个个像素

  6. 使用Fragment shader来处理这些像素

  7. 采样处理(主要包括Scissor Test,Depth Test,Blending,Stencil Test等)。

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。

fsh 负责搞定像素外观,填写 gl_FragColor ,偶尔配套填写另外一组变量。

他们都是一个像素运行一次的,也可能运行多次。为了“这一像素”而努力计算。

程序的版本是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_
1 #include GLTestingLayer.h 2 3 cocos2d::Scene* GLTestingLayer::createScene() 4 { 5 auto scene = Scene::create(); 6 auto layer = GLTestingLayer::create(); 7 scene->addChild(layer); 8 return scene; 9 } 10 11 bool GLTestingLayer::init() 12 { if ( !Layer::init() ) 14 { 15 return false; 16 } 17 this->setPosition(0,0); 19 Size visibleSize = Director::getInstance()->getVisibleSize(); 20 auto sprite = Sprite::create(HelloWorld.png"); 21 sprite->setAnchorPoint(Point(0.5,128); line-height:1.5!important">0.5)); 22 sprite->setPosition(Point(visibleSize.width / 2,visibleSize.height / 2)); 23 this->addChild(sprite); 24 graySprite(sprite); 25 26 this->setShaderProgram( shadercache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_COLOR)); 28 true; 29 } 30 31 void GLTestingLayer::menuCloseCallback( cocos2d::Ref* pSender ) 32 { 33 34 } 35 36 void GLTestingLayer::graySprite( Sprite * sprite ) 37 { 38 if(sprite) 39 { 40 GLProgram * p = new GLProgram(); 41 p->initWithFilenames(gray.vsh",0); line-height:1.5!important">gray.fsh42 p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION,GLProgram::VERTEX_ATTRIB_POSITION); 43 p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR,GLProgram::VERTEX_ATTRIB_COLOR); 44 p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD,GLProgram::VERTEX_ATTRIB_TEX_COORDS); 45 p->link(); 46 p->updateUniforms(); 47 sprite->setShaderProgram(p); 48 } 49 50 } 51 52 void GLTestingLayer::visit( Renderer* renderer,255); line-height:1.5!important">bool parentTransformUpdated ) 53 { 54 Layer::visit( renderer,parentTransform,parentTransformUpdated ); 55 _command.init(_globalZOrder); 56 _command.func = CC_CALLBACK_0(GLTestingLayer::onDraw,255); line-height:1.5!important">this); 57 Director::getInstance()->getRenderer()->addCommand(&_command); 58 } 59 60 void GLTestingLayer::onDraw() 61 { 62 auto glProgram = this->getShaderProgram(); 63 glProgram->use(); 64 glProgram->setUniformsForBuiltins(); 65 glPointSize( 10.0f); 66 glColor4f( 0.0f,128); line-height:1.5!important">1.0f,128); line-height:1.5!important">1.0f); 67 auto size = Director::getInstance()->getWinSize(); 68 69 float vertercies[] = { 100,128); line-height:1.5!important">100,70 200,128); line-height:1.5!important">200,128); line-height:1.5!important">71 300,128); line-height:1.5!important">100 }; 72 float color[] = { 1,128); line-height:1.5!important">1,128); line-height:1.5!important">73 74 1 }; 75 GL::enabLevertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR ); 76 glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION,GL_FLOAT,GL_FALSE,128); line-height:1.5!important">0,vertercies ); 77 glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR,128); line-height:1.5!important">4,GL_TRUE,color); 78 绘制三角形 79 glDrawArrays(GL_TRIANGLES,128); line-height:1.5!important">3 ); 80 通知cocos2d-x 的renderer,让它在合适的时候调用这些OpenGL命令 81 CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(3); 82 CHECK_GL_ERROR_DEBUG(); 83 84 }

内有利用shader使得sprite变灰的代码。

下面是变灰所用到的vsh和fsh文件。

1 attribute vec4 a_position; 2 attribute vec2 a_texCoord; 3 attribute vec4 a_color; 4 6 varying vec4 v_fragmentColor; 7 varying vec2 v_texCoord; 8 void main() 10 { 11 gl_Position = CC_PMatrix * a_position; 12 v_fragmentColor = a_color; 13 v_texCoord = a_texCoord; 14 }
1 varying vec4 v_fragmentColor; 2 varying vec2 v_texCoord; 3 uniform sampler2D CC_Texture0; 4 5 void main() 7 vec4 v_orColor = v_fragmentColor * texture2D(CC_Texture0,v_texCoord); float gray = dot(v_orColor.rgb,vec3(0.299,128); line-height:1.5!important">0.587,128); line-height:1.5!important">0.114)); 9 gl_FragColor = vec4(gray,gray,v_orColor.a); 10 }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


如何使用CCRenderTexture创建动态纹理 Cocos2d-x 2 1 4
    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
Cocos2D-x-3.0 编译(Win7)
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
quick-cocos2d-x实例之挑战记忆极限设计文档
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
Cocos2d-x 3 X CMake MinGW版本编译运行
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
vs 2013 编译cocos2d-x-3.9
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
Cocos2d-x CCControlPotentiometer之圆形音量button及特效
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
Cocos2d-x入门教程二简单的静态显示对象
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建

opengl之vsh、fsh简易介绍+cocos2dx 3.0 shader 变灰的更多相关文章

  1. 详解HTML5中CSS外观属性

    这篇文章主要介绍了HTML5中CSS外观属性的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,,需要的朋友可以参考下

  2. ios – 痛苦地减慢软件向量,特别是CoreGraphics与OpenGL

    )在这个实验之后,我切换到了OpenGL和MonkVG库,我感到非常高兴.我现在可以在没有任何帧速率下降的情况下同时渲染HUNDREDS曲线,对保真度的影响很小.>我是否有可能以某种方式滥用CoreGraphics,或者性能真的那么糟糕?我的预感是问题在于CoreGraphics,基于StackOverflow/论坛问题的数量以及有关CG性能的答案.从技术上讲,为什么会这样呢?>如果CoreGraphics真的那么慢,Safari究竟如何顺利地工作?OpenGL在早餐时吃这个测试.矢量绘图怎么可能如此慢得

  3. ios – 如何从变量访问属性或方法?

    是否可以使用变量作为Swift中方法或属性的名称来访问方法或属性?在PHP中,您可以使用$object->{$variable}.例如编辑:这是我正在使用的实际代码:解决方法你可以做到,但不能使用“纯粹的”Swift.Swift的重点是防止这种危险的动态属性访问.你必须使用Cocoa的Key-ValueCoding功能:非常方便,它完全穿过你要穿过的字符串到属性名称的桥,但要注意:这里是龙.

  4. iOS >>块>>更改块外部的变量值

    我不是在处理一个Object并改变它,就像我的mString一样.我希望’center’属性的行为类似于myInt,因为它是直接访问的C结构,而不是指向对象的指针.我希望’backgroundColor’的行为类似于我的imstring,因为它是一个指向一个新对象的对象的指针,不是吗?

  5. ios – Xcode Bot:如何在post触发器脚本上获得.ipa路径?

    我正在使用机器人来存档iOS应用程序,我需要获取.ipa产品路径才能将其发布到我们的分发系统中.机器人设置:并使用脚本打印所有env变量,其中不包含ipa文件的路径.此外,一些变量指向不存在的目录,即:XCS_OUTPUT_DIR这里的env变量输出:除此之外,我还能够确认.ipa文件是在另一个文件夹中创建的(/IntegrationAssets//

  6. ios – 使用附加字符串本地化Info.plist变量

    我正在尝试本地化应用程序的名称,同时仍然能够根据构建配置追加字符串.所以目前它被设置为:该设置定义为:通过这种方式,我们可以为应用程序添加后缀以用于不同的beta版本.问题是,当我们尝试本地化本地化的InfoPlist.strings中的应用程序显示名称时,就像这样我们覆盖存储在Info.plist中的值,并丢失后缀字符.这有什么好办法吗?

  7. 为什么这个OpenGL ES 2.0着色器不能在iOS上使用我的VBO?

    如果有人能够了解这里出了什么问题,也许是对gl命令或其他一些不兼容的命令序列的错误排序,我将非常感谢你的帮助.尽管谷歌在“OpenGLES2.0编程指南”中进行了大量研究和研究,但我一直试图让这段代码整天都没有成功.我正在尝试在iPhone上的OpenGLES2.0中使用顶点缓冲区对象和自定义着色器.我试图交错来自以下类型的一系列自定义结构的顶点数据:位置,半径和颜色字节分别考虑顶点位置,点大小和

  8. iOS – 开始iOS教程 – 变量之前的下划线?

    这是正确的还是我做错了什么?

  9. ios – 静态计算变量被多次实例化

    我有一个日期格式化程序,我试图在UITableViewCell子类中创建一个单例,所以我创建了一个这样的计算属性:问题是我不止一次看到print语句,这意味着它不止一次被创建.我已经找到了其他方法,但我很想知道这里发生了什么.有任何想法吗?解决方法您的代码段相当于只获取属性,基本上它与以下内容相同:如果你只想运行一次,你应该像定义一个惰性属性一样定义它:

  10. ios – 为什么Apple建议在串行后台队列中调度OpenGL命令,这不可避免地会导致崩溃?

    他们suggest:WhenusingGCD,useadedicatedserialqueuetodispatchcommandstoOpenGLES;thiscanbeusedtoreplacetheconventionalmutexpattern.我不明白这个建议.我无法解决这种冲突:当应用程序的app委托收到-applicationWillResignActive调用时,它必须立即停止调用任

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部