<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() {
	float diffuse = 1.564;
    float specular = 0.812;
    float rstop = 0.2;
    float palpha = 1.684;

	vec2 st = vUv; // [0,1]
	vec2 coord = vec2(st - vec2(0.5, 0.5))* 2.; // [-1,1]

	// angle = 15 degree
    const float flwrsn = 0.258819045102521;
    const float flwrcs = 0.965925826289068;
    mat2 flwrm = mat2(flwrcs, -flwrsn, flwrsn, flwrcs);
    // abs => double [0,1]
    vec2 flwrp = vec2(abs(coord.x), coord.y) * flwrm;
    float r;
    if(flwrp.x < 0.0) {
        // middle part(double)
        r = ellipse(flwrp, vec2(0.065, 0.024) * 0.5, vec2(0.36, 0.96) * 0.5);
    } else {
        // out part(double)
        r = ellipse(flwrp, vec2(0.065, 0.024) * 0.5, vec2(0.58, 0.96) * 0.5);
    }
    // r = ellipse(flwrp, vec2(0.250,0.440), vec2(0.140,0.190));
    vec3 col = mix(vec3(1.0, 0.8, 0.75), vec3(1.0, 0.9, 0.87), r);
    
    float grady = mix(0.0, 1.0, pow(coord.y * 0.5 + 0.5, 0.35));
    col *= vec3(1.0, grady, grady);
    col *= mix(0.8, 1.0, pow(abs(coord.x), 0.3));
    col = col * diffuse + specular;
    
    float alpha = (0.5 - r / (rstop * 1.0));
    alpha = smoothstep(0.0, 1.0, alpha) * palpha;
    
    //gl_FragColor = vec4(vec3(alpha), 1.);
    gl_FragColor = vec4(col*0.5, alpha);
}
`;

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