orillusion入门系列七 | 媒体扩展
-
本节和 orillusion入门系列四 | 材质 一节息息相关,请先了解材质的思路和基础用法。通用的材质用法非常广泛,本节介绍的媒体扩展实际上是一些特殊的材质,只不过通过扩展包的方式提示,具有专有的比较单一的用途,在某一方面也可以非常强大和灵活。
环境准备
我们仅以 npm 包管理为例,回忆一下引擎的安装,是通过安装
@orillusion/core
包实现的,媒体扩展在@orillusion/media-extention
包中,因此安装媒体扩展,需要在安装了@orillusion/core
包的基础上再执行npm install @orillusion/media-extention --save
。图片材质
因此图片材质也是一种材质,回忆一下之前介绍的两种通用材质。图片材质与 UnLitMaterial 类似,都不对光照做出处理,但是图片材质提供了更多图片的裁剪、位移等功能。
基本用法
图片材质用法与通用材质类似,首先引入图片材质,然后在渲染组件中创建图片材质就可以了。
下面是关键代码:// 从扩展包中导入图片材质,在此之前请确认已经安装了拓展包 import { ImageMaterial } from "@orillusion/media-extention" ... // 创建渲染组件 let mr: MeshRenderer = obj.addComponent(MeshRenderer); // 设置形状 mr.geometry = new PlaneGeometry(10, 10); // 设置材质 mr.material = new ImageMaterial(); ...
为了和其它两种通用模型做个对比,同时创建了三种材质,并且没有加载图片资源,效果如下:
从左至右使用的材质分别是:LitMaterial、UnLitMaterial、ImageMaterial,可以看到后两种材质不受光照的影响。如果加载的图片纹理,并且打开了引擎自带的操控面板,显示效果如下:
可以看到加载图片资源后的效果,那么ImageMaterial提供了以下个性化的参数:- baseColor 基础颜色
- uv_offsetX x方向位移
- uv_offsetY y方向位移
- uv_scaleX x方向缩放
- uv_scaleY y方向缩放
- clip_left 左方裁剪
- clip_top 上方裁剪
- clip_right 右方裁剪
- clip_bottom 下方裁剪
完整的代码
下面是最简化的代码:
import { Engine3D, Scene3D, Object3D, Camera3D, HoverCameraController, MeshRenderer, LitMaterial, View3D, PlaneGeometry, UnLitMaterial} from "@orillusion/core"; import { ImageMaterial } from "@orillusion/media-extention" export default class Image { cameraObj: Object3D; camera: Camera3D; scene: Scene3D; async run() { await this.init(); await this.setup(); await this.start(); } /*** * 配置并初始化引擎 */ private async init() { // 初始化引擎 await Engine3D.init(); } /** * 引擎功能代码 */ private async setup() { // 创建一个场景 this.scene = new Scene3D(); // 创建一个相机 this.cameraObj = new Object3D(); this.camera = this.cameraObj.addComponent(Camera3D); // 设置相机类型 this.camera.perspective(60, window.innerWidth / window.innerHeight, 1, 5000.0); // 设置相机控制器 let controller = this.cameraObj.addComponent(HoverCameraController); controller.setCamera(0, -45, 25); // 添加相机至场景 this.scene.addChild(this.cameraObj); this.createSphere(); } /** * 启动渲染 */ private async start() { let view = new View3D(); // 指定渲染的场景 view.scene = this.scene; // 指定使用的相机 view.camera = this.camera; // 开始渲染 Engine3D.startRenderView(view); } /** * 创建对象 */ private async createSphere() { let texture = await Engine3D.res.loadTexture('/material_02.png'); { // 创建 LitMaterial let obj = new Object3D(); obj.x = -20; // 创建渲染组件 let mr: MeshRenderer = obj.addComponent(MeshRenderer); // 设置形状 mr.geometry = new PlaneGeometry(10, 10); // 设置材质 mr.material = new LitMaterial(); mr.material.baseMap = texture; // 添加到场景 this.scene.addChild(obj); } { // 创建 UnLitMatial let obj = new Object3D(); // 创建渲染组件 let mr: MeshRenderer = obj.addComponent(MeshRenderer); // 设置形状 mr.geometry = new PlaneGeometry(10, 10); // 设置材质 mr.material = new UnLitMaterial(); mr.material.baseMap = texture; // 添加到场景 this.scene.addChild(obj); } { // 创建 ImageMaterial let obj = new Object3D(); obj.x = 20; // 创建渲染组件 let mr: MeshRenderer = obj.addComponent(MeshRenderer); // 设置形状 mr.geometry = new PlaneGeometry(10, 10); // 设置材质 mr.material = new ImageMaterial(); mr.material.baseMap = texture; // 添加到场景 this.scene.addChild(obj); } } }
可以看到在一些以显示图片资源为主的应用场景中,推荐使用图片材质。
视频材质
视频材质的用法和图片类似,需要注意的是视频材质需要绑定视频纹理。
关键代码如下:import { VideoMaterial, VideoTexture } from "@orillusion/media-extention" ... // 创建 LitMaterial let obj = new Object3D(); // 创建渲染组件 let mr: MeshRenderer = obj.addComponent(MeshRenderer); // 设置形状 mr.geometry = new PlaneGeometry(10, 10); // 设置材质 let videoTexture = new VideoTexture(); await videoTexture.load('/bunny.mp4') // 创建视频材质 mr.material = new VideoMaterial(); mr.material.baseMap = videoTexture; // 添加到场景 scene.addChild(obj);
视频材质支持的功能参数与图片材质相同。
色键材质
色键材质是视频材质的高级形式,在输出视频内容时可以对视频进行一些修饰,除了具有视频材质的所有参数外,示加了背景关键色,羽化等参数。具体参数可以参考官方文档,使用色键材质可以定制出更高级的视频显示效果。
import { VideoMaterial, VideoTexture } from "@orillusion/media-extention" { // 创建 LitMaterial let obj = new Object3D(); // 创建渲染组件 let mr: MeshRenderer = obj.addComponent(MeshRenderer); // 设置形状 mr.geometry = new PlaneGeometry(10, 10); // 设置材质 let videoTexture = new VideoTexture(); await videoTexture.load('/bunny.mp4') // 创建视频材质 mr.material = new VideoMaterial(); mr.material.baseMap = videoTexture; // 添加到场景 this.scene.addChild(obj); }
综合示例
在多媒体实际应用中为了优化显示效果或提高性能,一般需要对UV变换进行处理和资源的利用。
uv变换
将图片或视频显示在一个物体上,资源与物体通常会有不同的宽高比例,同时物体也会有不同的缩放比例,如何使得资源显示保持原有宽高比例是常见的问题。
这里结合引擎的特点提供一个常用的函数:/** * * @param texture 资源纹理 * @param obj 目标对象 */ const computeResourceUV = (texture: Texutre, obj: Object3D) => { // 定义一个多媒体内容的二维向量 let content: Vector2 = new Vector2(texture.width, texture.height); // 获取对象的物理信息与缩放比例 let mesh: MeshRenderer = obj.getComponent(MeshRenderer); let bound = new Vector2(mesh.geometry.bounds.size.x * obj.scaleX, mesh.geometry.bounds.size.y * obj.scaleY); let uv: Vector4 = new Vector4(); let W = bound.x, H = bound.y, w = content.x, h = content.y; let R = W / H; let r = w / h; if (R >= r) { let scaleX = R / r; let offsetX = (scaleX - 1) / 2; uv.x = -offsetX; uv.z = scaleX; } else { let scaleY = r / R; let offsetY = (scaleY - 1) / 2; uv.y = -offsetY; uv.w = scaleY; } // 材质的uvTransform_1 变量与UV变换关连 mesh.material.uvTransform_1 = uv; }
在设置完材质与纹理的绑定后,调用以上函数输入原材质与目标对象即可计算出优化的显示效果,当动态的修改了对象的缩放比例,需要两次调用该函数优化。该方法仅是抛砖引玉,深度用户会有更优化的方案。
资源复用
多媒体资源对系统资源占用格外多,需要特别的注意优化,比例每种材质与纹理可以只加载一次,在材质或物体中可以利用。为了更好的利用,建议使用简单的缓存方式,类似如下方式:
// 定义缓存结构 const textureCache: { [key: string]: { texture: Texture } } = {} // 读取缓存 let texture: Texture; if (textureCache[name]) { texture = textureCache[name].texture; } // 更新缓存 if (!texture) { let textureUrl = mesh.material.baseMap.url; texture = await Engine3D.res.loadTexture(textureUrl); textureCache[name] = { texture: texture }; }
以上代码仅以纹理举例,材质的用法类似,只需要更新一下缓存结构,其它的部分基本没有变化。类似的优化技巧非常多,可以一起来挖掘。
小结
本节介绍了引擎扩展包中的几种媒体专用材质,为编制出丰富多彩的系统提供了支持。
作为3D新手,后续会不断的记录学习过程,期待与你一起学习一起飞!