开源一个简单的c++软光栅渲染器
2016-08-08 21:45
176 查看
本文由zhangbaochong原创,转载请注明出处/article/11874537.html
由于开学就大四面临找工作了,为了在简历上放点项目,最近又把上学期练手写的一个c++软光栅渲染demo拿出来重新改了改,稍微优化了一下,顺便增加了光照。虽然写的比较简单,但还是拿出来分享一下,希望能起个抛砖引玉的作用吧,也欢迎指点批评O(∩_∩)O~
(ps :项目代码只有3000行左右,性能方面也比较渣,高性能的光栅渲染可以看空明大大的SALVIAhttp://www.cnblogs.com/lingjingqiu/)
视角矩阵、投影矩阵和屏幕坐标转换矩阵;
一些常用函数(插值、RGB颜色转UINT、角度弧度转换、求反射向量).
图元装配,也就是将顶点以一定顺序组装成三角形,本项目中采用顶点索引的方式来组织顶点,并且三角形顺时针顺序对应的法线朝向外面。之所以规定好顺序,是为了法线方向的一致性,只有这样才能进行后面的背面消隐。
投影后的坐标再进行透视除法,让顶点坐标位于cvv中(x[-1,1],y[-1,1],z[0,1]),裁剪过后再将cvv坐标转化为屏幕中对应的坐标。
三角形光栅算法:/article/3598577.html
填充三角形使用的扫描线。
View Code
等有时间我会再优化一下,比如采用SIMD加速等等。最近应该没时间搞这个了,d3d最近都没怎么看,为了开学找工作得把算法数据结构再复习下!
由于开学就大四面临找工作了,为了在简历上放点项目,最近又把上学期练手写的一个c++软光栅渲染demo拿出来重新改了改,稍微优化了一下,顺便增加了光照。虽然写的比较简单,但还是拿出来分享一下,希望能起个抛砖引玉的作用吧,也欢迎指点批评O(∩_∩)O~
(ps :项目代码只有3000行左右,性能方面也比较渣,高性能的光栅渲染可以看空明大大的SALVIAhttp://www.cnblogs.com/lingjingqiu/)
1.主要模块功能
1.1数学库
向量、矩阵的实现与变换(矩阵平移、旋转、转置、行列式、逆矩阵);视角矩阵、投影矩阵和屏幕坐标转换矩阵;
一些常用函数(插值、RGB颜色转UINT、角度弧度转换、求反射向量).
1.2后缓冲区
设置像素,我一开始采用SetPixel()函数,发现速度慢的不忍直视。后来改成用CreateDIBSections创建位图,直接向内存中写像素颜色值,完了后一块BitBlt到窗口就行了。1.3模型标准
由于之前一直在写directx11的代码,所以这里也采用标准d3d的坐标模型,左手系+world view proj三矩阵1.4几何阶段
顶点从模型空间到世界空间到相机空间到齐次裁剪空间,对应的主要是三个矩阵world view proj,数学库中提供了相应方法。图元装配,也就是将顶点以一定顺序组装成三角形,本项目中采用顶点索引的方式来组织顶点,并且三角形顺时针顺序对应的法线朝向外面。之所以规定好顺序,是为了法线方向的一致性,只有这样才能进行后面的背面消隐。
投影后的坐标再进行透视除法,让顶点坐标位于cvv中(x[-1,1],y[-1,1],z[0,1]),裁剪过后再将cvv坐标转化为屏幕中对应的坐标。
1.4三角形光栅化
线框模型使用的bresenham画线算法。三角形光栅算法:/article/3598577.html
填充三角形使用的扫描线。
1.5背面消隐
可以参考:/article/3598572.html1.6简单CVV裁剪
1.7支持纹理
纹理uv坐标同d3d,纹理坐标寻址同d3d的wrap方式,贴图在物体表面重复,类似于我们设置桌面是图片的平铺方式。当坐标大于1时,通过去掉整数部分,根据得到的小数部分来得到纹理值;坐标小于0,则加上一个最小正数,让坐标大于0。1.8简单光照
phong光照模型,实现平行光、点光源与聚光灯三种。1.9简单着色器
写了一个着色器类,有VS和PS两个函数对应顶点着色器和像素着色器,部分代码如下:VertexOut BoxShader::VS(const VertexIn& vin) { VertexOut out; out.posH = vin.pos * m_worldViewProj; out.posTrans = vin.pos * m_world; out.normal = out.normal * m_worldInvTranspose; out.color = vin.color; out.tex = vin.tex; return out; } ZCVector BoxShader::PS(VertexOut& pin) { //单位化法线 pin.normal.Normalize(); //纹理采样 ZCVector texColor = m_tex.Sample(pin.tex); //顶点到观察点向量 ZCVector toEye = (m_eyePos - pin.posTrans).Normalize(); //初始化颜色值全部为0 ZCVector ambient(0.f, 0.f, 0.f, 0.f); ZCVector diffuse(0.f, 0.f, 0.f, 0.f); ZCVector specular(0.f, 0.f, 0.f, 0.f); //光源计算后得到的环境光、漫反射 、高光 ZCVector A, D, S; Lights::ComputeDirectionalLight(m_material, m_dirLight, pin.normal, toEye, A, D, S); ambient = ambient + A; diffuse = diffuse + D; specular = specular + S; //纹理+光照计算公式: 纹理*(环境光+漫反射光)+高光 ZCVector litColor = texColor * (ambient + diffuse) + specular; //最终颜色透明度使用漫反射光的透明度 litColor.w = m_material.diffuse.w * texColor.w; return litColor; }
View Code
2.截图效果
2.1线框模型
2.2顶点色
2.3纹理+光照
图片本身是木纹材质,显得比较粗糙/(ㄒoㄒ)/~~3.源码
项目托管到Github上了:https://github.com/zhangbaochong/Tiny3D等有时间我会再优化一下,比如采用SIMD加速等等。最近应该没时间搞这个了,d3d最近都没怎么看,为了开学找工作得把算法数据结构再复习下!
相关文章推荐
- 发现一个开源的负载测试工具 loadUI,使用简单,开源
- 发现一个开源的负载测试工具 loadUI,使用简单,开源
- 分享一个简单易用的RPC开源项目—Tatala
- [安卓] 17、一个简单的例子学安卓侧滑设计——用开源slidingmenu
- 学习Android开源项目-根据知乎日报API分析重构一个简单的知乎日报Android客户端
- 发布一个开源项目,基于thinkphp框架搭建的一个简单框架
- KTDictSeg 一个C#.net做的简单快速准确的开源中文分词组件
- 分享一个简单易用的RPC开源项目—Tatala
- 一个简单的开源DIRECTUI界面框架
- 【个人收藏】Direct UI 与一个简单的开源DIRECTUI界面框架
- 金山卫士开源软件之旅(二) 简单教程:如何创建一个基于金山卫士界面库的工程
- 开源一个C#写的小爬虫,简单实用
- 一个简单的基于PHONEGAP的开源微博客户端
- 一个简单的开源PHP爬虫框架『Phpfetcher』
- 简介 WatiN是一个开源的用于Web测试自动化的类库,从watir中获得的灵感,使用C#开发。WatiN通过与浏览器的交互来实现自动化,使用起来具有轻便,简单的特点。目前最新版本为2.0,加入了对
- 开源一个简单的计算器
- 一个简单的开源PHP日志类
- 开源!!一个简单的代理吸附工具
- 一个简单的开源PHP爬虫框架『Phpfetcher』
- 分享一个简单易用的RPC开源项目—Tatala