自定义几何体
Tinoe 内置的几种常用几何体不满足需求时,用户还可以使用 BufferGeometry
创建自己定义的几何体,绘制出任意形状的几何体。
示例
使用
创建
const myGeom = new BufferGeometry();
上传数据
通过调用 .setAttribute(key: string, bufferData: BufferData)
,可以向新建的 BufferGeometry
实例中保存顶点属性数据。
// 上传顶点的位置数据
myGeom.setAttribute('position', {
data: positionData, // 数据
type: ComponentType.FLOAT, // 类型
itemSize: 3, // 每项大小
isPosition: true, // 是否是位置数据
bindingIdx: 1, // 属性数据所属的分组
bufferUsage: BufferUsage.Dynamic, // 动态数据,提醒底层该数据会动态更新,以优化使用
});
第一个参数接收一个字符串,作为顶点属性的名称,它需要严格与 Shader 中的属性名保持一致。
第二个参数接收一个BufferData
类型的对象,该类型具体定义如下:
type BufferData = {
data?: TypedArray; // 数据源
type?: ComponentType; // 数据类型
itemSize?: number; // 每项数据大小
isIndex?: boolean; // 是否是索引属性数据,与isPosition只能有一个为true
isPosition?: boolean; // 是否是位置属性,与isIndex只能有一个为true
stride?: number; // 步长
bindingIdx?: number; // 所属的属性组,同一组的属性数据会被合并上传,以优化性能
bufferUsage?: BufferUsage; // 使用方式,用以优化底层实现
/** 仅供实例属性数据使用 **/
instanceCount?: number; // 实例个数
divisor?: number; // 前进数
};
对于ComponentType
、BufferUsage
等类型的定义,请参考API 文档。
宏开关
通过调用 .setMacro(key: string, enable: boolean)
,打开或关闭宏key
。
myGeom.setMacro('u_hasNormal', true); // 开启`u_hasNormal`的宏定义
包围盒
几何体的包围盒是射线拾取、视锥体裁剪优化的必需。有两种方法设置几何体的包围盒。
.setBBox(min: Vector3, max: Vector3)
直接更新包围盒。
const min = new Vector3(-1, -1, -1);
const max = new Vector3(1, 1, 1);
myGeom.setBBox(min, max);
.resetBBox(positionKey: string)
,根据位置属性数据自动计算包围盒,需要提供位置属性名称。
myGeom.resetBBox('position');
API
BufferGeometryQ&A
为什么上传索引数据,绘制失败?
- 若控制台出现
[.WebGL-0x480a60f800] GL_INVALID_ENUM: Enum is not currently supported.
报错,请检测索引数据data
的 TypeArray 类型是否为Uint32Array
- 若控制台出现
为什么属性数据不生效?
- 请务必确保属性
key
与 Shader 中的 attribute 名称严格一致。 - 请务必确保宏
key
与 Shader 中的 宏 名称严格一致。 - 位置属性需要拥有独立的
bindingIdx
,不与其他属性共享。
- 请务必确保属性
如果想搭配 Tinoe 内置材质使用,那属性取值就要和 Tinoe 内置的属性名相同,如下表。
内置属性名 解释 a_position 顶点位置 a_texcoord 纹理坐标 a_normal 法线 a_tangent 切线 a_color 颜色 同样,宏取值也要和 Tinoe 内置的宏名称严格一致,如下表。
内置属性名 解释 u_hasNormal 存在法线属性,配合 a_normal 属性使用 u_hasTangent 存在切线属性,配合 a_tangent 属性使用 u_hasVertexColor 存在顶点颜色,配合 a_color 属性使用 u_hasVertexAlpha 存在顶点颜色透明度,配合 a_color 属性使用 u_hasUV 存在纹理坐标,配合 a_texcoord 属性使用 u_enableInstance 启动实例化渲染