Monthly Archives: January 2014

模板缓冲区

本文主要介绍模板缓冲区的用途,基本用法,主要的操作函数和模板缓冲区在倒影渲染中的应用。 示例代码下载地址:https://github.com/twinklingstar20/twinklingstar_cn_demo_stencil_buffer/ 一. 介绍 所谓的模板缓冲区是做什么用的,举个简单的例子来说明,如图1所示。屏幕上画一个平面,把这个平面写入到模板缓冲区中,再画小球的时候,进行模板测试,小球在平面范围内的内容会显示出来,不在平面范围内的就不显示。假设,把图1中画的平面,看成一扇窗户,而小球看成窗户外面的风景,那么只有在窗户范围内的风景才会显示出来。所谓的模板缓冲区,基本就干这么一件事儿,它在倒影(Reflection)和阴影(Shadow)效果处理上,都起到非常重要的作用。 图1. (1)画一个平面和一个球;(2)启用模板测试,小球不在平面范围内的内容不显示;(3)关闭模板测试,小球在与不在平面范围内,都将内容显示出来 只有存在模板缓冲区的情况下,才会进行模板测试,即将存储在模板缓冲区中的值与参考值进行对比,通过测试的像素才可能在屏幕上显示,而且依赖测试的结果,可能对模板缓冲区中的值进行修改。 OpenGL和DirectX都支持模板缓冲区,每个像素占的位数通常是1、4、8等。渲染过程中,对片断(Fragment)的处理,包括裁剪测试、透明度测试、模板测试、深度测试等等,它们的顺序如图2所示,模板测试发生在深度测试之间。 图2. 每个片断的处理管线 二. OpenGL中与模板缓冲区相关的操作 OpenGL中与模板缓冲区相关的操作,主要有下面几种。 glEnable/glDisable(GL_STENCIL_TEST); glClearStencil(0); glClear(… | GL_STENCIL_BUFFER_BIT); glStencilFunc(function, ref, mask); glStencilOp(stencil_fail, depth_fail, depth_pass); glStencilMask(mask); 默认情况下,模板测试是关闭的,需要调用glEnable()开启模板测试,不用时调用glDisable关系模板测试。 glClearStencil()和glClear()用于清除模板缓冲区。 glStencilFunc设置模板测试比较的条件、参考值和掩码,function可以取的值和意义如下表所示: glStencilOp()用于更新模板缓冲区的操作,模板缓冲区的更新与模板测试的结果和深度测试的结果都有关系,该函数有3个参数,它们的意思分别表示: (1) stencil_fail,规定模板测试失败时进行的操作,默认值是GL_KEEP; (2) depth_fail,规定模板测试通过,但是深度测试失败时的操作,默认值是GL_KEEP; (3) depth_pass,规定了下面有两种情况的操作,默认值是GL_KEEP: i. 模板测试和深度测试都通过 ii.  模板测试通过但是不存在深度缓冲区或者未开启深度测试 glStencilOp()中3个参数可取值和它们对应的意义如下表所示: 三. 倒影

spacer

How AGP Work(转载)

本文转载于http://computer.howstuffworks.com/agp.htm,对AGP进行了介绍。在图形渲染中主要有三种内存:系统内存(System Memory),显存(Video Memory)和AGP内存(AGP Memory)。系统内存和显存都容易理解,不过AGP内存是什么呢?简单来说,就是把RAM中划出一小块内存,当作显存来用,在“AGP Memory Improvements”小节,有详细的介绍。 Introduction You point, you click; you drag and you drop. Files open and close in separate windows. Movies play, pop-ups pop, and video games fill the screen, immersing you in a world of 3-D

spacer

欧拉角、四元数和矩阵的对比

三维空间的旋转可以用欧拉角,旋转矩阵,轴-角,四元数,双四元数来表示,本文主要总结这些表示方法的优缺点。 一.  欧拉角(Euler-Angles) 1.1    介绍 欧拉角包括3个旋转,根据这3个旋转来指定一个刚体的朝向。这3个旋转分别绕x轴,y轴和z轴,分别称为Pitch,Yaw和Roll,如下图所示。欧拉角可以表示成z-x-z,x-y-x,z-y-z等形式,旋转的顺序影响结果。 Pitch Yaw Roll 图1. 欧拉角的表示 欧拉角很重要的一个优点就是直观,容易理解。 欧拉角主要有下面几个缺点: (1)       欧拉角是不可传递的,旋转的顺序影响旋转的结果,不同的应用又可能使用不同的旋转顺序,旋转顺序无法统一; (2)       3个旋转的角度可以不受限制,即可以是10000度,也可以是-1500度; (3)       可能造成万向节死锁(Gimbal Lock)。 1.2 平万向节死锁 当两个环发生重叠的时候,就有丢失了一个自由度,如图2所示。对万向节死锁可以参考【1】【2】【3】,特别是【1】提供的视频,对知识点的介绍非常的形象生动。也正是由于锁的存在,无法使用欧拉角实现球面平滑的插值。 图2. 万向节死锁 二. 旋转矩阵 用3*3的矩阵,可以表示三维空间中所有的旋转,设\(\theta \)表示沿着轴的方向望去时,方向是顺时针的旋转角度。则绕着X轴、Y轴、Z轴旋转\(\theta \)角,对应的旋转矩阵表示如下所示: \(X = \left( {\begin{array}{*{20}{c}}1&0&0\\0&{\cos \theta }&{ - \sin \theta }\\0&{\sin \theta }&{\cos

spacer

任意点与平面的反射矩阵

  问题描述:设三维空间上,存在一个点\(V=\left( x,y,z \right)\),一个平面\(\Gamma :P\cdot \vec{n}+d=0\),求点\(V\)经过平面\(\Gamma \)的投影点\(V'\),其中,\(V'=\left( x',y',z' \right)\),\(\vec{n}=\left( {{n}_{x}},{{n}_{y}},{{n}_{z}} \right)\),如图1所示。 图1. 点\(V'\)是点\(V\)经过平面\(\Gamma \)的投影点 设\(l\)表示点\(V\)到平面\(\Gamma \)的有向距离,则有: \(l=\frac{V\cdot \vec{n}+d}{\left\| {\vec{n}} \right\|} \tag{1}\) 由于点\(V\)和点\(V'\)到平面\(\Gamma \)的距离大小相等,且\(\overline{VV'}\)垂直于平面\(\Gamma \),则有: \(V-V'=2l\cdot \frac{{\vec{n}}}{\left\| {\vec{n}} \right\|} \tag{2}\) 把(1)代入(2)式中,得到: \(V'=V-\frac{2\vec{n}\left( V\cdot \vec{n}+d \right)}{{{\left\| {\vec{n}} \right\|}^{2}}}=V-\frac{2\left( V\cdot \vec{n} \right)\vec{n}}{{{\left\| {\vec{n}}

spacer