入门图形学:透明混合

        这一篇是为了继续深入之前透明原理而写,为了更好的理解图形学理论知识,如果不明白透明原理的同学务必返回图形学理论分类去找到透明原理这一篇博客看明白。

        以上是前提,那么接下来入正题,我们知道透明其实也就是颜色缓冲区中已存在的片段颜色值ColorFrame和需要覆盖的片段颜色值ColorGenerated进行“混合”计算得到新的片段颜色值ColorFinal,然后ColorFinal更新到颜色缓冲区渲染。那么这个“混合”计算的过程就很重要,unity cg runtime一直以来就为我们提供了很齐全的“混合”计算,同时也提供了详细的文档,如下:

        

          首先是blend操作所处的渲染流程具体位置。

          Blend SrcFactor DstFactor: Configure and enable blending. The generated color is multiplied by the SrcFactor. The color already on screen is multiplied by DstFactor and the two are added together.

          配置和启用blend,首先对ColorGenerated乘SrcFactor,然后对颜色缓冲区中已存在的片段ColorFrame乘DstFactor,然后两者相加。这里要解释一下,ColorGenerated也就是“透明片段颜色”,也就是要去主动混合颜色缓冲区中片段ColorFrame,通俗简单一点来说就是你的shader/material中采样的(纹理)颜色(带有Alpha通道)。

          

Blend factors

All following properties are valid for both SrcFactor & DstFactor in the Blend command. Source refers to the calculated color, Destination is the color already on the screen. The blend factors are ignored if BlendOp is using logical operations.

  
OneThe value of one - use this to let either the source or the destination color come through fully.
ZeroThe value zero - use this to remove either the source or the destination values.
SrcColorThe value of this stage is multiplied by the source color value.
SrcAlphaThe value of this stage is multiplied by the source alpha value.
DstColorThe value of this stage is multiplied by frame buffer source color value.
DstAlphaThe value of this stage is multiplied by frame buffer source alpha value.
OneMinusSrcColorThe value of this stage is multiplied by (1 - source color).
OneMinusSrcAlphaThe value of this stage is multiplied by (1 - source alpha).
OneMinusDstColorThe value of this stage is multiplied by (1 - destination color).
OneMinusDstAlphaThe value of this stage is multiplied by (1 - destination alpha).

 

       上面是一些混合参数,这些混合参数方便我们进行混合渲染,这很重要,下面我来写几个例子让大家好理解一下,如下:

       1. Blend SrcAlpha OneMinusSrcAlpha

       首先使用blend命令去实现混合

Shader "Custom/BlendShader"
{
    Properties
    {
        _MainColor ("Main Color", Color) = (1,1,1,1)
		_SrcAlpha("Src Alpha",Range(0,1)) = 0
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 100

        Pass
        {
			Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

			float4 _MainColor;
			float _SrcAlpha;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				fixed4 col = _MainColor;
				col.a = _SrcAlpha;
                return col;
            }
            ENDCG
        }
    }
}

    效果如下:

  

   可以很明显看得出来,首先红色背景为颜色缓冲区中已存在的颜色值ColorFrame,然后蓝色为所谓的“generated color”ColorGenerated,SrcAlpha从0->1那么OneMinusSrcAlpha英文意思就是1-SrcAlpha从1->0,所以最终的“混合”颜色ColorFinal:

   ColorFinal= ColorGenerated* SrcAlpha + ColorFrame* (1-SrcAlpha)

   脑海中仔细想一下就能得到效果:蓝色慢慢消失,红色慢慢显现。

   得到上面的效果后,为了验证,我特意使用了一个Opaque渲染类型的shader去手动计算“透明混合”,如下:

   

Shader "Custom/SimulateBlendShader"
{
	Properties
	{
		_BackColor("Back Color",Color) = (1,1,1,1)
		_MainColor("Main Color", Color) = (1,1,1,1)
		_SrcAlpha("Src Alpha",Range(0,1)) = 0
	}
	SubShader
	{
		Tags { "RenderType" = "Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
			};

			float4 _BackColor;
			float4 _MainColor;
			float _SrcAlpha;

			v2f vert(appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				fixed4 col = _SrcAlpha * _MainColor + _BackColor * (1 - _SrcAlpha);
				return col;
			}
			ENDCG
		}
	}
}

    效果如下:

  

    可以很明显看的出来验证正确。

    2.Blend SrcAlpha One

OneThe value of one - use this to let either the source or the destination color come through fully.

       官方意思就是DstFactor = 1,所以得到的“混合”效果如下:

       ColorFinal= ColorGenerated* SrcAlpha + ColorFrame* 1

Blend SrcAlpha One

       

    脑海中想象一下:当SrcAlpha从0到1插值,那么背景色红色(1,0,0,1)和前景色蓝色(0,0,1,1)混合色最终混合成粉色(1,0,1,1)

    为了节省篇幅,我不在贴全shader代码,只贴关键部分。

    接下来使用Opaque去手动计算混合,如下:

      

fixed4 frag(v2f i) : SV_Target
			{
				fixed4 col = _SrcAlpha * _MainColor + _BackColor * 1;
				return col;
			}

     

    也得到了验证。

    3.Blend DstColor SrcAlpha

     

DstColorThe value of this stage is multiplied by frame buffer source color value.

     请注意,这里开始就和上面不一样了,因为使用了Color这种float4值作为系数去计算的,那么这条blend命令实际的意义就是:

      ColorFinal = ColorGenerated * DstColor + ColorFrame * SrcAlpha

     我来解释一下,DstColor也就是帧颜色缓冲区中原始颜色(等价于ColorFrame),其作为系数去乘generated color,再加上颜色缓冲区ColorFrame乘SrcAlpha,得到最终颜色ColorFinal,效果如下:

    

Blend DstColor SrcAlpha

 

   顺便来解释一下,这种混合现象:

   ①.当SrcAlpha==0时(ColorFrame * SrcAlpha = (0,0,0,1)),将背景色(DstColor)从白色(1,1,1,1)插值到红色(1,0,0,1)或黑色(0,0,0,1),其前景色(ColorGenerated)蓝色(0,0,1,1)做乘法就会趋向于黑色(0,0,0,1)。

   ②.当背景色(DstColor)为红色(1,0,0,1)和前景色(ColorGenerated)为蓝色(0,0,1,1)时(ColorGenerated * DstColor = (0,0,0,1)),SrcAlpha从0插值到1,那么ColorFrame * SrcAlpha则从黑色(0,0,0,1)趋向于背景色(ColorA)红色(1,0,0,1)。

    接下来手动计算这种混合算法,如下:

    

fixed4 frag(v2f i) : SV_Target
			{
				fixed4 col = _MainColor * _BackColor + _BackColor * _SrcAlpha;
				return col;
			}

  

  注意:同学们脑海中仔细推算一下,务必要清楚明白。

 4.Blend SrcAlpha OneMinusDstAlpha

OneMinusDstAlphaThe value of this stage is multiplied by (1 - destination alpha).

       首先,我们可以很容易的将公式写出来:

       ColorFinal = ColorGenerated * SrcAlpha + ColorFrame * (1-DstAlpa)

      请注意,这也是一个典型的特例,DstAlpha意思就是帧颜色缓冲区中的Alpha值,那么也就意味着背景色(ColorFrame)是带有Transparent Alpha通道的,那么我首先要给背景板的shader改成支持透明通道,同时Blend Off关闭混合,为了测试我们的ColorGenerated混合效果,如下:

      

Shader "Custom/ColorAlphaShader"
{
    Properties
    {
        _MainColor ("Main Color", Color) = (1,1,1,1)
		_DstAlpha("Dst Alpha",Range(0,1)) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent"}
        LOD 100

        Pass
        {
		    Blend off
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

			float4 _MainColor;
			float _DstAlpha;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				fixed4 col = _MainColor;
				col.a = _DstAlpha;
                return col;
            }
            ENDCG
        }
    }
}

      接下来观察这种混合命令的效果,如下:

Blend SrcAlpha OneMinusDstAlpha

      

     我来解释一下这种现象的原因,如下:

     ①.当背景色(ColorFrame)的DstAlpha==1,前景色(ColorGenerated)的SrcAlpha==1,那么混合中ColorFrame * (1-DstAlpa)则为(0,0,0,0),则ColorFinal为前景色(ColorGenerated)蓝色(0,0,1,1)。

     ②.当背景色(ColorFrame)的DstAlpha从1插值到0,那么混合中ColorFrame * (1-DstAlpa)则为(0,0,0,0)到红色(1,0,0,1),则ColorFinal为慢慢变成粉红色(1,0,1,1)。

      还是要同学们仔细在脑海中演算琢磨。

    接下来就来模拟混合计算了,如下:

fixed4 frag(v2f i) : SV_Target
			{
				fixed4 col = _MainColor * _SrcAlpha + _BackColor * (1 - _DstAlpha);
				return col;
			}

     

     结果一致,很正常。

     好了,其他的我就不模拟了,上面只挑四个突出的典型混合讲解,看完理解完,我觉得同学们对于透明混合基本就摸透了。

     以上属于图形理论知识,我说过的,数学算法和原理理论是最重要的东西,请务必牢记。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 android,后起之秀  1.1 android简介  1.2 版本分裂  1.3 谷歌的角色  1.3.1 android开源项目  1.3.2 android market  1.3.3 挑战赛、设备播种计划和谷歌i/o  1.4 android的功能和体系结构  1.4.1 内核  1.4.2 运行库和dalvik虚拟机  1.4.3 系统库  1.4.4 应用程序框架  1.5 软件开发工具包  1.6 开发人员社区  1.7 设备,设备,设备  1.7.1 硬件  1.7.2 设备的范围  1.8 所有设备之间的兼容性  1.9 不同的手机游戏  1.9.1 人手一台游戏机  1.9.2 随时上网  1.9.3 普通用户与游戏迷  1.9.4 市场很大,开发人员很少  1.10 小结 第2章 从android sdk开始  2.1 搭建开发环境  2.1.1 安装jdk  2.1.2 安装android sdk  2.1.3 安装eclipse  2.1.4 安装adt eclipse插件  2.1.5 eclipse快速浏览  2.1.6 一些实用的eclipse快捷键  2.2 android环境下的hello world  2.2.1 创建项目  2.2.2 进一步分析项目  2.2.3 编写应用程序代码  2.3 运行和调试android应用程序  2.3.1 连接设备  2.3.2 创建一个android虚拟设备  2.3.3 运行应用程序  2.3.4 调试应用程序  2.3.5 logcat和ddms  2.3.6 使用adb  2.4 小结 第3章 游戏开发基础  3.1 游戏类型  3.1.1 休闲游戏  3.1.2 益智游戏  3.1.3 动作和街机游戏  3.1.4 塔防游戏  3.1.5 创新  3.2 游戏设计:笔比代码更强大  3.2.1 游戏的核心机制  3.2.2 一个故事和一种艺术风格  3.2.3 画面和切换  3.3 代码:具体细节  3.3.1 应用程序和窗口管理  3.3.2 输入  3.3.3 文件i/o  3.3.4 音频  3.3.5 图形  3.3.6 游戏框架  3.4 小结 第4章 面向游戏开发人员的android  4.1 定义一个android应用程序:清单文件  4.1.1 [manifest]元素  4.1.2 [application]元素  4.1.3 [activity]元素  4.1.4 [uses-permission]元素  4.1.5 [uses-feature]元素  4.1.6 [uses-sdk]元素  4.1.7 10个简单步骤建立android游戏项目  4.1.8 市场过滤器  4.1.9 定义游戏图标  4.2 android api基础  4.2.1 创建测试项目  4.2.2 活动的生命周期  4.2.3 处理输入设备  4.2.4 文件处理  4.2.5 音频编程  4.2.6 播放音效  4.2.7 音乐流  4.2.8 基本图形编程  4.3 最佳实践  4.4 小结 第5章 android游戏开发框架  5.1 制定计划  5.2 androidfileio类  5.3 androidaudio、androidsound和androidmusic  5.4 androidinput和accelerometer-handler  5.4.1 accelerometerhandler:手机哪一面朝上  5.4.2 compasshandler  5.4.3 pool类:重用相当有用  5.4.4 keyboardhandler  5.4.5 触摸处理程序  5.4.6 androidinput:优秀的协调者  5.5 androidgraphics和androidpixmap  5.5.1 处理不同屏幕大小和分辨率的问题  5.5.2 androidpixmap:人物的像素  5.5.3 androidgraphics:满足绘图需求  5.5.4 androidfastrenderview  5.6 androidgame:合并所有内容  5.7 小结 第6章 mr. nom入侵android  6.1 创建资源  6.2 建立项目  6.3 mrnomgame:主要活动  6.3.1 资源:便捷的资源存储  6.3.2 设置:跟踪用户的选项设置和高分榜  6.3.3 loadingscreen:从磁盘获取资源  6.4 主菜单画面  6.5 helpscreen类  6.6 高分榜画面显示  6.6.1 渲染数字  6.6.2 画面的实现  6.7 抽象  6.7.1 抽象mr. nom的世界:模型、视图、控制器  6.7.2 gamescreen类  6.8 小结 第7章 opengl es介绍  7.1 opengl es概述以及关注它的原因  7.1.1 编程模型:一个比喻  7.1.2 投影  7.1.3 规范化设备空间和视口  7.1.4 矩阵  7.1.5 渲染管道  7.2 开始之前  7.3 glsurfaceview:从2008年开始,事情变得简单了  7.4 glgame:实现游戏接口  7.5 绘制一个红色的三角形  7.5.1 定义视口  7.5.2 定义投影矩阵  7.5.3 指定三角形  7.5.4 综合示例  7.6 指定每个顶点的颜色  7.7 纹理映射:轻松地创建壁纸  7.7.1 纹理坐标  7.7.2 上传位图  7.7.3 纹理过滤  7.7.4 释放纹理  7.7.5 有用的代码片段  7.7.6 启用纹理  7.7.7 综合示例  7.7.8 texture类  7.8 索引顶点:重用是有好处的  7.8.1 代码整合  7.8.2 vertices类  7.9 半透明混合处理  7.10 更多图元:点、线、条和扇  7.11 2d变换:操作模型视图矩阵  7.11.1 世界空间和模型空间  7.11.2 再次讨论矩阵  7.11.3 第一个使用平移的示例  7.11.4 更多的变换  7.12 性能优化  7.12.1 测量帧率  7.12.2 android 1.5平台下hero的奇特案例  7.12.3 使opengl es渲染如此慢的原因  7.12.4 移除不必要的状态改变  7.12.5 减小纹理大小意味着需要获取更少的像素  7.12.6 减少opengl es/jni方法的调用  7.12.7 绑定顶点的概念  7.12.8 写在结束之前  7.13 小结 第8章 2d游戏编程技巧  8.1 写在开始  8.2 向量  8.2.1 使用向量  8.2.2 一点三角学的知识  8.2.3 实现一个向量类  8.2.4 一个简单的用法示例  8.3 2d物理定律浅析  8.3.1 牛顿和欧拉,永远的好朋友  8.3.2 力和质量  8.3.3 理论上的运动  8.3.4 运动的实现  8.4 2d碰撞检测和对象表示  8.4.1 边界形状  8.4.2 构造边界形状  8.4.3 游戏对象的属性  8.4.4 宽阶段和窄阶段碰撞检测  8.4.5 一个详细的示例  8.5 2d照相机  8.5.1 camera2d类  8.5.2 示例  8.6 纹理图集  8.7 纹理区域、精灵和批处理:隐藏opengl es  8.7.1 textureregion类  8.7.2 spritebatcher类  8.8 精灵动画  8.8.1 animation类  8.8.2 示例  8.9 小结 第9章 super jumper:一个2dopengl es游戏  9.1 核心游戏机制  9.2 背景故事和艺术风格  9.3 画面和切换  9.4 定义游戏世界  9.5 创建资源  9.5.1 ui元素  9.5.2 使用点阵字体处理文本  9.5.3 游戏元素  9.5.4 用于救援的纹理图集  9.5.5 音乐与音效  9.6 实现super jumper  9.6.1 assets类  9.6.2 settings类  9.6.3 主活动  9.6.4 font类  9.6.5 glscreen  9.6.6 主菜单画面  9.6.7 帮助画面  9.6.8 高分画面  9.6.9 模拟类  9.6.10 游戏画面  9.6.11 worldrenderer类  9.7 是否需要优化  9.8 小结 第10章 opengl es:进入3d世界  10.1 准备工作  10.2 3d中的顶点  10.2.1 vertices3:存储3d空间位置  10.2.2 示例  10.3 透视投影:越近则越大  10.4 z-buffer:化混乱为有序  10.4.1 完善上一个例子  10.4.2 混合:身后空无一物  10.4.3 z-buffer精度与z-fighting  10.5 定义3d网格  10.5.1 立方体:3d中的“helloworld”  10.5.2 一个示例  10.6 矩阵和变换  10.6.1 矩阵堆栈  10.6.2 用矩阵堆栈实现分层系统  10.6.3 木箱太阳系的简单实例  10.7 小结 第11章 3d编程技巧  11.1 准备工作  11.2 3d中的向量  11.3 opengl es中的光照  11.3.1 光照的工作机制  11.3.2 光源  11.3.3 材质  11.3.4 opengl es中如何对光照过程进行运算:顶点法线  11.3.5 实践  11.3.6 关于opengl es中光照应用的一些建议  11.4 材质变换(mipmapping)  11.5 简单的照相机  11.5.1 第一人称照相机或欧拉照相机  11.5.2 一个欧拉照相机的示例  11.5.3 跟随照相机  11.6 加载模块  11.6.1 wavefront obj格式  11.6.2 obj加载器的实现  11.6.3 使用obj加载器  11.6.4 关于加载模型的一些建议  11.7 3d中的一些物理知识  11.8 碰撞检测与3d中的对象表达法  11.8.1 3d中的边界形状  11.8.2 边界球重叠测试  11.8.3 gameobject3d与dynamic-gameobject3d  11.9 小结 第12章 droid invaders游戏  12.1 游戏的核心机制  12.2 游戏的故事背景与艺术风格  12.3 屏幕与场景切换  12.4 定义游戏世界  12.5 创建资源  12.5.1 用户界面的资源  12.5.2 游戏资源  12.5.3 音效与音乐  12.6 开始编写代码  12.7 assets类  12.8 settings类  12.9 主活动  12.10 主菜单  12.11 游戏设置画面  12.12 模拟类  12.12.1 shield类  12.12.2 shot类  12.12.3 ship类  12.12.4 invader类  12.12.5 world类  12.13 gamescreen类  12.14 worldrender类  12.15 游戏优化  12.16 小结 第13章 发布游戏  13.1 关于测试  13.2 成为注册开发人员  13.3 给游戏的apk包签名  13.4 将游戏发布至market  13.4.1 上传资源  13.4.2 产品详情  13.4.3 发布选项  13.4.4 发布  13.4.5 市场推广  13.5 开发人员控制台  13.6 小结 第14章 进阶内容  14.1 社交网络  14.2 位置识别  14.3 多玩家功能  14.4 opengl es 2.0以及更多内容  14.5 框架及引擎  14.6 网络资源  14.7 结束语
创建一个OpenGL窗口: 在这个教程里,我将教你在Windows环境中创建OpenGL程序.它将显示一个空的OpenGL窗口,可以在窗口和全屏模式下切换,按ESC退出.它是我们以后应用程序的框架. 理解OpenGL如何工作非常重要,你可以在教程的末尾下载源程序,但我强烈建议你至少读一遍教程,然后再开始编程. 2.你的第一个多边形: 在第一个教程的基础上,我们添加了一个三角形和一个四边形。也许你认为这很简单,但你已经迈出了一大步,要知道任何在OpenGL中绘制的模型都会被分解为这两种简单的图形。 读完了这一课,你会学到如何在空间放置模型,并且会知道深度缓存的概念。 3.添加颜色: 作为第二课的扩展,我将叫你如何使用颜色。你将理解两种着色模式,在左图中,三角形用的是光滑着色,四边形用的是平面着色。 注意三角形上的颜色是如何混合的。 颜色为OpenGlL 工程增加很多。通过理解平面着色(flat coloring)和平滑着色(smooth coloring),你能显著的改善你的OpenGL Demo的样子。 4.旋转: 在这一课里,我将教会你如何旋转三角形和四边形。左图中的三角形沿Y轴旋转,四边形沿着X 轴旋转。 这一章将引入两个变量, rtri 被用来存储三角形的角度, rquad存储四边形的角度。 和容易创建一个多边形组成的场景。让这些物体动起来是整个场景变得生动起来。在后面的课程钟我将教给你如何绕屏幕上的一个点旋转物体,使得物体绕屏幕而不是它的轴转动。 5.3D形体: 既然我们已经领会到多边形,方形,色彩和旋转。现在该建立3D物体了。我将使用多边形和矩形c创建3D物体。这次我们将扩展上一章的教程,并且将三角形转换成一个彩色的棱锥,把正方形变为一个实心正方体。棱锥使用混合色,正方体每个面使用一种颜色。在3D空间创建物体可能很费时间,但是所获得的结果(收获)值得这样做。充分发挥你的想象力吧。 6.纹理映射: 你想要它,它现在就在这里了,那就是 ... 纹理映射!!!在这一章我将教会你如何将一幅位图(bitmap)映射到正方体的六个面上去。我们将使用第一章的OpenGL代码来创建工程。创建一个空的窗口比修改上一课的代码更容易。 你将会发现第一章的代码在对于快速创建工程来说是及其有价值的。第一章的代码为你设置好了一切,你所需要做的只是集中精力为效果编程。 7.纹理滤波, 光照和键盘控制: 好的,我希望到现在你已经理解了所有的东西,因为这是一个巨大的教程。我想教给你两个新的方法来过滤(filter)你的纹理,简单的光照,键盘控制并且还可能更多 :) .如果你对到这一课为止你所学的东西并不充满信心,那就回头复习一下。玩一下其它课程的代码,不要操之过急。最好专心把每一课学好,而不是蜻蜓点水,只知道如何把东西做出来。 8.混合 有理由等一下,一个来自很酷的Hypercosm的程序员伙伴问(我)他是否可以写一章关于混合的教程。第八课通常正是讲混合的,所以太巧了。这一章教程扩展了第七章。混合是一项很酷的技术 .. 我希望你们能好好享受这一章教程。这一章的作者是Tom Stanis他在这制作一章上花费了很多精力,所以让他知道你觉得怎么样。混合可不是一个好讲的话题。 9.在3D空间中移动位图: 这一章覆盖了一些你们要求的主题,你想知道如何移动你在3D屏幕空间上创造的物体。你想要知道如何在屏幕上绘制一幅位图,并且位图的黑色部分不会覆盖它后面的东西。你想要简单的动画,想要更多的混合的应用,这一章将教会你所有这些。You'll notice there's no spinning boxes(yaker:很惭愧这一句我不是很明白)。前面的课程覆盖了OpenGL的基础,每一章都基于前面的内容。前面的课程涵盖了基础的OpenGL,每一课都是在前一课的基础上创建的。这一课是前面几课知识的综合,当你学习这课时,请确保你已经掌握了前面几课的知识。 10.加载3D世界,并在其中漫游: 你一直期待的教程来了!这一章友一个叫Lionel Brites的伙伴制作。这一课里你讲学到如何导入一个3D世界。代码仍然使用第一章的,但是,课程页面只是解释了新的部分,包括导入3D场景,在3D世界中移动。下载VC++代码并且在你阅读教程的同时阅读代码。按[B]键控制混合,[F]键控制滤波,[L]键控制光照(但光并不随场景移动),还有[Page UP]和[Page Down]键。我希望你能喜欢Lionel对网站的贡献。我有空的时候我会让这个教程更容易学习。 11.旗帜效果

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值