I just learned babylon.js and want to implement a function:
I have some point clouds (actually there may be millions). The first step is to implement the point selection function.
I hope to run the calculation on the GPU and save the results into the texture for CPU extraction, so that I can quickly determine whether it is in the frame.
Below is a minimal (almost wrong) example I wrote in vue3+babylon.js, it’s not clear to me how to use RenderTargetTexture and PostProcess correctly
<template>
<canvas ref="renderCanvas"></canvas>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import * as BABYLON from 'babylonjs'
const renderCanvas = ref(null)
onMounted(() => {
const canvas = renderCanvas.value
const engine = new BABYLON.Engine(canvas, true)
const scene = new BABYLON.Scene(engine)
// Create camera and light
var light = new BABYLON.PointLight('Point', new BABYLON.Vector3(5, 10, 5), scene)
var camera = new BABYLON.ArcRotateCamera('Camera', 1, 0.8, 3, new BABYLON.Vector3(0, 0, 0), scene)
camera.attachControl(canvas, true)
const axes = new BABYLON.Debug.AxesViewer(scene, 1)
// Create point cloud
const points = []
const indices = []
for (let i = 0; i < 10000; i++) {
points.push(new BABYLON.Vector3(Math.random() * 10, Math.random() * 10, Math.random() * 10))
indices.push(i)
}
const vertexData = new BABYLON.VertexData()
const positions = []
points.forEach((point) => {
positions.push(point.x, point.y, point.z)
})
vertexData.positions = positions
// Create shader material
const customMaterial = new BABYLON.ShaderMaterial(
'customShader',
scene,
{
vertexSource: `
precision highp float;
attribute vec3 position;
uniform mat4 worldViewProjection;
void main(void) {
gl_PointSize = 3.0;
gl_Position = worldViewProjection * vec4(position, 1.0);
}
`,
fragmentSource: `
precision highp float;
void main(void) {
gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
}
`
},
{
attributes: ['position'],
uniforms: ['worldViewProjection'],
needAlphaBlending: true,
needAlphaTesting: true
}
)
customMaterial.pointsCloud = true // set PointCLoud mode
customMaterial.pointSize = 3 // set Point size
const pointCloud = new BABYLON.Mesh('pointCloud', scene)
pointCloud.material = customMaterial
vertexData.applyToMesh(pointCloud)
//??? how to render to texture with shader material
const renderTarget = new BABYLON.RenderTargetTexture(
'renderTarget',
{ width: 100, height: 100 },
scene
)
scene.customRenderTargets.push(renderTarget)
// do simple calculation
const modifyMaterial = new BABYLON.ShaderMaterial('modifyShader', scene, {
vertexSource: `
precision highp float;
attribute vec3 position;
uniform mat4 worldViewProjection;
void main(void) {
gl_Position = worldViewProjection * vec4(position + vec3(1.0, 1.0, 1.0), 1.0);
}
`,
fragmentSource: `
precision highp float;
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
`
})
renderTarget.onBeforeBindObservable.add(() => {
// scene.postProcessManager.directRender([modifyMaterial], renderTarget)
})
//??? how to get texture data, position
setTimeout(() => {
const textureData = renderTarget.readPixels()
console.log(textureData)
}, 2000)
// Run engine
engine.runRenderLoop(() => {
scene.render()
})
})
</script>
<style>
canvas {
width: 100%;
height: 100%;
display: block;
}
</style>
Any help is greatly appreciated!