Particular Wp Enqueue script in wordpress - javascript

When looking for a plugin, I ended up across this website
I saw that there is a nice cloud animation.
So I started a search on google to find the source of the code and I found it here ... Preview
/JS
<script type="text/javascript" src="js/ThreeWebGL.js"></script>
<script type="text/javascript" src="js/ThreeExtras.js"></script>
<script type="text/javascript" src="js/Detector.js"></script>
<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
/Html
<script id="vs" type="x-shader/x-vertex">
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fs" type="x-shader/x-fragment">
uniform sampler2D map;
uniform vec3 fogColor;
uniform float fogNear;
uniform float fogFar;
varying vec2 vUv;
void main() {
float depth = gl_FragCoord.z / gl_FragCoord.w;
float fogFactor = smoothstep( fogNear, fogFar, depth );
gl_FragColor = texture2D( map, vUv );
gl_FragColor.w *= pow( gl_FragCoord.z, 20.0 );
gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
}
</script>
<script type="text/javascript">
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
// Bg gradient
var canvas = document.createElement( 'canvas' );
canvas.width = 32;
canvas.height = window.innerHeight;
var context = canvas.getContext( '2d' );
var gradient = context.createLinearGradient( 0, 0, 0, canvas.height );
gradient.addColorStop(0, "#1e4877");
gradient.addColorStop(0.5, "#4584b4");
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
document.body.style.background = 'url(' + canvas.toDataURL('image/png') + ')';
// Clouds
var container;
var camera, scene, renderer, sky, mesh, geometry, material,
i, h, color, colors = [], sprite, size, x, y, z;
var mouseX = 0, mouseY = 0;
var start_time = new Date().getTime();
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.Camera( 30, window.innerWidth / window.innerHeight, 1, 3000 );
camera.position.z = 6000;
scene = new THREE.Scene();
geometry = new THREE.Geometry();
var texture = THREE.ImageUtils.loadTexture( 'cloud10.png' );
texture.magFilter = THREE.LinearMipMapLinearFilter;
texture.minFilter = THREE.LinearMipMapLinearFilter;
var fog = new THREE.Fog( 0x4584b4, - 100, 3000 );
material = new THREE.MeshShaderMaterial( {
uniforms: {
"map": { type: "t", value:2, texture: texture },
"fogColor" : { type: "c", value: fog.color },
"fogNear" : { type: "f", value: fog.near },
"fogFar" : { type: "f", value: fog.far },
},
vertexShader: document.getElementById( 'vs' ).textContent,
fragmentShader: document.getElementById( 'fs' ).textContent,
depthTest: false
} );
var plane = new THREE.Mesh( new THREE.Plane( 64, 64 ) );
for ( i = 0; i < 8000; i++ ) {
plane.position.x = Math.random() * 1000 - 500;
plane.position.y = - Math.random() * Math.random() * 200 - 15;
plane.position.z = i;
plane.rotation.z = Math.random() * Math.PI;
plane.scale.x = plane.scale.y = Math.random() * Math.random() * 1.5 + 0.5;
GeometryUtils.merge( geometry, plane );
}
mesh = new THREE.Mesh( geometry, material );
scene.addObject( mesh );
mesh = new THREE.Mesh( geometry, material );
mesh.position.z = - 8000;
scene.addObject( mesh );
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX ) * 0.25;
mouseY = ( event.clientY - windowHalfY ) * 0.15;
}
function onWindowResize( event ) {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
position = ( ( new Date().getTime() - start_time ) * 0.03 ) % 8000;
camera.position.x += ( mouseX - camera.target.position.x ) * 0.01;
camera.position.y += ( - mouseY - camera.target.position.y ) * 0.01;
camera.position.z = - position + 8000;
camera.target.position.x = camera.position.x;
camera.target.position.y = camera.position.y;
camera.target.position.z = camera.position.z - 1000;
renderer.render( scene, camera );
}
</script>
My question now :
I would like to set it up on my localhost site to test it on elementor.
I will call the script with an html widget.
The problem I know there is an wp_enqueue_script option in functions.php and the script goes there ..
but I can't understand the exact procedure. I failed for hours to set up the scripts ...
Can you show me how to integrate it ? I need a good example how use these scripts. to understand once and for all how to integrate scripts in wordpress child themes.
My setup :
A clean install of wordpress with an empty hello theme and it's child installed.
Update
let's develop the subject a bit
I did these manipulations in
functions.php
function my_scripts_method() {
wp_enqueue_script('custom-script',get_stylesheet_directory_uri() . '/js/ThreeWebGL.js',array( 'jquery' ));
wp_enqueue_script('custom-script',get_stylesheet_directory_uri() . '/js/ThreeExtras.js',array( 'jquery' ));
wp_enqueue_script('custom-script',get_stylesheet_directory_uri() . '/js/Detector.js',array( 'jquery' ));
wp_enqueue_script('custom-script',get_stylesheet_directory_uri() . '/js/RequestAnimationFrame.js',array( 'jquery' ));
}
add_action( 'wp_enqueue_scripts', 'my_scripts_method' );
It seems to work.. the scripts are loaded I hope.
I just have a message in the chrome console :
Uncaught ReferenceError: Detector is not defined at (index): 117
I guess because i haven't put html yet?
what do you think of a snippet?
I use it to create and add_shortcode
something like that.. do you think it's safe?
add_shortcode( 'amazing clouds', function () {
<script id="vs" type="x-shader/x-vertex">
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fs" type="x-shader/x-fragment">
uniform sampler2D map;
uniform vec3 fogColor;
uniform float fogNear;
uniform float fogFar;
varying vec2 vUv;
void main() {
float depth = gl_FragCoord.z / gl_FragCoord.w;
float fogFactor = smoothstep( fogNear, fogFar, depth );
gl_FragColor = texture2D( map, vUv );
gl_FragColor.w *= pow( gl_FragCoord.z, 20.0 );
gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
}
</script>
<script type="text/javascript">
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
// Bg gradient
var canvas = document.createElement( 'canvas' );
canvas.width = 32;
canvas.height = window.innerHeight;
var context = canvas.getContext( '2d' );
var gradient = context.createLinearGradient( 0, 0, 0, canvas.height );
gradient.addColorStop(0, "#1e4877");
gradient.addColorStop(0.5, "#4584b4");
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
document.body.style.background = 'url(' + canvas.toDataURL('image/png') + ')';
// Clouds
var container;
var camera, scene, renderer, sky, mesh, geometry, material,
i, h, color, colors = [], sprite, size, x, y, z;
var mouseX = 0, mouseY = 0;
var start_time = new Date().getTime();
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.Camera( 30, window.innerWidth / window.innerHeight, 1, 3000 );
camera.position.z = 6000;
scene = new THREE.Scene();
geometry = new THREE.Geometry();
var texture = THREE.ImageUtils.loadTexture( 'cloud10.png' );
texture.magFilter = THREE.LinearMipMapLinearFilter;
texture.minFilter = THREE.LinearMipMapLinearFilter;
var fog = new THREE.Fog( 0x4584b4, - 100, 3000 );
material = new THREE.MeshShaderMaterial( {
uniforms: {
"map": { type: "t", value:2, texture: texture },
"fogColor" : { type: "c", value: fog.color },
"fogNear" : { type: "f", value: fog.near },
"fogFar" : { type: "f", value: fog.far },
},
vertexShader: document.getElementById( 'vs' ).textContent,
fragmentShader: document.getElementById( 'fs' ).textContent,
depthTest: false
} );
var plane = new THREE.Mesh( new THREE.Plane( 64, 64 ) );
for ( i = 0; i < 8000; i++ ) {
plane.position.x = Math.random() * 1000 - 500;
plane.position.y = - Math.random() * Math.random() * 200 - 15;
plane.position.z = i;
plane.rotation.z = Math.random() * Math.PI;
plane.scale.x = plane.scale.y = Math.random() * Math.random() * 1.5 + 0.5;
GeometryUtils.merge( geometry, plane );
}
mesh = new THREE.Mesh( geometry, material );
scene.addObject( mesh );
mesh = new THREE.Mesh( geometry, material );
mesh.position.z = - 8000;
scene.addObject( mesh );
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX ) * 0.25;
mouseY = ( event.clientY - windowHalfY ) * 0.15;
}
function onWindowResize( event ) {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
position = ( ( new Date().getTime() - start_time ) * 0.03 ) % 8000;
camera.position.x += ( mouseX - camera.target.position.x ) * 0.01;
camera.position.y += ( - mouseY - camera.target.position.y ) * 0.01;
camera.position.z = - position + 8000;
camera.target.position.x = camera.position.x;
camera.target.position.y = camera.position.y;
camera.target.position.z = camera.position.z - 1000;
renderer.render( scene, camera );
}
</script>
} );
Things got very complicated very quickly.
I hope someone will come and show us how to integrate it into a wordpress page
(with elementor is bonus)

The HTML widget will strip out php tags for security reasons. But you have several options which will allow you to achieve your goal. Here are three:
Edit your child theme's functions.php file to allow php in the
widget. (Bad idea)
Write your own custom widget which enqueues the script you need.
(Better idea)
Don't use a widget at all. Just add the script to the pages you want it using the Advanced Custom Fields plugin. (Best idea IMHO)
And since you asked about loading JS, here's a good resource for you.
And here's another on the topic of wp_enqueue_scripts().
Edit: step by step instructions for ACF plugin:
Install Advanced Custom Fields plugin
Go to the Custom Fields settings and click Add New
Name the field group something like “Javascript Settings”
Create rules to restrict where the fields will appear and who will see them
Next to Style, choose Standard (WP metabox)
Click + Add Field
Name it “Header Script”
Change Field Type to “Text Area”
Change Formatting to “Convert HTML to tags”
Repeat from step 6, but this time call it “Footer Script”
Publish the Field Group
In header.php, right before the closing </head> tag, add: <?php the_field('header_script'); ?>
In footer.php, right before the closing </body> tag, add: <?php the_field(‘footer_script'); ?>
Place your javascript files in a folder on your server (preferably in a child theme).
Link your javascript in the new fields on your page using regular html <script> tags
Note: copy your header.php and footer.php files into your child theme and make the edits (steps 12 & 13) there to avoid losing these changes if your theme is updated.

Related

GLSL In ThreeJS Mix FragColor With UnrealBloom To Get Selective Glow

I want to implement selective bloom for an imported GLTF model in ThreeJS using an Emission map.
To achieve this I am supposed to first make the objects that should not have bloom completely black and using the UnrealBloomPass and the ShaderPass I'm going to mix the bloomed and non-bloomed effect passes together somehow.
I need to use GLSL code, which I'm only barely familiar with. Here is my basic setup:
View Example In JSFiddle
<!DOCTYPE html>
<html lang="en">
<head>
<title>Render View</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body id="body" style="overflow: hidden">
<h1 id="info">loading scene, this might take a few seconds..</h1>
<!-- Warning: xhr progress seems to not work over cnd.jsdelivr -->
<!-- <div id="loading" id="myProgress"><div id="myBar"></div></div> -->
<input class="tool" id="backgroundColor" type="color" value="#2e2e2e">
<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>
<script type="module">
import * as THREE from 'https://threejs.org/build/three.module.js'
import Stats from 'https://threejs.org/examples/jsm/libs/stats.module.js'
import { GUI } from 'https://threejs.org/examples/jsm/libs/dat.gui.module.js'
import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js'
import { GLTFLoader } from 'https://threejs.org/examples/jsm/loaders/GLTFLoader.js'
import { RGBELoader } from 'https://threejs.org/examples/jsm/loaders/RGBELoader.js'
import { EffectComposer } from 'https://threejs.org/examples/jsm/postprocessing/EffectComposer.js';
import { ShaderPass } from 'https://threejs.org/examples/jsm/postprocessing/ShaderPass.js';
import { RenderPass } from 'https://threejs.org/examples/jsm/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'https://threejs.org/examples/jsm/postprocessing/UnrealBloomPass.js';
function $(e){return document.getElementById(e)}
function createContainer() {
var ctn = document.createElement( 'div' )
document.body.appendChild( ctn )
return ctn
}
function createScene() {
var scn = new THREE.Scene()
scn.fog = new THREE.Fog( new THREE.Color("rgb(100, 100, 100)"), 40, 150 )
return scn
}
function createCamera() {
var cam = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 )
cam.position.set( 20, 12, 20 )
return cam
}
function createRenderer() {
var rnd = new THREE.WebGLRenderer( { antialias: true } )
rnd.setPixelRatio( window.devicePixelRatio )
rnd.setSize( window.innerWidth, window.innerHeight )
rnd.toneMapping = THREE.ReinhardToneMapping
rnd.outputEncoding = THREE.sRGBEncoding
rnd.shadowMap.enabled = true
rnd.shadowMap.type = THREE.PCFSoftShadowMap
container.appendChild( rnd.domElement )
return rnd
}
function createControls() {
var ctr = new OrbitControls( camera, renderer.domElement )
ctr.minDistance = 1
ctr.maxDistance = 50
ctr.enablePan = true
ctr.enableZoom = true
ctr.enableDamping = true
ctr.dampingFactor = 0.1
ctr.rotateSpeed = 0.5
return ctr
}
function createDirectionalLight() {
var drt = new THREE.DirectionalLight( new THREE.Color("rgb(255, 255, 255)"), 1 )
drt.castShadow = true
drt.shadow.camera.top = 64
drt.shadow.camera.top = 64
drt.shadow.camera.bottom = - 64
drt.shadow.camera.left = - 64
drt.shadow.camera.right = 64
drt.shadow.camera.near = 0.2
drt.shadow.camera.far = 80
drt.shadow.camera.far = 80
drt.shadow.bias = - 0.002
drt.position.set( 0, 20, 20 )
drt.shadow.mapSize.width = 1024*8
drt.shadow.mapSize.height = 1024*8
// scene.add( new THREE.CameraHelper( drt.shadow.camera ) )
scene.add( drt )
return drt
}
function createSceneBounds() {
var cube = new THREE.Mesh( new THREE.BoxGeometry( 20, 20, 20 ) )
cube.position.y = 0
cube.visible = false
scene.add(cube)
return new THREE.Box3().setFromObject( cube );
}
function createBloomPass() {
var blp = new UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 )
blp.threshold = params.bloomThreshold
blp.strength = params.bloomStrength
blp.radius = params.bloomRadius
return blp
}
function createFinalPass() {
var shp = new ShaderPass(
new THREE.ShaderMaterial( {
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer.renderTarget2.texture }
},
vertexShader: document.getElementById( 'vertexshader' ).textContent,
fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
defines: {}
} ), "baseTexture"
);
shp.needsSwap = true
return shp
}
function createEnvironment( hdr, onLoad ) {
new RGBELoader().setDataType( THREE.UnsignedByteType ).load( hdr, function ( texture ) {
const pmremGenerator = new THREE.PMREMGenerator( renderer )
pmremGenerator.compileEquirectangularShader()
const envMap = pmremGenerator.fromEquirectangular( texture ).texture
scene.environment = envMap
texture.dispose()
pmremGenerator.dispose()
onLoad()
} );
}
function loadGLTF( file, onLoad ) {
new GLTFLoader().load( file , onLoad, function( xhr ) {
// Warning: xhr progress seems to not work over cnd.jsdelivr
// if ( xhr.lengthComputable ) {
// var percentComplete = xhr.loaded / xhr.total * 100
// var elem = document.getElementById("myBar");
// elem.style.width = Math.round(percentComplete, 2) + "%";
// console.log( "Loading Model - " + Math.round(percentComplete, 2) + "%" )
// }
})
}
const params = {
exposure: 1,
bloomStrength: 5,
bloomThreshold: 0,
bloomRadius: 0,
scene: "Scene with Glow"
};
const container = createContainer()
const scene = createScene()
const camera = createCamera()
const renderer = createRenderer()
const controls = createControls()
const directionalLight = createDirectionalLight()
const sceneBounds = createSceneBounds()
const renderScene = new RenderPass( scene, camera )
const bloomPass = createBloomPass()
const bloomComposer = new EffectComposer( renderer )
bloomComposer.addPass( renderScene )
bloomComposer.addPass( bloomPass )
const finalPass = createFinalPass()
const finalComposer = new EffectComposer( renderer )
finalComposer.addPass( renderScene )
finalComposer.addPass( finalPass )
var model = null
var importedMaterial = null
var emissiveMaterial = null
var mesh = null
var meshBounds = null
createEnvironment( "https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/forest.hdr", function() {
loadGLTF( "https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/turntable_121.glb", function ( gltf ) {
model = gltf.scene
model.traverse( function ( child ) {
if ( child.isMesh ) {
mesh = child
// enable shadows
mesh.castShadow = true
mesh.receiveShadow = true
// set original material
importedMaterial = mesh.material
importedMaterial.envMapIntensity = 1
// assign temporary black material
mesh.material = new THREE.MeshBasicMaterial({color: 0x000000})
// assign bloom only material
new THREE.TextureLoader()
.load("https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/RecordPlayer_Emission.jpeg",
function( texture ) {
texture.flipY = false
texture.encoding = THREE.sRGBEncoding
emissiveMaterial = new THREE.MeshBasicMaterial({map: texture});
mesh.material = emissiveMaterial
})
}
});
fitObjectToSceneBounds()
scene.add( model )
$("info").style.display = "none"
// Warning: xhr progress seems to not work over cnd.jsdelivr
// $("loading").style.display = "none"
animate()
})
})
const animate = function () {
requestAnimationFrame( animate )
// set background color
scene.background = new THREE.Color( new THREE.Color( $("backgroundColor").value ) )
$('body').attributes['style'].textContent='background-color:'+ $("backgroundColor").value
controls.update()
bloomComposer.render()
// finalComposer.render()
};
window.addEventListener( 'resize', function () {
const width = window.innerWidth
const height = window.innerHeight
renderer.setSize( width, height )
bloomComposer.setSize( width, height );
finalComposer.setSize( width, height );
camera.aspect = width / height
camera.updateProjectionMatrix()
})
function fitCameraToSelection( camera, controls, selection, fitOffset = 1 ) {
const box = new THREE.Box3()
try {
for( const object of selection ) {
box.expandByObject( object )
}
} catch( e ) { box.expandByObject( selection ) }
const size = box.getSize( new THREE.Vector3() )
const center = box.getCenter( new THREE.Vector3() )
const maxSize = Math.max( size.x, size.y, size.z )
const fitHeightDistance = maxSize / ( 1.7 * Math.atan( Math.PI * camera.fov / 360 ) )
const fitWidthDistance = fitHeightDistance / camera.aspect
const distance = fitOffset * Math.max( fitHeightDistance, fitWidthDistance )
const direction = controls.target.clone().sub( camera.position ).normalize().multiplyScalar( distance )
controls.maxDistance = distance * 10
controls.target.copy( center )
camera.near = distance / 100
camera.far = distance * 100
camera.updateProjectionMatrix()
camera.position.copy( controls.target ).sub(direction);
controls.update()
}
function fitObjectToSceneBounds() {
meshBounds = new THREE.Box3().setFromObject( model )
let lengthSceneBounds = {
x: Math.abs(sceneBounds.max.x - sceneBounds.min.x),
y: Math.abs(sceneBounds.max.y - sceneBounds.min.y),
z: Math.abs(sceneBounds.max.z - sceneBounds.min.z),
};
let lengthMeshBounds = {
x: Math.abs(meshBounds.max.x - meshBounds.min.x),
y: Math.abs(meshBounds.max.y - meshBounds.min.y),
z: Math.abs(meshBounds.max.z - meshBounds.min.z),
};
let lengthRatios = [
(lengthSceneBounds.x / lengthMeshBounds.x),
(lengthSceneBounds.y / lengthMeshBounds.y),
(lengthSceneBounds.z / lengthMeshBounds.z),
];
let minRatio = Math.min(...lengthRatios)
let padding = 0
minRatio -= padding
model.scale.set(minRatio, minRatio, minRatio)
}
const gui = new GUI();
gui.add( params, 'exposure', 0.1, 2 ).onChange( function ( value ) {
renderer.toneMappingExposure = Math.pow( value, 4.0 );
} );
gui.add( params, 'bloomThreshold', 0.0, 1.0 ).step( 0.001 ).onChange( function ( value ) {
bloomPass.threshold = Number( value );
} );
gui.add( params, 'bloomStrength', 0.0, 20.0 ).step( 0.01 ).onChange( function ( value ) {
bloomPass.strength = Number( value );
} );
gui.add( params, 'bloomRadius', 0.0, 5.0 ).step( 0.01 ).onChange( function ( value ) {
bloomPass.radius = Number( value );
} );
</script>
</body>
</html>
When you look at the result in the JSFiddle you can see that the glow is nicely visible and the rest of the object is black.
Now I need to know how I can use GLSL to combine the fragment shader with the UnrealBloomPass and like mix both results together. However I do not really know how to do that since GLSL is not something I have a lot of experience with it and I don't know how to use it in combination with ThreeJS.
How can I get the selective bloom working?
The order for selective bloom is still the same:
Make all non-bloomed objects totally black
Render the scene with bloomComposer
Restore materials/colors to previous
Render the scene with finalComposer
Patch model's material, having a common uniform, that indicates which render will be used:
body{
overflow: hidden;
margin: 0;
}
<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>
<script type="module">
console.clear();
import * as THREE from 'https://cdn.jsdelivr.net/npm/three#0.127.0/build/three.module.js';
import {GLTFLoader} from 'https://cdn.jsdelivr.net/npm/three#0.127.0/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three#0.127.0/examples/jsm/controls/OrbitControls.js';
import { EffectComposer } from 'https://cdn.jsdelivr.net/npm/three#0.127.0/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'https://cdn.jsdelivr.net/npm/three#0.127.0/examples/jsm/postprocessing/RenderPass.js';
import { ShaderPass } from 'https://cdn.jsdelivr.net/npm/three#0.127.0/examples/jsm/postprocessing/ShaderPass.js';
import { UnrealBloomPass } from 'https://cdn.jsdelivr.net/npm/three#0.127.0/examples/jsm/postprocessing/UnrealBloomPass.js';
let model;
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 100);
camera.position.set(7.7, 2.5, 7.2);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
//renderer.setClearColor(0x404040);
document.body.appendChild(renderer.domElement);
let controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", e => {console.log(camera.position)})
let light = new THREE.DirectionalLight(0xffffff, 1.5);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
let uniforms = {
globalBloom: {value: 1}
}
let loader = new GLTFLoader();
loader.load( "https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/turntable_121.glb", function ( gltf ) {
model = gltf.scene;
let emssvTex = new THREE.TextureLoader().load("https://cdn.jsdelivr.net/gh/MigerRepo/bloom-solution/RecordPlayer_Emission.jpeg", function( texture ) {
texture.flipY = false
texture.encoding = THREE.sRGBEncoding
})
model.traverse( function ( child ) {
if ( child.isMesh ) {
child.material.emissiveMap = emssvTex;
child.material.onBeforeCompile = shader => {
shader.uniforms.globalBloom = uniforms.globalBloom;
shader.fragmentShader = `
uniform float globalBloom;
${shader.fragmentShader}
`.replace(
`#include <dithering_fragment>`,
`#include <dithering_fragment>
if (globalBloom > 0.5){
gl_FragColor = texture2D( emissiveMap, vUv );
}
`
);
console.log(shader.fragmentShader);
}
}
});
model.scale.setScalar(40);
scene.add(model);
});
// bloom
const renderScene = new RenderPass( scene, camera );
const bloomPass = new UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 2, 0, 0 );
const bloomComposer = new EffectComposer( renderer );
bloomComposer.renderToScreen = false;
bloomComposer.addPass( renderScene );
bloomComposer.addPass( bloomPass );
const finalPass = new ShaderPass(
new THREE.ShaderMaterial( {
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer.renderTarget2.texture }
},
vertexShader: document.getElementById( 'vertexshader' ).textContent,
fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
defines: {}
} ), "baseTexture"
);
finalPass.needsSwap = true;
const finalComposer = new EffectComposer( renderer );
finalComposer.addPass( renderScene );
finalComposer.addPass( finalPass );
window.onresize = function () {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( innerWidth, innerHeight );
bloomComposer.setSize( innerWidth, innerHeight );
finalComposer.setSize( innerWidth, innerHeight );
};
renderer.setAnimationLoop( _ => {
renderer.setClearColor(0x000000);
uniforms.globalBloom.value = 1;
bloomComposer.render();
renderer.setClearColor(0x404040);
uniforms.globalBloom.value = 0;
finalComposer.render();
//renderer.render(scene, camera);
})
</script>

three.js memory management shader material

I'm trying to create textual labels. I need to use shader material to better control the label during rendering.
I've noticed that the memory keeps increasing even though I clean up old labels.
I've created a jsfiddle example that is not unlike: https://threejs.org/examples/#webgl_test_memory
The following code uses a canvas object to generate a texture, which contains the text to be depicted as a label:
Please be careful, these computations are heavy and make the tab quite unresponsive.
var container;
var camera, scene, renderer;
var labels;
var canvas;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 200;
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
labels = new THREE.Object3D();
canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
// get text metrics
var fontface = 'Arial';
var fontSize = 60;
context.font = fontSize + "px " + fontface;
var width = context.measureText(text).width;
// add text
var text = 'abcdef';
canvas.width = width;
canvas.height = fontSize*1.3;
context.textAlign = "center";
context.font = fontSize + "px " + fontface;
context.fillStyle = "white";
context.fillText(text, canvas.width / 2, canvas.height / 2);
}
function createLabels() {
for(var i = 0; i < 10000 ; i++) {
createTextMesh();
}
scene.add( labels );
}
function createTextMesh() {
// canvas contents will be used for a texture
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
var uniforms = {
text: {
type: 't',
value: texture
}
};
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertex-shader' ).textContent,
fragmentShader: document.getElementById( 'fragment-shader' ).textContent
} );
var geometry = new THREE.PlaneBufferGeometry(15, 15);
var label = new THREE.Mesh( geometry, material );
labels.add(label);
}
function clearLabels() {
for(var i = 0; i < labels.children.length; i++) {
var label = labels.children[i];
if(label.material.uniforms) {
label.material.uniforms.text.value.dispose();
}
label.material.dispose();
label.geometry.dispose();
labels.remove(label);
}
scene.remove( labels );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
// build GL objects
createLabels();
renderer.render( scene, camera );
// clean up
clearLabels();
}
body {
margin:0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>
<script id="fragment-shader" type="x-shader/x-fragment">
uniform sampler2D text;
varying vec2 vUv;
void main() {
vec4 finalColor = texture2D(text, vUv);
gl_FragColor = finalColor;
}
</script>
<script id="vertex-shader" type="x-shader/x-fragment">
varying vec2 vUv;
void main() {
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<canvas></canvas>
You can use's chromes dev tools to evaluate the perceptual memory utilisation increase.
I'd recommend using something like Window's own task manager to see the memory increase.
You can decrease the label creation speed, although this will naturally mean that it will take longer for the tab do run out of memory.
Am I doing the resource clean-up wrongly?
Cheers
Hi try out following code
as I have added time gap in animate function which calls render function.
there is one variable fps currently 24, you can change it.
<!DOCTYPE html>
<html lang="en">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>three.js - shader material memory leak</title>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background:#fff;
padding:0;
margin:0;
overflow:hidden;
}
</style>
</head>
<body>
<script src="https://threejs.org/build/three.js"></script>
<script id="fragment-shader" type="x-shader/x-fragment">
uniform sampler2D text;
varying vec2 vUv;
void main() {
vec4 finalColor = texture2D(text, vUv);
gl_FragColor = finalColor;
}
</script>
<script id="vertex-shader" type="x-shader/x-fragment">
varying vec2 vUv;
void main() {
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script>
var container,
camera, scene, renderer,
labels,
canvas,
lastTime, fps = 24;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 200;
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
labels = new THREE.Object3D();
canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
// get text metrics
var fontface = 'Arial';
var fontSize = 60;
context.font = fontSize + "px " + fontface;
var width = context.measureText(text).width;
// add text
var text = 'abcdef';
canvas.width = width;
canvas.height = fontSize*1.3;
context.textAlign = "center";
context.font = fontSize + "px " + fontface;
context.fillStyle = "white";
context.fillText(text, canvas.width / 2, canvas.height / 2);
}
function createLabels() {
for(var i = 0; i < 10000 ; i++) {
createTextMesh();
}
scene.add( labels );
}
function createTextMesh() {
// canvas contents will be used for a texture
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
var uniforms = {
text: {
type: 't',
value: texture
}
};
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertex-shader' ).textContent,
fragmentShader: document.getElementById( 'fragment-shader' ).textContent
} );
var geometry = new THREE.PlaneBufferGeometry(15, 15);
var label = new THREE.Mesh( geometry, material );
labels.add(label);
}
function clearLabels() {
for(var i = 0; i < labels.children.length; i++) {
var label = labels.children[i];
if(label.material.uniforms) {
label.material.uniforms.text.value.dispose();
}
label.material.dispose();
label.geometry.dispose();
labels.remove(label);
}
scene.remove( labels );
}
// Add time gap render will call with 24 fps. or you can slow down speed to check.
function animate() {
var curTime = new Date();
if(lastTime === undefined || (Math.round(curTime - lastTime)/1000) >= fps)
{
render();
lastTime = curTime;
}
requestAnimationFrame( animate );
}
function render() {
// build GL objects
createLabels();
renderer.render( scene, camera );
// clean up
clearLabels();
}
</script>
<div>
<canvas width="1920" height="974" style="width: 1920px; height: 974px;"></canvas>
</div>
</body>
</html>
Don't create a new mesh 1000 times every tick, pool them.
Don't create a 1000 geometries that are all the same plane. This is probably the biggest culprit here. Create just one, ever, and pass it to meshes.
Textures, im not so sure about that one. I think you're not supposed to create a new texture from the canvas context, create once and update canvas.
This will go away with the changes, but it's good to note that for performance you'd want to avoid creating that uniforms object in the loop as well.
EDIT
You do create a lot of stuff. Width of the label comes in as 263, and if three's console log is to be trusted, it's resized to 256x64. So you end up with 480mb of data, although, with the alpha channel it could be 600mb. I assume that your demo never even gets to the disposal part. It just crashed the browser on my end.
Three also complains about the textures being NPOT, so it attempts to write out ten thousand console logs.

Load textures from Base64 in Three.js

I am currently loading textures from URLs but since my back-end code is generating planets I need them to be displayed using Base64.
(I'm playing around with procedural generation so I'd prefer not to save the image and then load it via URL)
Here's the code;
<!DOCTYPE html><html class=''>
<head>
<style>body {
background: black;
text-align: center;
}
</style></head><body>
<script id="vertexShader" type="x-shader/x-vertex">
uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main({
vec3 vNormal = normalize( normalMatrix * normal );
vec3 vNormel = normalize( normalMatrix * viewVector );
intensity = pow( c - dot(vNormal, vNormel), p );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec3 glowColor;
varying float intensity;
void main() {
vec3 glow = glowColor * intensity;
gl_FragColor = vec4( glow, 1.0 );
}
</script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/three.js/r63/three.min.js'></script><script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/orbitcontrols.js'></script>
<script>var container, controls, camera, renderer, scene, light,
rotationSpeed = 0.02,
clock = new THREE.Clock(),
WIDTH = window.innerWidth - 30,
HEIGHT = window.innerHeight - 30;
//cam vars
var angle = 45,
aspect = WIDTH / HEIGHT,
near = 0.1,
far = 10000;
//mesh vars
var earthMesh, Atmos, AtmosMat;
container = document.createElement('div');
document.body.appendChild(container);
//cam
camera = new THREE.PerspectiveCamera(angle, aspect, near, far);
camera.position.set(1380, -17, 394);
//scene
scene = new THREE.Scene();
camera.lookAt(scene.position);
//light
light = new THREE.SpotLight(0xFFFFFF, 1, 0, Math.PI / 2, 1);
light.position.set(4000, 4000, 1500);
light.target.position.set (1000, 3800, 1000);
light.castShadow = true;
//light.shadowCameraNear = 1;
//light.shadowCameraFar = 10000;
//light.shadowCameraFov = 50;
scene.add(light);
//EARTH
var earthGeo = new THREE.SphereGeometry (200, 400, 400),
earthMat = new THREE.MeshPhongMaterial();
earthMesh = new THREE.Mesh(earthGeo, earthMat);
earthMesh.position.set(-100, 0, 0);
earthMesh.rotation.y=5;
scene.add(earthMesh);
//diffuse
earthMat.map = THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/earthmap.jpg');
//bump
earthMat.bumpMap = THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/bump-map.jpg');
earthMat.bumpScale = 8;
//specular
earthMat.specularMap = THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/earthspec1k.jpg');
earthMat.specular = new THREE.Color('#2e2e2e');
earthMesh.castShadow = true;
earthMesh.receiveShadow = true;
//Atmosphere
AtmosMat = new THREE.ShaderMaterial({
uniforms:{
"c": { type: "f", value: 0.3 },
"p": { type: "f", value: 5.2},
glowColor: { type: "c", value: new THREE.Color(0x00dbdb)},
viewVector: { type: "v3", value: camera.position}
},
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent,
side: THREE.BackSide,
blending: THREE.AdditiveBlending,
transparent: true
});
Atmos = new THREE.Mesh(earthGeo, AtmosMat);
Atmos.position = earthMesh.position;
Atmos.scale.multiplyScalar(1.2);
scene.add(Atmos);
//STARS
var starGeo = new THREE.SphereGeometry (3000, 10, 100),
starMat = new THREE.MeshBasicMaterial();
starMat.map = THREE.ImageUtils.loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/star-field.png');
starMat.side = THREE.BackSide;
var starMesh = new THREE.Mesh(starGeo, starMat);
scene.add(starMesh);
//renderer
renderer = new THREE.WebGLRenderer({antialiasing : true});
renderer.setSize(WIDTH, HEIGHT);
container.appendChild(renderer.domElement);
//controls
controls = new THREE.OrbitControls( camera, renderer.domElement);
controls.addEventListener( 'change', render );
function animate(){
requestAnimationFrame(animate);
controls.update();
render();
}
function render(){
var delta = clock.getDelta();
earthMesh.rotation.y += rotationSpeed * delta;
renderer.clear();
renderer.render(scene, camera);
}
animate();
//# sourceURL=pen.js
</script>
</body></html>
I have tried;
image = document.createElement( 'img' );
document.body.appendChild( image );
earthMat.map = new THREE.Texture( image );
image.addEventListener( 'load', function ( event ) { texture.needsUpdate = true; } );
image.src = 'data:image/png;base64,<?php echo $image_data_base64 ?>';
But it doesn't seem to be working correctly.
Any help would be greatly appreciated, thanks.
Turns out I had to do;
earthMat.map = THREE.ImageUtils.loadTexture( image.src );
Instead of;
earthMat.map = new THREE.Texture( image );
new event listener;
image.addEventListener( 'load', function ( event ) {
earthMat.map = THREE.ImageUtils.loadTexture( image.src );
earthMat.needsUpdate = true;
});
Perhaps this does not meet the needs of the original question with the base64 string coming from a PHP script, but in our case the solution was much simpler (THREE.js r130):
const manager = new THREE.LoadingManager()
const texture = new THREE.TextureLoader(manager).load('data:image/png;base64,...')

make a three.js animation from an image with effects

This a code made in three.js so its like a gemoetry big cube made with small cube written in css,but i want to make that the source will be an image and that image will be the big structure made with small cube,i.e-if the image is google logo the thing will be google made with small cubes and with the three.js effects,but i can't figure out how to do it.
<html>
<head>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background:#fff;
padding:0;
margin:0;
font-weight: bold;
overflow:hidden;
}
</style>
</head>
<body>
<script src="../build/three.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
var container, stats;
var camera, scene, renderer;
var geometry, group;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 500;
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xffffff, 1, 10000 );
var geometry = new THREE.BoxGeometry( 100, 100, 100 );
var material = new THREE.MeshNormalMaterial();
group = new THREE.Group();
for ( var i = 0; i < 1000; i ++ ) {
var mesh = new THREE.Mesh( geometry, material );
mesh.position.x = Math.random() * 2000 - 1000;
mesh.position.y = Math.random() * 2000 - 1000;
mesh.position.z = Math.random() * 2000 - 1000;
mesh.rotation.x = Math.random() * 2 * Math.PI;
mesh.rotation.y = Math.random() * 2 * Math.PI;
mesh.matrixAutoUpdate = false;
mesh.updateMatrix();
group.add( mesh );
}
scene.add( group );
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0xffffff );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
container.appendChild( renderer.domElement );
stats = new Stats();
container.appendChild( stats.dom );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove(event) {
mouseX = ( event.clientX - windowHalfX ) * 10;
mouseY = ( event.clientY - windowHalfY ) * 10;
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
var time = Date.now() * 0.001;
var rx = Math.sin( time * 0.7 ) * 0.5,
ry = Math.sin( time * 0.3 ) * 0.5,
rz = Math.sin( time * 0.2 ) * 0.5;
camera.position.x += ( mouseX - camera.position.x ) * .05;
camera.position.y += ( - mouseY - camera.position.y ) * .05;
camera.lookAt( scene.position );
group.rotation.x = rx;
group.rotation.y = ry;
group.rotation.z = rz;
renderer.render( scene, camera );
}
</script></body></html>
UPDATE : after doing some research i found Those little cubes are called voxels. I want to upload an image and programmatically create a 3D structure using voxels. I have to create a 3D object from a 2D image. The other thing is to use Javascript to read the data of an image such that can get the color and transparency information of each individual pixel. I can use a canvas to draw the image, and then access the individual pixels to get their colors, so that's one way to read that data. Maybe three.js has a built-in way to do that also.For the 3D object I guess you could just say that white in the image is transparent, and that it's going to have a depth of 5 voxels or whatever. It would still be a flat representation though, just stretched on the Z axis.Still don't know how to combine and make the thing

Three.js same shader with multiple objects different parameters

I'm working with three.js and trying to write a shader to render many spheres with all of the same attributes except their radii. The radii are varying in real time and I'm not sure what the most efficient way to change the radii of the individual spheres.
Here is what I have so far to test. It seems that my uniform variable radius doesn't actually affect the radius of the sphere at all.
<!DOCTYPE html>
<html>
<title>Test Sphere</title>
<head>
</head>
<body>
<div id="test"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
<script type="x-shader/x-vertex" id="vertexShader">
/**
* Multiply each vertex by the
* model-view matrix and the
* projection matrix (both provided
* by Three.js) to get a final
* vertex position
*/
uniform float radius;
void main() {
gl_Position = radius * projectionMatrix *
modelViewMatrix *
vec4(position,1.0);
}
</script>
<script type="x-shader/x-vertex" id="fragmentShader">
/**
* Set the colour to a lovely pink.
* Note that the color is a 4D Float
* Vector, R,G,B and A and each part
* runs from 0.0 to 1.0
*/
void main() {
gl_FragColor = vec4(1.0, // R
0.0, // G
1.0, // B
1.0); // A
}
</script>
<script>
var light;
var material;
var scene, camera;
var puthere = document.getElementById("test");
container = document.createElement( 'div' );
puthere.appendChild( container );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 300;
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight )
container.appendChild( renderer.domElement );
var uniforms = {
radius: { type: "f", value: 10.0 }
};
material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
var geometry = new THREE.SphereGeometry( 1, 32, 32 );
sphere = new THREE.Mesh( geometry, material );
// material.needsUpdate = true;
scene.add( sphere );
scene.add( camera );
renderer.render( scene, camera );
setInterval( function() {
console.log( "here" );
sphere.material.uniforms.radius.value += 10;
renderer.render( scene, camera );
}, 100);
</script>
</body>
</html>

Categories

Resources