GEngine
Rendering engine based on webgpu
Install / Use
/learn @GEngine-js/GEngineREADME
GEngine.js
WebGPU Engine
install
$ yarn add @gengine-js/gengine
develop
# install
$ yarn
# dev
$ yarn dev
# build
$ yarn build
Usage
<script type="module">
import {
Mesh,
PerspectiveCamera,
Scene,
PhongMaterial,
Vector3,
Color,
SpotLight,
PointLight,
SphereGeometry,
OrbitControl
} from "../dist/index.js";
const init = async () => {
const geometry = new SphereGeometry(10);
const phongMaterial = new PhongMaterial();
phongMaterial.color = new Color(1.0, 0.0, 0.0);
const primitive = new Mesh(geometry, phongMaterial);
primitive.rotateX(-Math.PI / 2);
const camera = new PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.set(0, 20, 0);
camera.lookAt(0, 0, 0);
const spotLight = new SpotLight(new Vector3(1.0, 1.0, 1.0), 1.0, 15, 6, 1);
spotLight.position = new Vector3(0, 20, 0);
const scene = new Scene({ container: "app" });
axes.scale.set(10, 10, 10);
const control = new OrbitControl(camera, document.getElementById("app"));
scene.add(primitive);
scene.setCamera(camera);
scene.add(pointLight);
window.addEventListener("resize", onWindowResize);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
scene.resize(window.innerWidth, window.innerHeight);
}
function animate() {
control.update();
requestAnimationFrame(animate);
scene.render();
}
animate();
};
init();
</script>
Native
<script type="module">
import { Model, Context, Texture, RenderTarget, Attachment } from "webgpu-gengine-js";
import { mat4, vec3 } from "gl-matrix";
const init = async () => {
//init context
const context = new Context({
canvas: null,
container: document.getElementById("app"),
pixelRatio: 1
});
const { canvas, presentationFormat } = context;
await context.init();
const { width, height, depth } = context.presentationSize;
const colorAttachment = new Attachment(
{ r: 0.0, g: 0.0, b: 0.0, a: 0 },
{
textureView: () => {
return context.context.getCurrentTexture().createView();
}
}
);
const depthTexture = new Texture({
label: "resolveDepth",
size: { width, height, depth },
format: "depth24plus",
usage: GPUTextureUsage.RENDER_ATTACHMENT
});
const depthAttachment = new Attachment(1.0, { texture: depthTexture });
//fbo
const canvasRenderTarget = new RenderTarget("render", [colorAttachment], depthAttachment);
const aspect = canvas.width / canvas.height;
const projectionMatrix = mat4.perspective([], (2 * Math.PI) / 5, aspect, 1, 100.0);
const modelViewProjectionMatrix = mat4.create();
const model = new Model({
shaderId: "model",
frag: `
@fragment
fn main(@location(0) fragPosition: vec4<f32>) -> @location(0) vec4<f32> {
return fragPosition;
}
`,
vert: `
struct Uniforms {
modelViewProjectionMatrix : mat4x4<f32>,
}
@binding(0) @group(0) var<uniform> uniforms : Uniforms;
struct VertexOutput {
@builtin(position) Position : vec4<f32>,
@location(0) fragPosition: vec4<f32>,
}
@vertex
fn main(@location(0) position : vec4<f32>,@location(1) color : vec4<f32>) -> VertexOutput {
var output : VertexOutput;
output.Position = uniforms.modelViewProjectionMatrix * position;
output.fragPosition = 0.5 * (position + vec4(1.0, 1.0, 1.0, 1.0));
return output;
}
`,
vertexBuffers: [
{
stepMode: "vertex", //optional
uid: "vertAttr", //must
attributes: {
position: { size: 4, value: positions },
color: { size: 4, value: colors }
}
}
],
uniformBuffers: [
{
type: "uniform",
uid: "systemMatrix",
uniforms: {
modelViewProjectionMatrix: {
type: "mat4",
value: () => {
let viewMatrix = mat4.identity([]);
mat4.translate(viewMatrix, viewMatrix, vec3.fromValues(0, 0, -4));
const now = Date.now() / 1000;
mat4.rotate(
viewMatrix,
viewMatrix,
1,
vec3.fromValues(Math.sin(now), Math.cos(now), 0)
);
mat4.multiply(modelViewProjectionMatrix, projectionMatrix, viewMatrix);
return modelViewProjectionMatrix;
}
}
}
}
],
renderState: {
targets: [
{
format: presentationFormat
}
],
primitive: {
topology: "triangle-list",
cullMode: "back"
},
depthStencil: {
depthWriteEnabled: true,
depthCompare: "less",
format: "depth24plus"
}
},
draw: {
count: 36,
instanceCount: 1
}
});
function animate() {
requestAnimationFrame(animate);
const passEncoder = canvasRenderTarget.beginRenderPass(context.device);
model.render({ device: context.device, passEncoder });
canvasRenderTarget.endRenderPass();
}
animate();
};
init();
</script>
feature
- [✔] Camera
- [✔] PerspectiveCamera
- [✔] OrthographicCamera
- [✔] Math
- [✔] control
- [✔] OrbitControl
- [✔] Light
- [✔] AmbientLight
- [✔] DirectionalLight
- [✔] PointLight
- [✔] SpotLight
- [✔] Loader
- [✔] GLTFLoader
- [✔] CubeTextureLoader
- [✔] Materials
- [✔] ColorMaterial
- [✔] Material
- [✔] PbrMaterial(IBL/Light Render)
- [✔] BlinPhongMaterial
- [✔] ShaderMaterial
- [✔] SkyBoxMaterial
- [✔] Post-Effect
- [✔] BloomPostEffect
- [✔] Shadow
- [✔] DirectionalLightShadow
- [✔] PointLightShadow
- [✔] SpotLightShadow
Next
- Complete animation
- Complete core glTF 2.0
- Text and Sprite
- Pick
Related Skills
node-connect
353.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
111.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
353.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
353.3kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
