GMS2的shader入门教程 糖豆版
gamemaker吧
全部回复
仅看楼主
吧务
level 13
q糖豆p 楼主
不知道什么时候,咱成了群里“会用shader”那一边的。想想看教程和实际用shader走过的弯路,咱也写点东西,希望能有那么一点帮助。
2018年07月14日 03点07分 1
吧务
level 13
q糖豆p 楼主
第一部分:开启shader
首先简单说一下,shader,好像翻译成渲染器,主要就是把运算量转移到显卡去,让显卡的上千条渲染线并行工作。所以如果你的图片需要一些特殊处理,逐像素循环的话浪费CPU而且会很慢,转移到显卡就快多了。咱感触最深的是咱有个图片计算器,启用shader直接让几十秒等进度条的运算变成了60FPS的实时运算。
然后是shader的正题。shader的用法和blend mode特别,特别,特别的像,用的时候开启,用完关上。相关的代码也就那两句:
shader_set(shader0);//开启shader,此后的所有绘制过程都会按shader0标准来(而不是GM自带的方式)(就像开启了bm)
shader_reset();//关闭shader回归默认方式(就像回到了bm_normal)
对,就现在来说,在GML里需要的部分,没了。
2018年07月14日 03点07分 2
哇!糖豆大佬,支持。顺带一提:应该是“着色器”吧……
2018年07月14日 09点07分
吧务
level 13
q糖豆p 楼主
第二部分:参数、纹理传递
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 <接收名称>;
直观一点,大概就是图片这样:
2018年07月14日 04点07分 3
吧务
level 13
q糖豆p 楼主
第三部分: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能做到的东西远比这个厉害,我却只给演示了那么一点点。
2018年07月14日 04点07分 4
level 1
糖豆万岁~!你是好糖,你是好豆!
2018年07月14日 05点07分 5
level 15
啊好久没看到糖豆了,学习一下
2018年07月14日 05点07分 6
“闻道有先后,术业有专攻,如是而已”——爱谁说的谁说的,今天就是懒得度娘查
2018年07月20日 02点07分
level 7
这是做崩溃大陆的知识点吧?
2018年07月15日 02点07分 7
别说的好像我知道崩溃大陆是什么样子一样,明明发个教程(其实更像研究报告)总被人安利其他游戏[咦]
2018年07月20日 02点07分
@q糖豆p 黄配紫神教
2018年07月24日 07点07分
level 9
好!顶!赞!对gm8没有卵用
2018年07月20日 12点07分 8
level 10
赞啊 先mark一下
2018年07月20日 13点07分 9
level 5
看不懂啊[泪]
2020年08月17日 04点08分 11
这东西本来就不是拿来“看懂”的,是拿来“用懂”的。
2020年08月17日 10点08分
@q糖豆p 但我连看都看不懂哇[泪]
2020年08月17日 12点08分
@我是53君啦- 怎么用哇[泪]
2020年08月17日 12点08分
@我是53君啦- 就是2楼所说的方法,开启和关闭……等等你在另开帖子找GM8的文档……shader是GMS好像1.2还是1.几新增的功能块,也许你应该先换个版本。
2020年08月18日 05点08分
level 5
而且还那么长[泪]
2020年08月17日 04点08分 12
GML里介绍2个函数和参数解释(详细一点的),差不多也要这个篇幅吧。
2020年08月17日 10点08分
其实很短了,和f1比大概就1%的程度吧
2020年08月19日 00点08分
@MikuScarlet 太抬举我了吧……上次统计函数数量好像是500+还是800+来着,所以和F1比应该是1‰这个数量级的程度吧(毕竟F1里不只是函数,还有基础功能介绍啥的)
2020年08月19日 00点08分
@q糖豆p 看不懂[泪]
2020年08月19日 06点08分
level 11
好耶
2020年08月19日 00点08分 14
1