⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tutorial_22.htm

📁 如果你相信它就好好学学吧,同样这里也只是个入门
💻 HTM
📖 第 1 页 / 共 5 页
字号:
        <li>使用漫射光颜色调制(相乘)片断颜色T0c</li>
        <li>混合1 颜色设置:</li>
        <li>(T0c * C0a + T0c * Fda - 0.5 )*2</li>
        <li>0.5 平衡损失的掐除值</li>
        <li>乘以2加亮图像颜色</li>
      </ul>
      结束理论讲解(凹凸映射)<font size="-1"><br>
      <br>
      </font>虽
然我们做了一些改动,使得这个程序的实现与TNT的实现不一样,但它能工作与各种不同的显卡上。在这里我们将学到两三件事,凹凸映射在大多数显卡上是一个
多通道算法(在TNT系列,可以使用一个2纹理通道实现),现在你应该能想到多重纹理的好处了吧。我们将使用一个三通道非多重纹理的算法实现,这个算法可
以被改写为使用一个2纹理通道实现的算法。 <p>现在必须告诉你,我们将要做一些矩阵和向量的乘法,但那没有什么可担心的,所有的矩阵和向量都使用齐次坐标。</p></td>
    <td background="Tutorial_22_files/r.png"><img src="Tutorial_22_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
	
<pre><font color="#ffffaa">// 计算向量v=v*M(左乘)</font>
void VMatMult(GLfloat *M, GLfloat *v) {
	GLfloat res[3];
	res[0]=M[ 0]*v[0]+M[ 1]*v[1]+M[ 2]*v[2]+M[ 3]*v[3];
	res[1]=M[ 4]*v[0]+M[ 5]*v[1]+M[ 6]*v[2]+M[ 7]*v[3];
	res[2]=M[ 8]*v[0]+M[ 9]*v[1]+M[10]*v[2]+M[11]*v[3];
	v[0]=res[0];
	v[1]=res[1];
	v[2]=res[2];
	v[3]=M[15];								
}
</pre>
</font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_22_files/l.png"><img src="Tutorial_22_files/l.png"></td>
    <td valign="top" width="100%"><p>开始理论讲解(凹凸映射)</p>
      <p>开始,让我们看看它的算法</p>
      <ol>
        <li>所有的向量必须在物体空间或则世界空间中</li>
        <li>计算向量v,由灯的位置减去当前顶点的位置</li>
        <li>归一化向量v</li>
        <li>把向量v投影到切空间中</li>
        <li>安向量v在切空间中的投影偏移纹理坐标</li>
      </ol>
      这看起来不错,它基本上和Michael I. Gold介绍的方法差不多。但它有一个缺点,它只对xy平面进行投影,这对我们的应用还是不够的。 <p>但
这个实现在计算漫射光的方法和我们是一样的,我们不能存储漫射因子,所以我们不能使用Michael I.
Gold介绍的方法,因为我们想让它在任何显卡上运行而不仅仅是TNT系列。为什么不光照计算留到最后呢?这在简单的几何体绘制上是可行的,如果你需要渲
染几千个具有凹凸贴图的三角形,你会感到绘制的速度不够快,到那时你需要改变这种渲染过程,寻找其它的方法。</p>
      <p>在我们的实现里,它看起来和上面的实现差不多,除了投影部分,我们将使用我们自己的近似。</p>
      <ul type="disc">
        <li>我们使用模型坐标,这种设定可以使得灯光位置相对于物体不变。</li>
        <li>我们计算当前的顶点坐标</li>
        <li>接着计算法线,并使它单位化</li>
        <li>创建一个正投影矩阵,把灯光方向变为切空间</li>
        <li>计算纹理坐标的偏移量,ds = s点乘v*MAX_EMBOSS, dt=t点乘v*MAX_EMBOSS</li>
        <li>在通道2中,把偏移量添加到纹理坐标</li>
      </ul>
      <b><u>为什么更好:</u></b> <ul type="disc">
        <li>更快</li>
        <li>看起来好看</li>
        <li>这个方法可以工作与各种表面</li>
        <li>可以运行于各种显卡</li>
        <li>最大化的兼容</li>
      </ul>
      <b><u>缺陷:</u></b> <ul type="disc">
        <li>并不是完全的物理模拟</li>
        <li>残留一些人为的假相</li>
      </ul>
      <font size="-1"><img src="Tutorial_22_files/image008.jpg" border="0" height="243" width="412"> 
      <br>
      <br>
      </font>这个示意图显示了我们坐标系统,你可以通过相减相邻的坐标来获得s,t向量,但必须保证他们构成右手系和归一化。<font size="-1"><br>
      <br>
      </font>结束理论讲解(凹凸映射)<font size="-1">&nbsp;<br>
      <br>
      </font>下面让我们看看如何生成偏移量,首先创建一个函数创建凹凸映射: 
      <p></p></td>
    <td background="Tutorial_22_files/r.png"><img src="Tutorial_22_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3"> 
</font><pre><font color="#aaffaa" size="3"><font color="#ffffaa">// 设置纹理偏移,都为单位长度</font>
<font color="#ffffaa">// n : 表面的法向量</font>
<font color="#ffffaa">// c : 当前的顶点纹理坐标,返回纹理坐标的偏移量</font>
<font color="#ffffaa">// l : 灯光的位置</font>
<font color="#ffffaa">// s : s方向</font>
<font color="#ffffaa">// t : t方向</font>
void SetUpBumps(GLfloat *n, GLfloat *c, GLfloat *l, GLfloat *s, GLfloat *t) {
	GLfloat v[3];								<font color="#ffffaa">// 灯光方向</font>
	GLfloat lenQ;								<font color="#ffffaa">// 灯光方向向量的长度,使用它来单位化</font>
	<font color="#ffffaa">// 计算灯光方向</font>
	v[0]=l[0]-c[0];
	v[1]=l[1]-c[1];
	v[2]=l[2]-c[2];
	lenQ=(GLfloat) sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
	v[0]/=lenQ;
	v[1]/=lenQ;
	v[2]/=lenQ;
	<font color="#ffffaa">// 把方向向量投影到s,t方向 </font>
	c[0]=(s[0]*v[0]+s[1]*v[1]+s[2]*v[2])*MAX_EMBOSS;
	c[1]=(t[0]*v[0]+t[1]*v[1]+t[2]*v[2])*MAX_EMBOSS;<br>}</font></pre>
 
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_22_files/l.png"><img src="Tutorial_22_files/l.png"></td>
    <td valign="top" width="100%">那看起来复杂么,但为了理解这个效果理论是必须的。(我在写这篇教程的时候也学习了它)。
      <p>我在程序运行的时候,总喜欢在屏幕上显示标志,现在我们有了两个,使用doLogo函数创建它。</p>
      <p>下面的函数显示两个标志:一个OpenGL的标志,一个多重纹理的标志,如果可以使用多重纹理,则标志使用alpha混合,并看起来半透明。为了让它在屏幕的边沿显示我们使用混合并禁用光照和深度测试。</p>
      <p></p>
      <p></p></td><td background="Tutorial_22_files/r.png"><img src="Tutorial_22_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3"> 
</font><pre><font color="#aaffaa" size="3">void doLogo(void) {
	<font color="#ffffaa">// 必须最后在调用这个函数,以公告板的形式显示两个标志</font>
	glDepthFunc(GL_ALWAYS);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_BLEND);
	glDisable(GL_LIGHTING);
	glLoadIdentity();
	glBindTexture(GL_TEXTURE_2D,glLogo);
	glBegin(GL_QUADS);
		glTexCoord2f(0.0f,0.0f);	glVertex3f(0.23f, -0.4f,-1.0f);
		glTexCoord2f(1.0f,0.0f);	glVertex3f(0.53f, -0.4f,-1.0f);
		glTexCoord2f(1.0f,1.0f);	glVertex3f(0.53f, -0.25f,-1.0f);
		glTexCoord2f(0.0f,1.0f);	glVertex3f(0.23f, -0.25f,-1.0f);
	glEnd();
	if (useMultitexture) {
		glBindTexture(GL_TEXTURE_2D,multiLogo);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0f,0.0f);	glVertex3f(-0.53f, -0.25f,-1.0f);
			glTexCoord2f(1.0f,0.0f);	glVertex3f(-0.33f, -0.25f,-1.0f);
			glTexCoord2f(1.0f,1.0f);	glVertex3f(-0.33f, -0.15f,-1.0f);
			glTexCoord2f(0.0f,1.0f);	glVertex3f(-0.53f, -0.15f,-1.0f);
		glEnd();
	}
	glDepthFunc(GL_LEQUAL);
}
</font></pre>

<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_22_files/l.png"><img src="Tutorial_22_files/l.png"></td>
    <td valign="top" width="100%">现在到了绘制凹凸贴图的函数了,我们先来看看不使用多重映射的方法,它通过三个通道实现。在第一步,我们先取得模型变换矩阵的逆矩阵!</td>
    <td background="Tutorial_22_files/r.png"><img src="Tutorial_22_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3"> 
<pre>bool doMesh1TexelUnits(void) {
	GLfloat c[4]={0.0f,0.0f,0.0f,1.0f};					<font color="#ffffaa">// 保存当前的顶点</font>
	GLfloat n[4]={0.0f,0.0f,0.0f,1.0f};					<font color="#ffffaa">// 保存法线</font>
	GLfloat s[4]={0.0f,0.0f,0.0f,1.0f};					<font color="#ffffaa">// s纹理坐标方向</font>
	GLfloat t[4]={0.0f,0.0f,0.0f,1.0f};					<font color="#ffffaa">// t</font><font color="#aaffaa" size="3"><font color="#ffffaa">纹理坐标方向</font></font>
	GLfloat l[4];							<font color="#ffffaa">// 保存灯光方向</font>
	GLfloat Minv[16];							<font color="#ffffaa">// 保存模型变换矩阵的逆</font>
	int i;

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			<font color="#ffffaa">// 清空背景颜色和深度缓存</font>

	<font color="#ffffaa">// 创建模型变换矩阵的逆</font>
	glLoadIdentity();
	glRotatef(-yrot,0.0f,1.0f,0.0f);
	glRotatef(-xrot,1.0f,0.0f,0.0f);
	glTranslatef(0.0f,0.0f,-z);
	glGetFloatv(GL_MODELVIEW_MATRIX,Minv);
	glLoadIdentity();
	glTranslatef(0.0f,0.0f,z);
	glRotatef(xrot,1.0f,0.0f,0.0f);
	glRotatef(yrot,0.0f,1.0f,0.0f);

	<font color="#ffffaa">// 设置灯光的位置</font>
	l[0]=LightPosition[0];
	l[1]=LightPosition[1];
	l[2]=LightPosition[2];
	l[3]=1.0f;								
	VMatMult(Minv,l);
</pre>
</font>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_22_files/l.png"><img src="Tutorial_22_files/l.png"></td>
    <td valign="top" width="100%"><u>通道1:</u> <ul type="disc">
        <li>使用凹凸纹理</li>
        <li>禁止混合</li>
        <li>禁止光照</li>
        <li>使用无偏移的纹理坐标</li>
        <li>绘制几何体</li>
      </ul>
      这将渲染一个无凹凸贴图的几何体</td>
    <td background="Tutorial_22_files/r.png"><img src="Tutorial_22_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3"><pre>	glBindTexture(GL_TEXTURE_2D, bump[filter]);
	glDisable(GL_BLEND);
	glDisable(GL_LIGHTING);
	doCube();
</pre></font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_22_files/l.png"><img src="Tutorial_22_files/l.png"></td>
    <td valign="top" width="100%"><u>通道2:</u> <ul type="disc">
        <li>使用反转的纹理凹凸贴图</li>
        <li>设置混合因子为1,1</li>
        <li>使用光照</li>
        <li>使用偏移纹理坐标</li>
        <li>绘制几何体</li>
      </ul>
      这将绘制一个具有凹凸贴图的几何体,但没有颜色&nbsp;<font size="-1">&nbsp;</font><font face="Tahoma,Verdana,sans-serif" size="-1"><br>
      <br>
      </font></td>
    <td background="Tutorial_22_files/r.png"><img src="Tutorial_22_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_22_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_22_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_22_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3">	glBindTexture(GL_TEXTURE_2D,invbump[filter]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -