[从零构建光栅渲染器] 6. 顶点和片元着色器的工作原理
非常感谢和推荐Sokolov的教程,Sokolov使用500行C++代码实现一个光栅渲染器。教程学习过程非常平滑,从画点、线和三角形开始教学,在逐步深入三维变换,投影,再到顶点着色器,片段着色器等等。教程地址:https://github.com/ssloy/tinyrenderer。Sokolov的教程为英文,我翻译了其文章。
在学习过程中,有些内容可能您可能云里雾里,这时就需要查阅《计算机图形学》的书籍了,这里面的算法和公式可以帮助您理解代码。
作者:尹豆(憨豆酒),联系我yindou97@163.com,熟悉图形学,图像处理领域,本章代码: https://github.com/douysu/computer-graphics-notes
本章运行结果

开始
请记住,我的代码只是帮你进行参考,不要用我的代码,写你自己的代码。我是个糟糕的程序员。请你做最疯狂的着色器,并把图片发给我,我会把它们贴在这里。
有趣的时间,首先让我们检查一下我们现在的代码。source code
- geometry.cpp+.h — 218 行
- model.cpp+.h — 139 行
- our_gl.cpp+.h — 102 行
- main.cpp — 66 行
总共525行,正是我们想要的。请注意,只有our_gl.*和main.cpp两个文件负责实际渲染,总共168行。

重构代码
main.cpp中的代码太多了,让我们分割成两部分:
- our_gl.h+cpp——这部分开发者接触不到,说白了是OpenGL的library。
- main.cpp——这是我们想要的重构的。
现在我们应该放什么到our_gl中?ModelView,Viewport 和Projection矩阵初始化函数和三角光栅化。就这些。
下面是文件our_gl.h的内容(我稍后会介绍IShader结构)。
#include "tgaimage.h"
#include "geometry.h"
extern Matrix ModelView;
extern Matrix Viewport;
extern Matrix Projection;
void viewport(int x, int y, int w, int h);
void projection(float coeff=0.f); // coeff = -1/c
void lookat(Vec3f eye, Vec3f center, Vec3f up);
struct IShader {
virtual ~IShader();
virtual Vec3i vertex(int iface, int nthvert) = 0;
virtual bool fragment(Vec3f bar, TGAColor &color) = 0;
};
void triangle(Vec4f *pts, IShader &shader, TGAImage &image, TGAImage &zbuffer);
翻译作者内容:从上面的代码可以看到vertex()方法和fragment()方法,这里就是我们常用的顶点着色器和片元着色器,从这两个函数中,我们可以明白着色器的工作原理。
文件main.cpp现在只有66行,因此我把它完整的列出来(很抱歉代码太长,但我仍然把他完整的列出来,因为我很喜欢它)。
#include <vector>
#include <iostream>
#include "tgaimage.h"
#include "model.h"
#include "geometry.h"
#include "our_gl.h"
Model *model = NULL;
const int width = 800;
const int height = 800;
Vec3f light_dir(1,1,1);
Vec3f eye(1,1,3);
Vec3f center(0,0,0);
Vec3f up(0,1,0);
struct GouraudShader : public IShader {
Vec3f varying_intensity; // written by vertex shader, read by fragment shader
virtual Vec4f vertex(int iface, int nthvert) {
varying_intensity[nthvert] = std::max(0.f, model->normal(iface, nthvert)*light_dir); // get diffuse lighting intensity
Vec4f gl_V

本文通过从零构建光栅渲染器的过程,详细介绍了顶点和片元着色器的工作原理。从Sokolov的教程出发,通过500行C++代码实现,逐步深入讲解三维变换、投影、着色器等内容。通过具体代码示例,解释了着色器如何处理顶点坐标转换和片段颜色计算,展示了Gouraud着色、纹理、法线贴图和镜面贴图的应用。
最低0.47元/天 解锁文章
158

被折叠的 条评论
为什么被折叠?



