这次我们来初步尝试下 shader 编程,由于 shader 编程在不同平台的编写形式不同,根据语法分为 glsl 和 hlsl,根据引擎分为:opengl、webgl、directx 和其他我不知道的引擎,一些游戏引擎又会针对 shader 做一些封装:Unity、UE、Godot。
这系列的教程不会详细讲不同平台的区别,虽然不同平台的函数、变量甚至语法可能都有差异,不过思路是共通的,本系列的代码均使用 webgl,而且为了方便快速体验 shader 编程,我们会在一个封装好的平台 https://www.shadertoy.com/ 上去写代码,如果你已经有熟悉的平台,例如 Unity,可以自己根据文中代码进行实践。
先来个 Hello World?不,我直接蓝屏!
对于 shader 编程来说,画个 hello world 还挺麻烦的,所以我们直接先画个蓝屏吧!
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
fragColor = vec4(0.0, 0.0, 1.0 ,1.0);
}
一句核心代码就实现了蓝屏,我们逐步看下上面的代码写的是什么意思。
首先我们定义了一个叫 mainImage 的函数,由于 shadertoy 做了一些封装,其实这个和传统的 shader 编程稍微有点不同。传统的 shader 编程这个函数应该叫 fragment
,也被叫为 fragment shader
,也没有接受入参和出参。这个函数可以认为是系统给我们的钩子函数,绘制每个像素时都会调用这个函数,具体的执行时机由系统决定。
然后就是一句核心代码 fragColor = vec4(0.0, 0.0, 1.0 ,1.0)
,fragColor
是 webgl 的内置变量,表示当前像素的颜色。
后面的 vec4(0.0, 0.0, 1.0, 1.0)
,vec4
可以先看作是一个存了四个值的数据结构,变体还有 vec3
、vec2
,里面的值类型都是 float
(浮点数),vec3
存的就是三个值,以此类推。
我们给 vec4 设置的值是 (0.0, 0.0, 1.0, 1.0),因为这个值是赋给 fragColor 的,那这个值就表示的是颜色值,颜色值用 rgba
表示,所以这个值的意思是红色、绿色的值都为 0,蓝色和 alpha 值为 1.0,所以最终展现了蓝色。
再来个黄屏!
那如果我想要表现的是黄色,那要怎么做呢?根据颜色混合的原理,黄色=红色+绿色,所以我们这样设置:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
fragColor = vec4(1.0, 1.0, 0.0 ,1.0);
}
一个像《赛博朋克2077》跳票通知的东西就出来啦!
这篇文章的内容目前为止没讲太多东西,主要是先让大家熟悉一下,接下来就开始正式地绘制一些常规的图案了。
本次文章的作业是,让屏幕显示出呼伦贝尔大草原的颜色。
暂无关于此日志的评论。