mirror of
https://github.com/visgl/luma.gl.git
synced 2025-12-08 17:36:19 +00:00
148 lines
3.2 KiB
TypeScript
148 lines
3.2 KiB
TypeScript
// luma.gl, MIT license
|
|
// Copyright (c) vis.gl contributors
|
|
|
|
import {Buffer, NumberArray, UniformStore} from '@luma.gl/core';
|
|
import {AnimationLoopTemplate, AnimationProps, Model} from '@luma.gl/engine';
|
|
import {ShaderAssembler} from '@luma.gl/shadertools';
|
|
|
|
const INFO_HTML = `
|
|
Modifying shader behavior with shader hooks
|
|
`;
|
|
|
|
// Base vertex and fragment shader code
|
|
const vs = `\
|
|
#version 300 es
|
|
|
|
in vec2 position;
|
|
|
|
void main() {
|
|
gl_Position = vec4(position, 0.0, 1.0);
|
|
OFFSET_POSITION(gl_Position);
|
|
}
|
|
`;
|
|
|
|
const fs = `\
|
|
#version 300 es
|
|
|
|
uniform appUniforms {
|
|
vec3 color;
|
|
} app;
|
|
|
|
out vec4 fragColor;
|
|
|
|
void main() {
|
|
fragColor = vec4(app.color, 1.0);
|
|
}
|
|
`;
|
|
|
|
const offsetLeftModule = {
|
|
name: 'offsetLeft',
|
|
inject: {
|
|
'vs:OFFSET_POSITION': 'position.x -= 0.5;'
|
|
}
|
|
};
|
|
|
|
const offsetRightModule = {
|
|
name: 'offsetRight',
|
|
inject: {
|
|
'vs:OFFSET_POSITION': 'position.x += 0.5;'
|
|
}
|
|
};
|
|
|
|
export default class AppAnimationLoopTemplate extends AnimationLoopTemplate {
|
|
static info = INFO_HTML;
|
|
|
|
model1: Model;
|
|
model2: Model;
|
|
positionBuffer: Buffer;
|
|
uniformBuffer1: Buffer;
|
|
uniformBuffer2: Buffer;
|
|
|
|
uniformStore = new UniformStore<{
|
|
app: {
|
|
color: NumberArray;
|
|
};
|
|
}>({
|
|
app: {
|
|
uniformTypes: {
|
|
color: 'vec3<f32>'
|
|
}
|
|
}
|
|
});
|
|
|
|
constructor({device}: AnimationProps) {
|
|
super();
|
|
|
|
const shaderAssembler = ShaderAssembler.getDefaultShaderAssembler();
|
|
shaderAssembler.addShaderHook('vs:OFFSET_POSITION(inout vec4 position)');
|
|
|
|
this.positionBuffer = device.createBuffer(new Float32Array([-0.3, -0.5, 0.3, -0.5, 0.0, 0.5]));
|
|
|
|
|
|
this.uniformBuffer1 = this.uniformStore.createUniformBuffer(device, 'app', {
|
|
app: {
|
|
color: [1, 0, 0]
|
|
}
|
|
});
|
|
|
|
let uniformBufferData = this.uniformStore.getUniformBufferData('app');
|
|
this.uniformBuffer1.write(uniformBufferData);
|
|
|
|
this.uniformBuffer2 = this.uniformStore.createUniformBuffer(device, 'app', {
|
|
app: {
|
|
color: [0, 0, 1]
|
|
}
|
|
});
|
|
|
|
this.model1 = new Model(device, {
|
|
vs,
|
|
fs,
|
|
shaderAssembler, // Not needed, if not specified uses the default ShaderAssembler
|
|
modules: [offsetLeftModule],
|
|
bufferLayout: [
|
|
{name: 'position', format: 'float32x2'},
|
|
],
|
|
attributes: {
|
|
position: this.positionBuffer
|
|
},
|
|
vertexCount: 3,
|
|
bindings: {
|
|
app: this.uniformBuffer1
|
|
}
|
|
});
|
|
|
|
this.model2 = new Model(device, {
|
|
vs,
|
|
fs,
|
|
shaderAssembler, // Not needed, if not specified uses the default ShaderAssembler
|
|
modules: [offsetRightModule],
|
|
bufferLayout: [
|
|
{name: 'position', format: 'float32x2'},
|
|
],
|
|
vertexCount: 3,
|
|
attributes: {
|
|
position: this.positionBuffer
|
|
},
|
|
bindings: {
|
|
app: this.uniformBuffer2
|
|
}
|
|
});
|
|
}
|
|
|
|
onFinalize() {
|
|
this.model1.destroy();
|
|
this.model2.destroy();
|
|
this.positionBuffer.destroy();
|
|
this.uniformStore.destroy();
|
|
this.uniformBuffer1.destroy();
|
|
this.uniformBuffer2.destroy();
|
|
}
|
|
|
|
onRender({device}: AnimationProps) {
|
|
const renderPass = device.beginRenderPass({clearColor: [0, 0, 0, 1]});
|
|
this.model1.draw(renderPass);
|
|
this.model2.draw(renderPass);
|
|
renderPass.end();
|
|
}
|
|
}
|