0.1.0-alpha-6 • Published 6 years ago

@molay/magi v0.1.0-alpha-6

Weekly downloads
1
License
CC-BY-NC-ND-4.0
Repository
-
Last release
6 years ago

MAGI

基于 three.js 引擎的三维图形库,具备更高的绘制性能与呈现质量,以及对数据可视化的良好支持,并提供各式开箱即用的呈现组件。

主要特色:

  • 完全兼容 three.js 自有特性
  • 面向对象的 Pass 定义与渲染流程
  • 对 Unity / Unreal 的部分 Shader 和功能特性提供兼容支持
  • 具备完善的事件与交互系统
  • 提供各式高性能呈现组件

安装

yarn add @molay/magi

OR

npm install @molay/magi

使用参考

Magi3dEnv 通用三维集成环境

可按照如下方式直接使用。

import {Magi3dEnv} from '@molay/magi';
import {Mesh, SphereBufferGeometry, MeshBasicMaterial} from 'three';

// 初始化环境
const app = new Magi3dEnv({
  enableZoom: true,
});
document.body.appendChild(app.domElement);
app.startRender();

window.onresize = function () {
  app.resize(window.innerWidth, window.innerHeight);
};
window.onresize();

// 添加对象
const mesh = new Mesh(
  new SphereBufferGeometry(1),
  new MeshBasicMaterial({color: '#ff0000'})
);
app.scene.add(mesh);

或者采用继承的方式进行扩展。

import {Magi3dEnv} from '@molay/magi';
import {Mesh, SphereBufferGeometry, MeshBasicMaterial} from 'three';

class App01 extends Magi3dEnv {
  constructor(option) {
    super(option);
    
    this.initObjects();
  }
  
  initObjects() {
    const scene = this.scene;
    const mesh = new Mesh(
      new SphereBufferGeometry(1),
      new MeshBasicMaterial({color: '#ff0000'})
    );
    scene.add(mesh);
  }
}

// 初始化环境
const app = new App01({
  enableZoom: true,
});
document.body.appendChild(app.domElement);
app.startRender();

window.onresize = function () {
  app.resize(window.innerWidth, window.innerHeight);
};
window.onresize();

事件交互

MAGI 采用标准的事件交互系统,three.js 中的 Object3D 基于其自身 EventDispatcher 实现,MAGI 兼容此事件派发器实现, 同时 MAGI 也提供对 @molay/common 中的 EventDispatcher 的支持,后者具备更实用的功能,并可实现事件的冒泡和捕获流程。

import {Magi3dEnv} from '@molay/magi';
import {Mesh, SphereBufferGeometry, MeshBasicMaterial} from 'three';

class App01 extends Magi3dEnv {
  constructor(option) {
    super(option);
    
    this.initObjects();
  }
  
  initObjects() {
    const scene = this.scene;
    const mesh = new Mesh(
      new SphereBufferGeometry(1),
      new MeshBasicMaterial({color: '#ff0000'})
    );
    // 声明此对象具备事件交互能力
    mesh.pointerEvents = true;
    // 设置此对象的事件光标样式
    mesh.cursor = 'wait';
    mesh.addEventListener('click', function (event) {
      console.log('mesh clicked.', event);
    });
    mesh.addEventListener('mouseOut', function (event) {
      event.target.material.color = new Color('#ff0000');
    });
    mesh.addEventListener('mouseOut', function (event) {
      event.target.material.color = new Color('#ffff00');
    });
    scene.add(mesh);
  }
}

const app = new App01({});
document.body.appendChild(app.domElement);
app.startRender();

window.onresize = function () {
  app.resize(window.innerWidth, window.innerHeight);
};
window.onresize();

特殊 Shader 应用

MagiMaterial

MagiMaterial 是抽象的材质类型,可绑定一个 MagiShader。

一般地,建议为每种特效建立一种 MagiMaterial,并为其配置合适的 MagiShader,默认设置所用到的如 Texture 等数据。

MagiShader

MagiShader 由属性和一个或多个 MagiSubShader 组成。

属性一般为 Shader 所使用的 Uniforms 数据,会作用于该 MagiShader 下的全部 MagiSubShader。

每个 MagiSubShader 可对应一种设备和运行环境,MAGI 将自动选择与当前设备和运行环境相匹配的 MagiSubShader 应用在对象上。

一般情况下,大部分 MagiShader 只包含一个 MagiSubShader。

MagiSubShader

MagiSubShader 由属性和一个或多个 Pass 组成。

属性指示了该 SubShader 适用的设备和运行环境,执行的先后顺序与层级等信息。

每个 Pass 指示一种着色器,每个 Pass 将按顺序分别执行渲染。

一般情况下,大部分 MagiSubShader 只包含一个 Pass。

MagiPass

MagiSubShader 下的 Pass 可以是 three.js 的 ShaderMaterial / RawShaderMaterial,也可以是 MagiPass 的子类。

GrabPass

GrabPass 是特殊的 MagiPass 类型,其作用为截取当前屏幕内容并传递给后续 Pass ,以便实现特殊的图形效果。

示例

使用内置的反色 Shader 。

import {Magi3dEnv, MagiMaterial, InverseShader} from '@molay/magi';
import {Mesh, SphereBufferGeometry, MeshBasicMaterial} from 'three';

class App01 extends Magi3dEnv {
  constructor(option) {
    super(option);
    
    this.initObjects();
  }
  
  initObjects() {
    const scene = this.scene;
    const mesh01 = new Mesh(
      new SphereBufferGeometry(3),
      new MeshBasicMaterial({color: '#ff0000'})
    );
    mesh01.position.set(0, 0, -10);
    scene.add(mesh01);
    
    const mesh02 = new Mesh(
      new SphereBufferGeometry(3),
      new MagiMaterial({
        shader: new InverseShader()
      })
    );
    mesh02.position.set(0, 0, 10);
    scene.add(mesh02);
  }
}

// 初始化环境
const app = new App01({
  enableZoom: true,
});
document.body.appendChild(app.domElement);
app.startRender();

window.onresize = function () {
  app.resize(window.innerWidth, window.innerHeight);
};
window.onresize();

组件

粒子系统

MAGI 的粒子系统采用业界标准化的实现,可用于诸多粒子特效场合。

import {Magi3dEnv, ParticleSystem, ParticleSystemEnum, CurveUtil} from '@molay/magi';
import dot_image from './asset/image/dot.png';

class App01 extends Magi3dEnv {
  constructor(option) {
    super(option);
    
    this.initObjects();
  }
  
  initObjects() {
    const scene = this.scene;
    const texture = new TextureLoader().load(dot_image);
    const particleSystem = new ParticleSystem({
      // 粒子的贴图
      map: texture,
      // 粒子的存活时间,单位秒
      startLifetime: 3,
      // 粒子的运动速度
      startSpeed: 10,
      // 粒子开始的尺寸
      startSize: 2,
      // 重力速度
      gravityModifier: 1,
      // 坐标空间
      simulationSpace: ParticleSystemEnum.SIMULATION_SPACE_LOCAL,
      // 同时可呈现的最大粒子数
      maxParticles: 1000,
      // 发生器配置
      emission: {
        // 每秒生成多少粒子
        rateOverTime: 200,
        // 每单位距离生成多少粒子
        rateOverDistance: 0,
      },
      // 粒子生产空间配置
      shape: {
        radius: 0,
        radiusThickness: 0,
      },
      // 尺寸变化配置
      sizeOverLifetime: {
        // 变化曲线,使用三次贝塞尔曲线,可多曲线分段配置
        curve: CurveUtil.linear1to0
      },
      // 颜色变化配置
      colorOverLifetime: {
        colorStops: [
          {offset: 0, color: '#FF0000'},
          {offset: 1, color: '#FFFF00'},
        ],
        alphaStops: [
          {offset: 0, alpha: 1},
          {offset: 1, alpha: 1},
        ],
      },
    });
    scene.add(particleSystem);
  }
}

// 初始化环境
const app = new App01({
  enableZoom: true,
});
document.body.appendChild(app.domElement);
app.startRender();

window.onresize = function () {
  app.resize(window.innerWidth, window.innerHeight);
};
window.onresize();

Utils 工具方法集

GeometryUtil 几何体工具方法

合并 BufferGeometry ,source 的内容将被合并至 target

  • mergeBufferGeometry(target, source)
    • target
    • source

移动 BufferGeometry

  • moveBufferGeometry(geometry, offset)
    • geometry
    • offset

将 BufferGeometry 移至原点(中心点)

  • originBufferGeometry(geometry)
    • geometry