﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-漫游生活</title><link>http://www.cppblog.com/LSWinson/</link><description /><language>zh-cn</language><lastBuildDate>Fri, 17 Apr 2026 11:47:09 GMT</lastBuildDate><pubDate>Fri, 17 Apr 2026 11:47:09 GMT</pubDate><ttl>60</ttl><item><title>我的第一个3D渲染管线（2）</title><link>http://www.cppblog.com/LSWinson/archive/2009/03/12/76288.html</link><dc:creator>林森(L.S.Winson)</dc:creator><author>林森(L.S.Winson)</author><pubDate>Wed, 11 Mar 2009 16:58:00 GMT</pubDate><guid>http://www.cppblog.com/LSWinson/archive/2009/03/12/76288.html</guid><wfw:comment>http://www.cppblog.com/LSWinson/comments/76288.html</wfw:comment><comments>http://www.cppblog.com/LSWinson/archive/2009/03/12/76288.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/LSWinson/comments/commentRss/76288.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LSWinson/services/trackbacks/76288.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 上次说到渲染管线的一般组成，接下来就要说说各部分的转换怎么做了。<br>在这之前，本着扫盲的态度，先介绍一点矩阵的基础知识。<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/LSWinson/archive/2009/03/12/76288.html'>阅读全文</a><img src ="http://www.cppblog.com/LSWinson/aggbug/76288.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LSWinson/" target="_blank">林森(L.S.Winson)</a> 2009-03-12 00:58 <a href="http://www.cppblog.com/LSWinson/archive/2009/03/12/76288.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的第一个3D渲染管线</title><link>http://www.cppblog.com/LSWinson/archive/2009/03/10/76156.html</link><dc:creator>林森(L.S.Winson)</dc:creator><author>林森(L.S.Winson)</author><pubDate>Tue, 10 Mar 2009 14:40:00 GMT</pubDate><guid>http://www.cppblog.com/LSWinson/archive/2009/03/10/76156.html</guid><wfw:comment>http://www.cppblog.com/LSWinson/comments/76156.html</wfw:comment><comments>http://www.cppblog.com/LSWinson/archive/2009/03/10/76156.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/LSWinson/comments/commentRss/76156.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LSWinson/services/trackbacks/76156.html</trackback:ping><description><![CDATA[<font size=2>&nbsp;&nbsp; 呵呵，既然都说了，是&#8220;我的第一个&#8221;。那自然就不会有太好的效率和表现，不过实现了基本功能，值得鼓励一下~。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PS：这属于扫盲帖，同时邀请牛们来点评下。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先，介绍背景。。。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目前在一个游戏公司实习，培训的时候，有一个扩展练习，就是写一个3D渲染管线。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 之前没写过这种东西，仅仅小用了一下OPENGL，搞了个旋转立方体以后，就因为自己混乱的坐标变换概念无法深入了。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在算是基本实现出来了，马上就发觉了这东西的锻炼价值了，首先是包含的数学多，尤其线性代数，不理解的话很多东西都不能懂。其次，是计算量潜力很大，图形计算，随便一算就几百万几千万的，真要做得好，要优化效率，然后各种东西都来了，汇编啊，显卡啊之类的。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 何为3D渲染管线呢，就是一个能把3D世界模型，转换成屏幕显示的这个东西。说&#8220;管线&#8221;，就是因为它一般是一种类似过滤器的实现方法，经过N步的转换过程，最终输出了屏幕像素信息。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OK，直入主题。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最基本的渲染过程一般包含这样几个步骤。 世界坐标变换、摄像机变换、透视变换、剪切、行扫描输出。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 世界坐标变换：就是把3D世界中的各种物体，通过 缩放、旋转、平移 放置到一个指定的位置，这个过程一般都可以记录成文本或二进制格式，从而渲染管线可以方便地初始化好整个世界信息。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;摄像机变换： 这个比较好理解，3D世界生成好了，那么人在哪里呢？ 我们总要有一个眼睛来看这个3D世界。这个眼睛的位置不同，所看到的东西也就不同。 这个摄像机变换，就把3D世界的物体坐标转换为眼睛看到的坐标。&nbsp; 例子：有个点在(1,1,1) 处，我的眼睛在(1,1,0)处，看着那个点。 那么这个时候，这个点就在我的正前方，它在我眼中的坐标就是(0,0,1)。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 透视变换： 一般情况下，我们看东西都有一种近大远小的感觉，那么这个变换，就是为了制造出这种效果。比如说，我眼睛看到了两个点 (-1,0,0) 和(1,0,0) ，假如我们把这两个点都垂直于我们拿远一点，那么他们的摄像机坐标本来是变成(-1,0,1) (1,0,1)，但是由于透视效果，近大远小，我们实际看到的坐标会变成(-a,0,1) (a,0,1)&nbsp;&nbsp;，这里 a &lt; 1。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 剪切： 这个也很好理解，我们看不到我们身后的东西，所以我们就不要去管它了，这样可以节省很多计算量，也可以使得计算的结果有一个确定的范围。实际的剪切变换中，还有近平面，远平面等参数，就是最近能看到多近，最远能看多远。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 行扫描输出： 我们现在已经得到了一堆坐标，表示我们看到的世界是什么样子，现在就是要把这个坐标转换成图片了，3D世界中的所有东西都是由三角形组成，所以我们把这些三角型的每一个点的坐标都计算出来（在之前的处理中始终只保留其顶点）。然后根据X,Y坐标画到屏幕上，画的过程中还要判断哪个点在前面，哪个点在后面，在后面的点不能遮住前面的点。这里使用的一个技术叫Z-Buffer，用来记录某个X,Y坐标上离屏幕最近的点的Z坐标值。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 大概就这么多先，发觉原来想把东西表达清楚还真不容易，代码过两天再贴，等把纹理和比较方便的世界模型定义脚本做好再说。而且，讲到具体的东西，需要比较透彻的线性代数理解，要表达好不容易，自己还要先理解理解。</font><br>
<img src ="http://www.cppblog.com/LSWinson/aggbug/76156.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LSWinson/" target="_blank">林森(L.S.Winson)</a> 2009-03-10 22:40 <a href="http://www.cppblog.com/LSWinson/archive/2009/03/10/76156.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>很随的随笔</title><link>http://www.cppblog.com/LSWinson/archive/2009/02/19/74269.html</link><dc:creator>林森(L.S.Winson)</dc:creator><author>林森(L.S.Winson)</author><pubDate>Thu, 19 Feb 2009 04:45:00 GMT</pubDate><guid>http://www.cppblog.com/LSWinson/archive/2009/02/19/74269.html</guid><wfw:comment>http://www.cppblog.com/LSWinson/comments/74269.html</wfw:comment><comments>http://www.cppblog.com/LSWinson/archive/2009/02/19/74269.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/LSWinson/comments/commentRss/74269.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LSWinson/services/trackbacks/74269.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;总的来说是比较欣赏 开发-测试-重构-测试-开发 这样的流程的，比较重要的一点是，这种模式才能在不熟悉的领域工作中得到有效的结果。感觉之前是被那种高屋建瓴的总体架构设计给搞蒙了，其实能做到这种程度架构的，功力必须超越当前的工作需要。 傻乎乎的作一个看似有效的高层架构设计，然后一头扎进底层开发，发现设计有问题，改，再做再改。 于是最终开发效率低，质量也并不高。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;作为刚起步的程序员，这两年是有点感觉了，好程序不是一开始就把所有东西做好，只是能推动它慢慢成长就行了。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有时候觉得，似乎是要像商人一样来作程序的决策，做这个功能有用吗？没用，那就不做了。以后可能有用？那以后能做吗，能，那就以后做吧。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;写C++写多了，就会喜欢造车轮，确实C++天生就是干这个的能手。不过像我这样的，车轮也不能乱造，虽然有些车轮造出来会感觉很爽，但是实际上没太大收益。
<img src ="http://www.cppblog.com/LSWinson/aggbug/74269.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LSWinson/" target="_blank">林森(L.S.Winson)</a> 2009-02-19 12:45 <a href="http://www.cppblog.com/LSWinson/archive/2009/02/19/74269.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开博宣言</title><link>http://www.cppblog.com/LSWinson/archive/2009/02/16/73930.html</link><dc:creator>林森(L.S.Winson)</dc:creator><author>林森(L.S.Winson)</author><pubDate>Mon, 16 Feb 2009 06:25:00 GMT</pubDate><guid>http://www.cppblog.com/LSWinson/archive/2009/02/16/73930.html</guid><wfw:comment>http://www.cppblog.com/LSWinson/comments/73930.html</wfw:comment><comments>http://www.cppblog.com/LSWinson/archive/2009/02/16/73930.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/LSWinson/comments/commentRss/73930.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/LSWinson/services/trackbacks/73930.html</trackback:ping><description><![CDATA[这是一篇比较形式化的开博文，没什么意义。<br>马上开始实习，需要一个地方来慢慢积累自己的想法。
<img src ="http://www.cppblog.com/LSWinson/aggbug/73930.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/LSWinson/" target="_blank">林森(L.S.Winson)</a> 2009-02-16 14:25 <a href="http://www.cppblog.com/LSWinson/archive/2009/02/16/73930.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>