After some efforts, I have no way to use SPS and customize the Shader at the same time
For this I had to try to use Threejs for test, surprisingly it is almost no problem at all, the following is a screenshot of my test and the corresponding code
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Babylon Template</title>
<style>
body {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="canvas-holder">
<canvas id="maincanvas" width="300" height="300"></canvas>
</div>
<button id="btnRepeat" style="position: absolute; margin: 5px;">Repeat</button>
<script type="module">
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
1,
1000
);
camera.position.set(0, 8, 13);
camera.lookAt(0, 5, 0);
var renderer = new THREE.WebGL1Renderer({
antialias: true,
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x101010);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", onWindowResize, false);
var controls = new OrbitControls(camera, renderer.domElement);
scene.add(new THREE.GridHelper(10, 10));
var rMin = 5;
var rMax = 15;
var hMin = 0;
var hMax = 5;
var centerH = 6;
var delayMax = 1; // seconds
var colors = [0xd50f30, 0x039bdc, 0xfc5411, 0x1a2683, 0xfbe23d, 0x12923b];
var c = new THREE.Color();
var MAX_POINTS = 5000;
var pointsCount = 0;
var points = []; //3
var delay = []; //1
var color = []; //3
var turns = []; //1
var turnsMin = 5;
var turnsMax = 10;
var angle = [];
while (pointsCount < MAX_POINTS) {
let a = THREE.MathUtils.randFloat(0, Math.PI * 2);
let vec = new THREE.Vector3().setFromCylindricalCoords(
THREE.MathUtils.randFloat(rMin, rMax),
a,
THREE.MathUtils.randFloat(hMin, hMax)
);
points.push(vec);
delay.push(THREE.MathUtils.randFloat(-delayMax, 0));
c.set(colors[THREE.MathUtils.randInt(0, colors.length - 1)]);
color.push(c.r, c.g, c.b);
angle.push(a);
turns.push(THREE.MathUtils.randFloat(turnsMin, turnsMax));
pointsCount++;
}
var pointsTornadoGeom = new THREE.BufferGeometry().setFromPoints(points);
pointsTornadoGeom.setAttribute(
"color",
new THREE.BufferAttribute(new Float32Array(color), 3)
);
pointsTornadoGeom.setAttribute(
"delay",
new THREE.BufferAttribute(new Float32Array(delay), 1)
);
pointsTornadoGeom.setAttribute(
"angle",
new THREE.BufferAttribute(new Float32Array(angle), 1)
);
pointsTornadoGeom.setAttribute(
"turns",
new THREE.BufferAttribute(new Float32Array(turns), 1)
);
var pointsTornadoMat = new THREE.PointsMaterial({
vertexColors: THREE.VertexColors,
size: 0.2,
map: new THREE.TextureLoader().load(
"https://threejs.org/examples/textures/sprites/ball.png",
(tex) => {
tex.center.setScalar(0.5);
tex.rotation = -Math.PI * 0.5;
}
),
alphaTest: 0.5,
});
var uniformsTornado = {
time: { value: 0 },
centerH: { value: centerH },
duration: { value: 10 - delayMax }, // seconds
turnsMax: { value: turnsMax },
};
pointsTornadoMat.onBeforeCompile = (shader) => {
shader.uniforms.time = uniformsTornado.time;
shader.uniforms.centerH = uniformsTornado.centerH;
shader.uniforms.duration = uniformsTornado.duration;
shader.uniforms.turnsMax = uniformsTornado.turnsMax;
shader.vertexShader =
`
uniform float time;
uniform float centerH;
uniform float duration;
uniform float turnsMax;
attribute float delay;
attribute float angle;
attribute float turns;
varying float vRatio;
` + shader.vertexShader;
shader.vertexShader = shader.vertexShader.replace(
`#include <begin_vertex>`,
`#include <begin_vertex>
float t = time + delay;
t = t < 0. ? 0. : t;
float tRatio = 0.;
tRatio = clamp( (t * (turnsMax / turns)) / duration, 0., 1.);
vRatio = step(0.01, tRatio) - step(0.999, tRatio);
float durationA = PI * 2. * turns * tRatio;;
float A = angle + durationA;
transformed.x = cos(A);
transformed.z = sin(-A);
float l = length(position.xz);
transformed.xz *= l * mix(1., 0., tRatio);
transformed.y = mix(position.y, centerH, tRatio);
`
);
shader.vertexShader = shader.vertexShader.replace(
`gl_PointSize = size;`,
`gl_PointSize = size * smoothstep(0.01, 0.1, tRatio);`
);
shader.fragmentShader =
`
varying float vRatio;
` + shader.fragmentShader;
shader.fragmentShader = shader.fragmentShader.replace(
`#include <clipping_planes_fragment>`,
`
if (floor(vRatio + 0.5) < 1.) discard;
#include <clipping_planes_fragment>`
);
};
var pointsTornado = new THREE.Points(pointsTornadoGeom, pointsTornadoMat);
scene.add(pointsTornado);
var clock = new THREE.Clock();
var t = 0;
btnRepeat.addEventListener(
"click",
(event) => {
t = 0;
},
false
);
renderer.setAnimationLoop(() => {
t += clock.getDelta();
uniformsTornado.time.value = t;
renderer.render(scene, camera);
});
function onWindowResize() {
var width = window.innerWidth;
var height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
}
</script>
</body>
</html>
So maybe itâs not a system/driver issue? Do you think I have to use Threejs because of this problem?