I need to write a program that evaluates a cubic bezier curve, using threejs and vertex shader.
I tried to calculate the bezier curve based on the x axis and the control points using the cubic bezier formula as a function that returns the vertex position, but what I got was a random straight deformed line. Here it was my attempt:
<script src="https://threejs.org/build/three.js"></script>
<script type="module">
const rendSize = new THREE.Vector2();
var controls,
scene,
camera,
renderer,
shaderMat;
function main() {
renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.OrthographicCamera( -10., 10., 10., -10., -10.0, 10.0 );
var vShader = `
//bellow is bezier formula
vec3 toBezier(float t, vec3 P0, vec3 P1, vec3 P2, vec3 P3) {
float t2 = t * t;
float one_minus_t = 1.0 - t;
float one_minus_t2 = one_minus_t * one_minus_t;
return (P0 * one_minus_t2 * one_minus_t + P1 * 3.0 * t * one_minus_t2 + P2 * 3.0 * t2 * one_minus_t + P3 * t2 * t);
}
uniform vec3 p0;
uniform vec3 p1;
uniform vec3 p2;
uniform vec3 p3;
void main(void) {
//the plan was to create a bezier curve based on the x position and the control points
vec3 pos = toBezier(position.x, p0, p1, p2, p3);
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos.x, pos.y, 0.0, 1.0);
}
`;
generateCurve(vShader);
renderer.clear();
renderer.render(scene, camera);
}
function generateCurve(vShader) {
var ptosControle = [ new THREE.Vector3( 0.0, 0.0, 0.0 ),
new THREE.Vector3( -0.5, Math.sin(Math.PI/2.0) / 2.0, 0.0 ),
new THREE.Vector3( 0.5, Math.sin(3.0*Math.PI/2.0) / 2.0, 0.0 ),
new THREE.Vector3( 1.0, 1.0, 0.0 )
];
shaderMat = new THREE.ShaderMaterial(
{ uniforms : {
p0 : { value : ptosControle[0]},
p1 : { value : ptosControle[1]},
p0 : { value : ptosControle[2]},
p3 : { value : ptosControle[3]},
},
vertexShader : vShader,
} );
const objPolCtrl = new THREE.Line ( new THREE.BufferGeometry().setFromPoints(ptosControle),
shaderMat
);
scene.add(objPolCtrl);
} main();