<main id="container"></main>
body, html{
	margin: 0;
	padding: 0;
}
const PI2 = Math.PI * 2.0;
const vertexShader = `
attribute vec3 position;
attribute vec2 uv;

varying vec2 vUv;

void main() {
  vUv = uv;
  gl_Position = vec4(position, 1.0);
}
`;
const fragmentShader = `
precision highp float;
varying vec2 vUv;
// pos orign radius
float ellipse(vec2 p, vec2 o, vec2 r) { 
    vec2 lp = (p - o) / r;
    return length(lp) - 1.0;
}
void main() {
	vec2 st = vUv;
	float r = ellipse(st, vec2(0.5), vec2(0.2,0.1));
	vec3 col = mix(vec3(1.0, 0.8, 0.75), vec3(1.0, 0.9, 0.87), r);
	// gl_FragColor = vec4(vec3(r), 1.);
	gl_FragColor = vec4(col, 1.);
}
`;

class Shaping {
	constructor() {
		this.obj = this.createObj();
	}
	createObj() {
		let screenGeometry = new THREE.BufferGeometry();
		let posVertices = new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0]);
		let uvVertices = new Float32Array([0, 0, 2, 0, 0, 2]);
		screenGeometry.addAttribute('position', new THREE.BufferAttribute(posVertices, 3));
		screenGeometry.addAttribute('uv', new THREE.BufferAttribute(uvVertices, 2));
		return new THREE.Mesh(
			screenGeometry,
			new THREE.RawShaderMaterial({
				vertexShader,
				fragmentShader,
				blending: THREE.AdditiveBlending
			})
		);
	}
	render() {}
}

class MainScene {
	constructor(container, callback) {
		this.container = container;
		this.width = window.innerWidth;
		this.height = window.innerHeight;
		this.clock = new THREE.Clock();

		// Camera
		const camera = (this.camera = new THREE.PerspectiveCamera(
			45,
			document.innerWidth / window.innerHeight,
			1,
			1000
		));
		camera.position.set(0, 0, 400);

		// Renderer
		const renderer = (this.renderer = new THREE.WebGLRenderer({
			antialias: false
		}));
		renderer.domElement.id = 'canvasWebGL';
		renderer.setPixelRatio(window.devicePixelRatio);
		renderer.setSize(this.width, this.height);
		renderer.gammaFactor = 2.2;
		renderer.setClearColor(0x111111, 1.0);
		container.appendChild(renderer.domElement);
		// Scene
		this.initScene(callback);
		// Events
		this.initEvents();
	}
	initScene(callback) {
		const scene = (this.scene = new THREE.Scene());
		const shapingObject = (this.shapingObject = new Shaping());
		scene.add(shapingObject.obj);
		this.animete();
		typeof callback === 'function' && callback();
	}
	initEvents() {
		window.addEventListener('resize', this.onWindowResize.bind(this), false);
	}
	onWindowResize() {
		this.width = getEleWidth(this.container);
		this.height = getEleHeight(this.container);
		this.camera.aspect = this.width / this.height;
		this.camera.updateProjectionMatrix();
		this.renderer.setPixelRatio(window.devicePixelRatio);
		this.renderer.setSize(this.width, this.height);
	}
	animete() {
		const time = this.clock.getDelta();
		this.shapingObject.render(time);
		this.renderer.render(this.scene, this.camera);
		requestAnimationFrame(this.animete.bind(this));
	}
}

window.onload = ()=> {
	let containerEle = document.querySelector("#container");
	new MainScene(containerEle);
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js