前言
shadertoy和glslsandbox上有许多很有意思的shader,都是用glsl编写的。
本文描述了如何直接将这两个网站的单个pass、只用2d贴图的shader,直接应用于cocos2d-x。

前排提示请严格遵守知识共享许可和开源许可协议
vertex shader
由于shadertoy和glslsanbox都是只使用像素着色器,所以顶点着色器就只需要传递整张屏幕的顶点位置即可。
###shader
attribute vec4 a_position;
void main()
{
gl_Position = a_position;
}
###顶点绑定
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
Vec2 vertex[] = {{-1.0f, 1.0f},
{-1.0f, -1.0f},
{1.0f, 1.0f},
{1.0f, -1.0f} };
glBufferData(GL_ARRAY_BUFFER, sizeof(Vec2) * 4, vertex, GL_STREAM_DRAW);
// vertex
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(Vec2), (GLvoid*)(0));
glBindVertexArray(0);
###fragment shader
这里只讨论shadertoy的单个pass 图像着色器,并且不含立方体贴图。
###shader
为了能直接使用需要给shader加上以下输入和调用:
"\nuniform vec3 iResolution;\
uniform float iTime;\
uniform float iTimeDelta;\
uniform vec4 iMouse;\
uniform int iFrame; \
uniform sampler2D iChannel0; \
uniform sampler2D iChannel1; \
uniform sampler2D iChannel2; \
uniform sampler2D iChannel3; \
"
"\nvoid main() \
{ \
mainImage(gl_FragColor, gl_FragCoord.xy); \n\
}";
主体部分可以直接复制网址分享的shader内容。
###uniform 传递
shadertoy和glslsanbox都使用大量的预定义uniform,通过官方教程就能很清楚的知道对于含义。
只要清楚含义就很好办了,这里介绍shadertoy常用的几个:
iResolution 屏幕像素分辨率
iTime shader启动时间,单位秒
iTimeDelta 每帧渲染时间,单位秒
iFrame 帧数
samplerXX iChannel0..3 四张贴图可以是2d也可以是3d立方体贴图,这里只用2d
iMouse 四维向量,xy表示鼠标悬停位置,zw表示鼠标点击位置,这里一般想转化视角可以视情况给参数即可
鼠标位置参数传递可以参考以下:
Vec4 mouse;
e->onMouseMove = [this, &mouse](EventMouse* event) {
mouse.x = event->getCursorX();
mouse.y = event->getCursorY();
_eff->getGLProgramState()->setUniformVec4("iMouse", mouse);
};
e->onMouseDown = [this, &mouse] (EventMouse* event)
{
mouse.z = event->getCursorX();
mouse.w = event->getCursorY();
//_eff->getGLProgramState()->setUniformVec4("iMouse", mouse);
};
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(e, this);
其它参数都非常简单,对于贴图可以直接从shadertoy的的shader源码下方的直接保存。
参考代码:
参考.zip (2.9 KB)
