Shader能做什么
定位顶点非常快
计算颜色非常快
计算光照非常快
可以做大量的数学计算
Shader不能做什么
不能在网格以外绘制
不能访问当前绘制像素(或顶点)以外的像素
不能存储之前的迭代器
不能在运行中更新(可以,但必须编译)
Shader的结构
在Godot中,Shader由3个主函数组成:vertex()
,fragment()
以及light()
。
vertex()
函数会遍历网格的所有顶点并设置它们的位置以及其它一些逐顶点变量(per-vertex variables
)。
fragment()
函数会对每一个被网格覆盖的像素执行。它会基于vertex()函数提供的变量运行。这些变量会在顶点间进行插值以供fragment()
函数使用。
light()
函数会逐像素逐光源执行。它会基于fragment()
函数提供的变量以及自身先前运行的结果来运行。
要获取更详细的信息请阅读Shaders。
技术概要
GPU渲染速度远大于CPU有很多原因,其中最主要的是,它们可以进行大规模的并行计算。一个CPU一般有4或8个核心(core),而GPU一般(至少)上千个核。这意味着GPU可以同时进行(至少)上百个任务。GPU架构师充分利用了这一点使得GPU可以非常迅速地处理大量运算。前提是当GPU的多数甚至全部核心都在针对不同数据进行相同的运算。
Shader由此而生。GPU会同时批量地调用Shader来处理数据块提供(包括顶点和像素)。这些大批量的数据块被称为波前(wavefronts)。在一个波前里Shader会对每个线程进行相同的操作。比如,如果一个GPU给每个波前提供100个线程,那么一个波前将在一个10x10的像素块上运行。然后它对所有的像素执行这个波前直至全部完成。相应地只要你(的波前中)有一个像素处理慢于其它像素(由于分支过度),整个波前将被拖后腿,最后导致大大延缓了渲染速度。这一点和基于CPU的处理非常不同,在CPU上,只要你对一个像素的处理提速,那么整个渲染时间就减少了,而在GPU上你必须对整个波前加速,才能提高渲染速度。