threeOnBeforeCompileCache

by sjpt

HTML

<p id='test' style="color:white">
test
</p>

CSS

html,body {
  margin: 0;
  height: 100%;
  background: #000;
  overflow: hidden;
}

JavaScript

// experiment to see how to tunr shadown of/off dynamically
// (experimentaiton done within devtools)
// Most things dynamic, change of renderer.shadowMap or receiveShadow 
// needs material update
// Cannot share material between objects with different receiveShadow

'use strict';
import * as THREE from "https://rawgit.com/mrdoob/three.js/dev/build/three.module.js";
let rr = 0.991;
function onBeforeCompile(shader) {
	window.test.innerHTML = 'material compiled: ' + rr;
	const r = '#include <lights_physical_fragment>';
    shader.fragmentShader = shader.fragmentShader.replace(r, `diffuseColor.r = ${rr};
    ${r}`);
}
console.clear(); console.log('>>>>>>>>>');

var
	renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true }),
	scene = new THREE.Scene(),
	camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight,
    	1, 1000),
	shape = new THREE.IcosahedronGeometry(1, 0),
    material = new THREE.MeshStandardMaterial({color: 0xffffff}),
    mesh = new THREE.Mesh(shape, material),
    light = new THREE.DirectionalLight(0xffffff);
material.onBeforeCompile = onBeforeCompile;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

camera.position.z = 5;
light.position.set(-5, 1, 5);

scene.add(mesh);
scene.add(light);

const render = function() {
	requestAnimationFrame(render);
  
  mesh.rotation.y+=0.01;
  rr += 0.01; rr = rr%1;
  material = new THREE.MeshStandardMaterial();
  material.onBeforeCompile = onBeforeCompile;
  material.defines = {test:rr}
  mesh.material = material;
  // material.transparent = !material.transparent
  // material.needsUpdate = true;
  
  //scene.remove(mesh);
  //scene.add(new THREE.Mesh(shape, material));
  //scene = new THREE.Scene();
  //scene.add(mesh); scene.add(light);
 ...