- 浏览: 312962 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
开发小菜:
支持IE9以下的吗?
HTML5+CSS3+JQuery打造自定义视频播放器 -
攻城使:
开发Html5必须得下载么,我用dw编写,把文件复制到myec ...
html5开发 myeclipse安装aptana插件 -
疾风鹰狼:
...
根据判断浏览器类型屏幕分辨率自动调用不同CSS的代码 -
sardodo:
你好,我想问下,导入例子中的.dae格式模型是可以看到旋转的小 ...
c3dl 初步认识 -
BIOHAZARDX:
下载学习,初学者膜拜一下。
html5 实现动画(三)
这一章讲纹理,纹理,不能顾名思义了,其实就是一张图片,我们要做的就是把这张图片贴到模型上面, 从而让模型一下子生动起来,说得有文采点就是栩栩如生,这个过程就叫纹理映射(也可以叫贴图)。纹理映射有时候能产生非常神奇的效果,比如说凹凸贴图,和 凹凸贴图衍生出来的法线贴图,能够让只有几百个几千个多边形的模型产生几万个,几十万个多边形的模型的效果。
接下来就要介绍怎么创建一个纹理采样器 (texture sampler) ,如何设置采样的属性,然后把一张图片(纹理)成功地 贴到那个立方体上面,图片的格式可以是 TGA , JPEG , PNG , DDS ,其中像 TGA,PNG 这样的格式是支 持半透明的,可以用来模拟阴影(当然只是简单地模拟)。
纹理采样器负责怎么把一张图片上的各个像素映射到模型的像素上,反过来说,就是为每个像素选取纹理像 素。看似很简单,但是当显示的图片大于(或小于)要覆盖的那个面时,就得就结了,这个不能一一映射了,那得怎么做呢,这是门学问,我们可以通过设置这个纹 理采样器的各个属性来达到较好的效果。
Address Mode
首先是 addressModeU 和 addressModeV 属 性,这两个属性决定了当纹理坐标超出( 0 , 1 ) 后该怎么做。纹理坐标,顾名思义,就是在纹理上的坐标,这是我们截取纹理中的一部分是要用到的。它的范围是( 0 , 1 )。 其中左下角的坐标是 (0.0 , 1.0) ,右 上角的坐标是 (1.0 , 1.0)
这两个属性有下面四种可能值
Value Meaning
WRAP ( 默认为此值)重复贴图来填充贴图区域
MIRROR 重复贴图,当遇到 UV 的边界时反向( UV 边界为 0.0 或者 1.0 )
CLAMP 用贴图的最后一行像素,重复覆盖没贴到的区域
BORDER 超过的贴图区 域,用一种特殊颜色的边标记出来
Minification Filter
Minification filter, 即 minFilter 这 个属性具体说明了怎么把纹理贴到一个像素比它少的模上面(这个上面有提到过),这个属性可能有下面 3 个值
Value Meaning
POINT 用最近的那个像素
LINEAR 线性插值
ANISOTROPIC 各向异性过滤
这三个滤镜效果是单调递增的,具体是怎么实现的,这里不多讲了 ( 其实也不会讲 - -) , 想了解的话可以去看图像处理方面的书籍。。。。
Mipmap Filter
由 于处理缩小纹理比处理放大纹理复杂多了,如果只是简单地取最近的那个像素,或者说只是和这个像素的周围几个像素简单的比较一下,获得平均值就插进去的话, 会严重降低图片缩小后的质量,而如果去周围大量的像素,做大量的计算又会严重降低程序效率。于是有才的人就想到了 mipmap 这个方法。它先将这张图片按原来尺寸一半一半地压缩,举个例子,原来的 是 64*64 的图片,就压缩成一张 32*32 的,一张 16*16 的,一张 8*8 的......当这张图片需要映射成 20*20 的大小的,就取 32*32 和 16*16 这两张图片来计算出 20*20 大小的图片,这比只是计算单张图片的效率和效果要好得多 .
下 面是这个参数可能的值
Value of mipFilter Which Mipmap Is Used
NONE 不用mipmap
POINT 取与需要映射的大 小最近的那张图片,然后依据上面的minification filter 进行过滤
LINEAR 取与需要映射的大 小最近的两张图片,为每张图片按照上面的miniFilter 进行过滤,然后把这两张图片一起进行 线性插值等到最终的图片
Magnification Filter
放 大纹理的处理就比较简单了,有下面两种可能的值。
Value Meaning
POINT Use the closest pixel.
LINEAR Perform a linear interpolation between neighboring pixels and use the result.
跟 minFilter 差不多。
Border Color
当 前面的 address mode 设成 border 时,这个属性就派上用场了,它可以用来设置那个边框的颜色。
Anisotropy
当 前面的 minFilter 是 Anisotropy 时,这个值就是决定了各向异性过滤的质量。
这 些属性介绍完了,下面就举个实例,把那张求是潮的 logo 贴到那个立方体上。
首 先要建立一个 texture sampler ,同 shape 和 material 一样,这也是一个 Object ,非常好地体现了"面向对象"的思想。
g_sampler = g_pack . createObject ( 'Sampler' );
g_sampler . minFilter = g_o3d . Sampler . ANISOTROPIC ;
g_sampler . maxAnisotropy = 4 ;
可以看到第一句就是建立 sampler 对象,后面两句就是设置上面提到的属性, minFilter 设为各向异性过滤, maxAnisotropy 设为 4 。
这样一个简单的 sampler 就建立了,但是比较打击人的是这个还只是设了下最基本的参数,这个参数设了给谁用呢,又是在哪里把 图片贴到那个模型上面去的呢
恩 ~ 在 o3d 里面纹理贴图就是在 pixel shader 里面用了一个函数 tex2D 把图片像素一个个根据上面设好的各 个参数填进已经经过 vertex shader 变换和 primitive assembly (就是 shape 一章里讲过的把各个顶点按照一定规则连接成图元的操作)了的东西里面。而传给 tex2D 的参数有两个,一个是一开始提到 的纹理坐标( texCoord ),还有一个就是采样器的各个参数了(这里面也包括了整个纹理素材),要把 js 中设的参数传到 shader 里面, o3d 中的做法是先在 shader 里面建一个变量,比如 texSampler0 ,然后在 js 中用 material 的 getParam 方法获取这个 texSampler0 变量,具体的如下:
effect . createUniformParameters ( material ); // 这句话是不可少的,否则就不能 获取shader 里面设的变量了
var samplerParam = material . getParam ( 'texSampler0' );
samplerParam . value = g_sampler ; // 把 g_sampler 的参数赋给 samplerParam
这里的 material 和 effect 就是前面几章为那个立方体建立的材质对象。所以可把上面几句代码加在原来的建立 material 和 effect 的代码的后面 ( 具体的 shader 代码在最后放出来 )
下面要做的是把纹理资源载入内存。
o3djs . io . loadTexture ( g_pack , textureUrl , function ( texture ) {
// set the texture on the sampler object to the newly created texture
// object returned by the request.
g_sampler . texture = texture ; // 可以看到这里把纹理资源也附到sampler 里 了以供shader 使用
})
其中 function(texuture) 。。。。。是回调函数,这里声明成匿名函数了( js 非常好用的一个特性),如果要处理的量比较大的话,可以独立 出来写成一个函数。也可以在其它纹理载入的时候使用。 textureURL 顾名思义就是图片地址了。
最后是声明各个顶点的纹理坐标,前面说到过要传给 shader 的,这个和声明顶点坐标差不多(顶点坐标数组也得相应的改过,不能几个面公用同一个顶点了,具体的建 sample 里的代码吧,再放出来就太长了 = = )
var texCoordsArray = [
0 , 0 ,
1 , 0 ,
1 , 1 ,
0 , 1 ,
0 , 0 ,
1 , 0 ,
1 , 1 ,
0 , 1 ,
1 , 1 ,
0 , 1 ,
0 , 0 ,
1 , 0 ,
0 , 0 ,
1 , 0 ,
1 , 1 ,
0 , 1 ,
0 , 0 ,
1 , 0 ,
1 , 1 ,
0 , 1 ,
0 , 0 ,
1 , 0 ,
1 , 1 ,
0 , 1
];
var texCoordsBuffer = g_pack . createObject ( 'VertexBuffer' );
var texCoordsField = texCoordsBuffer . createField ( 'FloatField' , 2 );
texCoordsBuffer . set ( texCoordsArray );
streamBank . setVertexStream (
g_o3d . Stream . TEXCOORD , // semantic
0 , // semantic index
texCoordsField , // field
0 ); // start_index
不多做解释了。
最后的最后:
Shader 代码
// World View Projection matrix that will transform the input vertices
// to screen space.
float4x4 worldViewProjection : WorldViewProjection;
// The texture sampler is used to access the texture bitmap in the fragment
// shader.
sampler texSampler0;
// input for our vertex shader
struct VertexShaderInput {
float4 position : POSITION;
float2 tex : TEXCOORD0; // Texture coordinates
};
// input for our pixel shader
struct PixelShaderInput {
float4 position : POSITION;
float2 tex : TEXCOORD0; // Texture coordinates
};
/**
* The vertex shader simply transforms the input vertices to screen space.
*/
PixelShaderInput vertexShaderFunction(VertexShaderInput input) {
PixelShaderInput output;
// Multiply the vertex positions by the worldViewProjection matrix to
// transform them to screen space.
output.position = mul(input.position, worldViewProjection);
output.tex = input.tex;
return output;
}
/**
* Given the texture coordinates, our pixel shader grabs the corresponding
* color from the texture.
*/
float4 pixelShaderFunction(PixelShaderInput input): COLOR {
return tex2D(texSampler0, input.tex);
}
// Here we tell our effect file *which* functions are
// our vertex and pixel shaders.
// #o3d VertexShaderEntryPoint vertexShaderFunction
// #o3d PixelShaderEntryPoint pixelShaderFunction
// #o3d MatrixLoadOrder RowMajor
Shader 的代码就不解释了,下一章会比较详细地讲下 shading language 和图形渲软管线到底是怎么样的,下下章可能会讲光照,光 照就是都在 shader 里面计算了,这个纯考数学物理知识啊,不过幸好已经有前人弄好的公式给我们套了。然后就是讲下阴影 (shadow) 的生成了,注意的是并不是有 光照就会自然而然地产生阴影了,阴影的处理是游戏中比较关键的,也是很占资源的一个地方。阴影处理的好的话游戏的真实性倍增啊啊。。。。
还有要说的就是 shapes 和这章的纹理映射以后不会这么详 细地用到,不会让你一个个顶点地去定义,更多的是载入一个用 3d 软件诸如 3DMAX 或 maya 做的模型,或者是用自带的函数简单地创个球,毕竟像这次这样创建一个带有贴图的立方体会让人崩溃的。
刚刚在整 sample 的时候发现纹理素材载入的时候总 是出现未知错误,折腾了半天都没找到原因,后来复制到别的地方发现又莫名其妙地可以用了,总算找到了原因:路径中不能有中文,哎,感叹一下,其实很多游戏 安装路径中也是不允许有中文的 = = 。
发表评论
-
bufferData
2011-07-21 14:30 1110/*void*/ bufferData //缓冲区数 ... -
导入支持的格式(Import)
2011-05-31 16:54 2483导入对话框选择格式,你会看到众多导入的格式。3ds m ... -
法线贴图
2011-05-13 11:48 1930本文转自:http://yumi08.jimdo.co ... -
法线向量
2011-05-13 10:20 2542面法线的计算相对来 ... -
ShowWebGL 强大的3D模型查看器
2011-04-12 14:01 6181ShowWebGL http://showwebgl.com ... -
o3d 创建一个平面
2011-03-29 15:27 894var vertexInfo = o3djs.primitiv ... -
o3d 常见几何图形创建
2011-03-29 15:25 11351、基本形状包括: o3djs.primitives.cre ... -
o3D 材质-定义透明材质
2011-03-29 15:20 1113//定义一个为白色并且是透明材质 var material = ... -
o3D 光照设定材质的光反射系数
2011-03-29 15:19 9971、创建材质 2、设定效果 3、创建光源的位置 4、设置材质环 ... -
O3D程序基本结构
2011-03-29 15:13 847创建一个O3D对象 设置全局变量初始化通用库 创建一个O3D ... -
Google 三维 JavaScript API
2011-03-28 15:59 911O3D 是一个开源的Web API,其可以创建相当牛X的基于浏 ... -
3D引擎CopperLicht(二)
2011-03-28 15:14 1444在上一个课程的基础上 ... -
3D引擎CopperLicht
2011-03-28 15:09 1746WebGL是一种3D绘图标准, ... -
o3d 文档原文
2011-03-18 18:00 887Basic TasksThe basic tasks perf ... -
WebGL的框架
2011-03-18 16:23 3941WebGL的框架 WebGL http://www.khro ... -
c3dl 官方教程(二)
2011-03-18 16:13 1907教程#2:一个简单的场景本教程将展示C3DL)的基础知识使用三 ... -
C3DL 官方教程(一)
2011-03-18 15:57 1574本文笔者翻译,如有错误请留言。 教程#1:Web ... -
3D模型导入 CanvasMatrix.js引擎 demo(一)
2011-03-17 17:51 3072为广大html5 3d开发的朋友们演示 代码贴图,请下载附 ... -
c3dl 可以直接导入3dmax文件的3D引擎
2011-03-17 17:41 1211c3dl可以直接在网页代码中使用.dae格式的3dma ... -
o3d 模型导入引擎CanvasMatrix.js
2011-03-17 16:09 1645最近研究3d引擎在html5中的效果实现,需求当然是 ...
相关推荐
3DS是一种广泛使用的三维建模软件3ds Max导出的文件格式,而O3DTGZ是O3D(Open 3D Engine)框架下的压缩文件格式,它包含了模型数据、纹理和其他相关资源,便于在O3D环境中高效加载和使用。 首先,我们需要了解3DS...
2. **丰富的图形功能**:支持多边形建模、光照、纹理映射、动画等复杂图形效果。 3. **交互性**:用户可以通过鼠标和键盘与三维场景进行交互,如旋转、平移、缩放视角。 4. **易于集成**:O3D 提供了一套 JavaScript...
UV坐标是纹理在3D模型上的映射,它们定义了每个顶点如何从2D纹理中采样颜色。通过动态改变这些坐标,可以创建出仿佛纹理在表面移动或扭曲的错觉。 实现纹理扭曲的基本步骤包括: 1. **创建材质**:首先,你需要...
在这个项目中,WebGL被用来绘制台球桌、台球以及游戏环境的其他元素,通过矩阵变换、纹理映射等技术实现逼真的视觉效果。开发者使用顶点着色器和片段着色器编写GLSL(OpenGL Shading Language)程序,来控制每个像素...
Open3D 还支持点云的滤波、变换、分割、纹理映射等多种操作。例如,可以使用 `radius_outlier_removal` 过滤掉离群点,`paint_uniform_color` 给点云上色,`translate` 和 `rotate` 进行位移和旋转操作,`extract_...
在本课件“计算机图形学computergraphics课件15.ppt”中,重点介绍了从顶点到片段的处理过程,包括投影、裁剪、着色、表面隐藏、纹理映射和透明度等关键概念。以下将对其中的裁剪算法和栅格化方法进行详细阐述。 ...
BP神经网络(Back Propagation Neural Network)是一种多层前馈神经网络,通过学习算法从输入输出数据中学习并建立一个输入和输出之间的非线性映射模型。该网络由输入层、隐藏层和输出层组成,通过输入数据前向传播...
它的核心特性在于提供了一整套工具集,涵盖了从场景建模、光照处理、纹理映射到物理模拟等多个方面,使得开发者能够构建出具有沉浸感的虚拟世界。作为一个开源项目,Open 3DGE的源代码对公众开放,允许用户自由地...
1. **计算机图形学基础**:包括顶点坐标系统、向量和矩阵运算、光照模型、纹理映射等。 2. **OpenGL或类似的图形库**:虽然MyGL是软件模拟,但了解硬件加速的OpenGL可以帮助理解渲染管线的基本工作原理。 3. **C++...