这是一个用C#+winform实现的软件光栅化渲染器,今天拿出来与大家分享一下,希望能起到抛砖引玉的作用,给新人一点启发(结构比较简单,注释比较详细^_^),也欢迎司机们拍砖指点和交流~

目的:

巩固图形编程知识,理解渲染流水线所做的事情。

实现功能:

1、将顶点数据进行一系列处理显示到屏幕上(废话。。。(¬_¬))

2、线框渲染模式、纹理渲染模式、顶点色模式

3、纹理uv坐标和顶点色等的透视校正插值

4、纹理双线性过滤采样

5、背面消隐

6、Cvv简单裁剪

7、“基础光照模型”(相当于D3D、OpenGL中的固定管线顶点光照)

截图:

光照

顶点色

线框模式:


代码放在Github上面: https://github.com/aceyan/SimpleSoftwareRenderer

下面我会将一些完成这个渲染器所需要的知识点以及相关资料的链接(多是博文)罗列一下,方便查阅。

零、准备阶段

想要实现渲染器首先我们得知道“给定视点、三维物体、光源、照明模式,和纹理等元素,如何绘制一幅二维图像”,这就必须提到一个词“图像绘制管线”(也称绘制流水线),我们得渲染器正是要以软件的形式来模拟这条流水线的运作。

流水线:http://www.cnblogs.com/wonderKK/p/5022226.html

理解了绘制管线,我们发现其中充满对矩阵向量等数学工具的运用,那么再实现流水线之前,我们必须先实现这些数学工具,这些数学类网上已经有很多的资料了,但是有几点需要特别说明:

1、本程序中使用行矩阵与行向量

相关资料:D3d和openGl矩阵区别

http://blog.csdn.net/Nightmare/article/details/3983724

2、本程序使用左手坐标系

3、实现了color类来方便进行颜色的运算,因为进行光照的时候要使用颜色乘以颜色的计算方法,它跟向量的乘法不同,应该称为“Modulate(调制)”,注意不能用向量乘法的计算公式哦。

相关资料:

https://www.zhihu.com/question/24026277/answer/26433842

@Milo Yip 大神的博文里面有一段讲颜色计算的:

http://www.cnblogs.com/miloyip/archive/2010/03/29/1698953.html#1794025

4、矩阵求逆

由于要进行光照,我们需要变换顶点法线,那么就需要矩阵求逆和求转置的运算。(为什么需要逆转置呢?请看:https://www.zhihu.com/question/27739027)

其中矩阵求逆比较复杂,本程序使用的是伴随矩阵的方法求矩阵的逆, 必须先求出矩阵的行列式和伴随矩阵,这部分需要一定的线性代数基础知识。

4.1矩阵求逆重要定理:

http://wenku.baidu.com/link?url=dga27GT5oSK8SDwHaeqPGL_raHnMLNP54oad7q8wJnMOqEpuT4_UAC-BHAeTsL8vGpYkRuphnXng99TLfHOx8_Nn7WMVycFRlUiMgSS-2Ve

4.2求矩阵行列式

本程序使用递归算法求行列式,请查看矩阵行列式的递归定义:

http://wenku.baidu.com/link?url=9TSCuxJdfypmsqZLYegHNuKYP1TABFwGT22v-cJut5wenWM-Ll2Bp6zqgDEeIvd9ChV3Laj3czAbdWtjSwaulHHSkUZtrLNcgLqNw2xrjb7,

4.3伴随矩阵:

http://wenku.baidu.com/link?url=BVbtO30v7eygbZUloybJtpFkCrpAwypYNyIx7XGX-OItxdWz0w4Y2hpzux729bq4MLKnx0sWwS4mJwm8Nrnf_3zxG9RqzD7LND3mklrwyDe

实现了数学类,就可以正式进入流水线了:

一、几何阶段

1、顶点从模型空间----->世界空间

这一步要生成世界矩阵(简称m),m是一系列平移、选择等变换的组合

如果开启了光照,我们还需要把模型空间的法线信息变换到世界空间,对顶点进行光照计算并保存光照结果颜色,以便在光栅化的时候进行差值和颜色调制(Modulate)

这里实现的“简单光照模型”可以参见《Cg教程_可编程实时图形权威指南》第五章光照

2、世界空间----->相机空间

这一步需要生成视矩阵(简称v)

推导过程:@zdd的博客 http://www.cnblogs.com/graphics/archive/2012/07/12/2476413.html

上面的推导中写错了

应该是

rxry rz

[ ux uy uz ]

dx dy dz

但是推导结果是对的

3、相机空间--->齐次剪裁空间

这里要生成投影矩阵,简称p

Dx风格的投影矩阵推导:

http://www.cnblogs.com/graphics/archive/2012/07/25/2582119.html

本程序使用的投影矩阵:

视空间的顶点乘以这个矩阵之后被变换到齐次剪裁空间,并且w分量保存着视空间的z信息。

在齐次剪裁空间我们可以对顶点进行简单的裁剪,既将不在

-w <= x <= w

-w<= y <= w

0 <= z <= w

这个范围的顶点剔除掉,不进行渲染。

这里采用的是最简单粗暴的剪裁方法,更加复杂的剪裁还需要生成新的顶点,有很多可以深入挖掘的地方:)

Ps:为了方便后续的透视校正插值,程序中还将1/z 保存在顶点数据中。

4、进行图元装配,也就是将顶点以一定的顺序组装成三角形(Primitive Assembly && Trianglesetup )

本程序中使用了顶点索引的方式来组织顶点数据,并且约定以逆时针顺序组织的三角形的法线朝向屏幕外,换句话说就是逆时针顺序组织的三角形看起来是正面。

有了这个约定就可以进行背面消隐:

http://blog.csdn.net/cppyin/article/details/6207206

5、透视除法

对透视变换得到的含有深度信息(z)的齐次坐标做透视除法。所谓透视除法,
  就是把透视变换后的齐次坐标除以(z)。由于透视变换矩阵已经构造好了,当
  视锥体内部点经透视处理后的齐次坐标除以(z)后,使得顶点进入

-1<= x <= 1

-1<= y <= 1

0 <= z <= 1  (CVV正方体中)。

6、映射到视口

将cvv正方体的顶点根据屏幕大小或者视口大小转换为屏幕坐标

二、光栅化阶段

1、Rasterization光栅化

光栅化决定哪些像素被几何图元覆盖的过程

1.1 如果选择线框模式,本程序使用的画线方法是Bresenham快速画直线算法

相关资料:http://www.cnblogs.com/gamesky/archive/2012/08/21/2648623.html

1.2顶点色模式和纹理模式

三角形光栅化算法:http://blog.csdn.net/cppyin/article/details/6232453

扫描线填充算法:http://blog.csdn.net/cppyin/article/details/6172211

光栅化过程当中,我们要对uv坐标,顶点颜色、我们保存在顶点信息中的1/z等信息进行透视校正插值:

http://blog.csdn.net/popy007/article/details/5570803

文章中的重要结论:

我们发现s/z、t/z和x’、y’也是线性关系。而我们之前知道1/z和x’、y’是线性关系。则我们得出新的思路:对1/z关于x’、y’插值得到1/z’,然后对s/z、t/z关于x’、y’进行插值得到s’/z’、t’/z’,然后用s’/z’和t’/z’分别除以1/z’,就得到了s’和t’。

这就是为什么我们要保存1/z的原因。

2、Pixel Operation 像素操作

2.1消除遮挡面

根据zbuff  使用1/z来进行ztest,这样就不用给zbuff初始化一个很大的值了。

2.2 Texture operation 纹理操作,也就是根据像素的纹理坐标,查询对应的纹理值

纹理坐标的透视校正: http://blog.csdn.net/popy007/article/details/5556639

纹理采样,双线性纹理过滤:http://dev.gameres.com/Program/Visual/3D/Bilinear.htm

http://blog.csdn.net/i_dovelemon/article/details/27839279

2.3 Blending

本程序暂时没有对alpha的处理,后面应该会更新

2.4:Filtering

相当于后处理,就是对即将写入framebuff(帧缓冲)的像素进行一些处理,本程序暂时没有添加。

经历了上面的步骤,把要渲染的像素写到framebuff中,再将framebuff渲染到屏幕上就完成了所有步骤(本程序简单的生成了一个bitmap来作为framebuff),这时你应该可以在屏幕上看到你所渲染的东西。如果看起来不太对,那么进入debug吧。一开始也许会觉得调试这样一个绘制流水线会无从下手,因为其中任何一步的偏差都会使最后的渲染发生错误。

请假了一些大神后找到了不错的调试方法,下面给出一些tips:

1、调试数学库,用笔算来验证结果的正确性

2、调试流水线,可以建立一个简单多边形,比如一个quad,用笔算来验证m、v、p三个矩阵的正确性。光栅化的阶段由于要进行插值,计算量比较大,建议使用心算和单步跟踪的方式来进行调试。

笔算的过程能让你更加了解背后的数学奥秘:)

最后要感谢一下@cppyin,@zdd,@Milo Yip,@韦易笑等大神的文章,给我很大帮助。

特别要推荐@韦易笑老师写的mini3D:http://www.skywind.me/blog/archives/1498,让我受益匪浅。

用C#实现一个简易的软件光栅化渲染器相关推荐

  1. matlab z变换离散化_用C++编写一个简单的光栅化渲染器:3D篇

    3D光栅化与2D光栅化在图元绘制方面差别并不大,3D光栅化主要是多了很多坐标系(Local,world,View...),除此外遮挡算法和裁剪算法也会稍微复杂一些. 本篇文章的重点就主要集中在各种坐标 ...

  2. 稳扎稳打Silverlight(18) - 2.0视频之详解MediaElement, 开发一个简易版的全功能播放器...

    [索引页] [×××] 稳扎稳打Silverlight(18) - 2.0视频之详解MediaElement, 开发一个简易版的全功能播放器 作者:webabcd 介绍 Silverlight 2.0 ...

  3. 一个简易版的iphone电子书阅读器

    2019独角兽企业重金招聘Python工程师标准>>> 一个简易版的iphone电子书阅读器 里面的基本功能都有了 感兴趣的朋友可以下来研究 点击此处下载源码 转载:http://w ...

  4. 上面两点下面一个三角形_三角形光栅化

    Scanline triangle rasterizer 将三角形分成4类: 1.平顶三角形 2.平底三角形 3.右边为主 4.左边为主 1.平顶三角形 void 2.平底三角形 void 3.后两种 ...

  5. 通俗傻瓜式理清光栅化渲染和光线追踪渲染的原理

    本文适合完全不了解渲染又想略窥一二的兴趣朋友,我也非大牛,仅写下自己粗略的理解,内容上难免会有错漏,如果你发现有误的地方,欢迎交流修改.文中部分图片来源网络,如侵权请联系,我马上修改. 1.让你做渲染 ...

  6. 利用Qt制作一个简易聊天软件

    需求分析 即时通讯软件是通过即时通讯技术来实现在线聊天.交流的软件.需要完成基本的通信需求及工作场景需求. 架构分析 截图展示 项目简介 我们编写的即时通信软件叫做SeeU,它是一款基于Qt开发平台, ...

  7. 基于Unity的软光栅实现(3):基于Job system的多核加速光栅化

    文章目录 系列文章导航 拥抱CPU多核计算 Job System简介 ParallelFor Job JobRasterizer 数据准备:JobRenderObjectData 缓冲区表示和Clea ...

  8. SoftRendererRenderPipeline(从迷你光栅化软渲染器的实现看渲染流水线)

    简介 这是可能一篇没有什么实际作用的文章,因为没有任何shader效果实现,整篇文章到最后,我只实现了一个旋转的立方体(o(╯□╰)o,好弱),和游戏引擎渲染的万紫千红的3D世界显得有很大落差,仿佛一 ...

  9. 上面两点下面一个三角形_图形学底层探秘 - 更现代的三角形光栅化与插值算法的实现与优化...

    前言 本文是对之前实现的软光栅渲染器中光栅化算法的进一步讲解与优化,这里放上前文的传送门:https://zhuanlan.zhihu.com/p/95621444 在之前的文章中,我使用的是扫描线算 ...

最新文章

  1. Java 运行时数据区域,哪些是线程隔离的?哪些又是公有的?
  2. 1090 Highest Price in Supply Chain (25 分)【难度: 一般 / 知识点: 树的遍历】
  3. binary masks_Python中的Masks概念
  4. 前端学习(3208):react中的事件绑定
  5. php$this-conn可以不先定义吗,CodeIgniter 是不是支持PDO 查询?还是本来就不支持
  6. 程序员对辉瑞新冠疫苗的计算解读,这些常识可能你也不知道
  7. mysql Error_code: 1593
  8. python制作软件界面_Python 脚本 GUI 界面生成工具
  9. Ubuntu 16.04升级Linux内核为4.7.0最快的方法
  10. android应用程序开发_如何开始进行Android应用程序开发
  11. 适合自己的网名测试软件,如何取个适合自己的网名?
  12. 计算机恢复语言文件格式,txt文件乱码怎么恢复正常
  13. 这是一个猜数字的游戏。判断输入的第1个字符,略过其余的字符。
  14. [智慧园区]之访客应用
  15. 短视频SDK用于旅游行业
  16. Godot着色器语言
  17. Marvell宣战博通网络交换芯片,一大波饿狼扑食而来
  18. 计算机二级您是系统管理用户,全国计算机等级考试(NCRE)考务管理系统考生网报手册...
  19. 谈谈Web端性能测试
  20. QCC3040---Glossary

热门文章

  1. 微信开发------------公众号支付统一下单整个流程
  2. item_get - 获得suning商品详情
  3. html网页设计文字出现动画,网页设计中的文字与图片的动画有以下几种形式
  4. 字符映射表没有所有字体(专用字符),以及显示空白的解决办法
  5. 情人节送什么礼物好呢?实用又有纪念意义的礼物推荐
  6. 实例019:完数 一个数如果恰好等于它的因子之和,这个数就称为“完数“。例如6=1+2+3.编程找出1000以内的所有完数。
  7. 大数据心法来了!一站式玩转MaxCompute
  8. mysql使用()文件中的配置参数_MySQL使用( )文件中的配置参数。 答案:my.ini
  9. 阿里的黄金时代|一点财经
  10. FT232驱动安装不成功的解决方案