<script type="x-shader/x-vertex" id="vertexshader">

			varying vec2 vUv;

			void main() {

				vUv = uv;

				gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

			}

		</script>

		<script type="x-shader/x-fragment" id="fragmentshader">

			uniform sampler2D baseTexture;
			uniform sampler2D bloomTexture;

			varying vec2 vUv;

			void main() {

				gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );

			}

		</script>
* {
  background-color: black;
}
import * as THREE from "https://cdn.skypack.dev/three@0.130.0";
import { OrbitControls } from "https://cdn.skypack.dev/three@0.130.0/examples/jsm/controls/OrbitControls.js";
import { EffectComposer } from "https://cdn.skypack.dev/three@0.130.0/examples/jsm/postprocessing/EffectComposer.js";
import { RenderPass } from "https://cdn.skypack.dev/three@0.130.0/examples/jsm/postprocessing/RenderPass.js";
import { UnrealBloomPass } from "https://cdn.skypack.dev/three@0.130.0/examples/jsm/postprocessing/UnrealBloomPass.js";
import { ShaderPass } from "https://cdn.skypack.dev/three@0.130.0/examples/jsm/postprocessing/ShaderPass.js";
import { CopyShader } from "https://cdn.skypack.dev/three@0.130.0/examples/jsm/shaders/CopyShader.js";

let bgScene, scene, camera, renderer, skybox, box, controls, composer, finalComposer, ring;

function initialise() {
 
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(55, window.innerWidth/window.innerHeight, 5, 1000); // near 45, fov 55
  camera.position.set(0, 3, 30);
  scene.background = new THREE.Color(0x0000FF);

  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.autoClear = false;
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  
  controls = new OrbitControls(camera, renderer.domElement);

  const geometry = new THREE.TorusKnotGeometry(5, 2, 5, 3, Math.PI);
  const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
  
  ring = new THREE.Mesh( geometry, material );
  
  scene.add(ring);
  
  const renderPass = new RenderPass(scene, camera);
  const bloomPass = new UnrealBloomPass(
    1.5,
    0.4,
    0.85
  );
  bloomPass.threshold = 0.2;
  bloomPass.strength = 2;
  bloomPass.radius = 0.65;

  composer = new EffectComposer(renderer);
  composer.renderToScreen = false;
  composer.addPass(renderPass);
  composer.addPass(bloomPass);
  
  const finalPass = new ShaderPass(
    new THREE.ShaderMaterial( {
      uniforms: {
        baseTexture: { value: null },
        bloomTexture: { value: composer.renderTarget2.texture }
      },
      vertexShader: document.getElementById( 'vertexshader' ).textContent,
      fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
      defines: {}
    } ), "baseTexture"
  );
  finalPass.needsSwap = true;
  
  finalComposer = new EffectComposer(renderer);
  finalComposer.addPass(renderPass);
  finalComposer.addPass(finalPass);
  
  animate();
}

function animate() {
  requestAnimationFrame(animate);
  scene.background.set(0x000000);
  composer.render();
  scene.background.set(0x0000FF);
  finalComposer.render();
}

initialise();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.