gamemakerstudio2的shader入门教程 糖豆版

分类栏目:gamemaker教程

219

第一部分:开启shader

首先简单说一下,shader,好像翻译成渲染器,主要就是把运算量转移到显卡去,让显卡的上千条渲染线并行工作。所以如果你的图片需要一些特殊处理,逐像素循环的话浪费CPU而且会很慢,转移到显卡就快多了。咱感触最深的是咱有个图片计算器,启用shader直接让几十秒等进度条的运算变成了60FPS的实时运算。
然后是shader的正题。shader的用法和blend mode特别,特别,特别的像,用的时候开启,用完关上。相关的代码也就那两句:
shader_set(shader0);//开启shader,此后的所有绘制过程都会按shader0标准来(而不是GM自带的方式)(就像开启了bm)
shader_reset();//关闭shader回归默认方式(就像回到了bm_normal)

对,就现在来说,在GML里需要的部分,没了。


第二部分:参数、纹理传递

shader的教程真的这么简单就结束了嘛,当然不,比如咱的图片制作工具,是用两张图片来计算,但启用shader以后只能有一个“绘制进去的内容”,另一张图,或者叫“背景”却没办法传递进去。再比如shader里有一些参数需要微调,不能针对每个参数做单独的shader吧,所以说还需要一个把参数传递到shader里用的方法。是的,这些都有。


在下一步的介绍之前,咱还是先说一下咱目前shader的几个原则:
1、使用shader的时候,绘制的内容、参考的背景(以及其他运算要用的图片)、还有绘制目标,一定都是等大的表面(surface);
2、除极少量的情况外,绘制目标一定是单独的表面;
3、如果涉及透明度方面运算,GM自己的混合模式(blend mode)一定是1,0(GMS2的gpu_set_blendmode_ext(bm_one,bm_zero);)
至于理由……
1、等大表面意味着在不同素材使用UV坐标不用转换;
2、以一个表面的数据运算后直接放回到这个表面,目前遇到的问题全都没有解决方案,而放到新表面上又完全没问题;
3、GM自带混色模式的锅,有必要的话单开一楼来解释


然后,如果想把东西传递到shader里,GML方面需要写的是
传递表面:texture_set_stage(shader_get_sampler_index(<shader名称>,"<shader里的接收名称>"),surface_get_texture(<表面名称>));
传递参数(实数形式):shader_set_uniform_f(shader_get_uniform(<shader名称>,"<shader里的接收名称>"),<变量或值>);
然后,shader里接收方面就是在fsh页里
接收表面:uniform sampler2D <接收名称>;
接收实数:uniform float <接收名称>;
直观一点,大概就是图片这样:

第三部分:shader里边

shader里的语法不是GML语法!你们写GML那些陋习必须改正!
shader里的语法不是GML语法!你们写GML那些陋习必须改正!
shader里的语法不是GML语法!你们写GML那些陋习必须改正!
重要的事情说3遍。
首先,所有的变量都需要定义了,其中rgba这4个单独字母尽量不要用。
然后,句尾的分号必须要加,否则报错。而且GMS2里对于shader语句报错的行一直提示不准,再加上括号高亮一类的提示也不如GML编辑界面,所以一旦shader写长了再报错可能要查很久。
第三是一些GML不太在乎的数据类型问题在shader里要重新重视起来,比如+1和+1.0的区别。
第四是一些函数的差异,比如shader里不能写max(rr, gg, bb)而要写max(rr, max(gg, bb))因为max必须是2个参数
如果你能接受这些差异,可以继续看:
基本上GML习惯里的变量在shader里统一定义成实数类型(float)就可以,记得和数值运算时数值如果是整数就在后边追个.0以便shader识别为实数。shader里有一些GML里没有的数据类型,比如vec2、vec3、vec4分别表示二位向量、三维向量、四维向量,你可以先想象这是2元素、3元素、4元素的数组,可以在变量名后边加[0]、[1]来提取子元素。shader里还有一个好处是也可以用.r、.g、.b和.a来提取,方便了颜色信息(带alpha)的通道分析。还有sampler2D类型,这种变量里边是整张的纹理。
上面那些都理解的话,差不多主要算法部分都能实现了,最后再说一下几个变量/函数:
gm_BaseTexture:纹理变量,内容是GML那边启用shader以后draw的内容;
v_vTexcoord:二维向量,表示当前位置的uv值。shader是并行计算整张图片的,也可以想象成是把图片上所有的像素点遍历了,不同的渲染线会计算不同UV坐标,也就是不同的v_vTexcoord。UV坐标范围是0到1,左上角0.0, 0.0,右上角1.0, 0.0,右下角1.0, 1.0。注意如果不是用的等大表面的话,这个坐标可能需要进行补偿运算;
gl_FragColor:四维向量,4个元素分别是red分量、green分量、blue分量、alpha分量。把最终的运算结果赋值到这里进行输出。
texture2D:函数,第一个参数放材质,第二个参数放UV坐标,返回值是那个像素点RGBA的四维向量信息。


现在很明显的事情是
gl_FragColor = texture2D( gm_BaseTexture , v_vTexcoord);
和没启用shader的感觉差不多,把draw的内容直接就draw出去了(其实比默认shader少考虑了一个draw color)。至于你是要把RGBA提取出来运算一下实现不同的叠加效果、要给v_vTexcoord一些补偿运算还扭曲图形还是做出什么更有意思的内容就看你自己的想法咯。


什么,你说咱的教程没有任何演示例子看不到效果……这个过几天再补充吧,有几个之前在群里发过的看看一会搬过来。另外咱总感觉演示例子会扼杀新人的想象力,明明shader能做到的东西远比这个厉害,我却只给演示了那么一点点。