Three.js Cannot read property 'uniforms' of undefined - three.js

I completely followed the translucency example(https://threejs.org/examples/?q=tran#webgl_materials_translucency), but i don't know why i failed.
" var uniforms = THREE.UniformsUtils.clone( shader.uniforms );" with this chrome said: Uncaught TypeError: Cannot read property 'uniforms' of undefined.
Please help me ~~~
Just incase i put is all my code here.
<html>
<head>
<meta charset="utf-8">
<title> 1 </title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script type="module">
import * as THREE from './js/three.module.js';
import { OrbitControls } from './js/OrbitControls.js';
import { TranslucentShader } from './js/TranslucentShader.js';
let scene, camera, renderer;
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(70,window.innerWidth/window.innerHeight,1,15000);
camera.position.set(0,500,1000);
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
var loader = new THREE.TextureLoader();
var imgTexture = loader.load( 'white.jpg' );
imgTexture.wrapS = imgTexture.wrapT = THREE.RepeatWrapping;
var shader = THREE.TranslucentShader;
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
uniforms[ 'map' ].value = imgTexture;
uniforms[ 'diffuse' ].value = new THREE.Vector3( 1.0, 0.2, 0.2 );
uniforms[ 'shininess' ].value = 500;
uniforms[ 'thicknessMap' ].value = imgTexture;
uniforms[ 'thicknessColor' ].value = new THREE.Vector3( 0.5, 0.3, 0.0 );
uniforms[ 'thicknessDistortion' ].value = 0.1;
uniforms[ 'thicknessAmbient' ].value = 2;
uniforms[ 'thicknessAttenuation' ].value = 1.2;
uniforms[ 'thicknessPower' ].value = 3.0;
uniforms[ 'thicknessScale' ].value = 10;
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader,
lights: true
} );
material.extensions.derivatives = true;
var geo = new THREE.BoxGeometry(100,100,100);
var cube = new THREE.Mesh(geo,material);
scene.add(cube);
let control = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.PointLight( 0xffffff,1 );
scene.add(light);
}
function animate(){
requestAnimationFrame(animate);
renderer.render(scene,camera);
}
init();
animate();
</script>
</body>
</html>
coding is so hard 😒

When you import { TranslucentShader } at the top of your code, the example shows you have to access it as follows:
var shader = TranslucentShader;
No need to put THREE. in front of it. This is creating a reference to an undefined object.

Related

(Three.js) bloom over not bloom issue

Can someone please a bit change the given example for solve the main issue?
It will help everyone to understand how to properly use scene.traverse and obj.material.dispose in a real simple example (because original example has a bit complex code for dive freely).
How bloom over not bloom should looks: bloomYes.png
But in example it is incorrect: bloomNot.png
Example to see and change
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth/ window.innerHeight, 1, 1000);
camera.position.set(20, 0, -20);
camera.layers.enable(1);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.autoClear = false;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor( 0x000000 );
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, 0.75);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.25));
// not bloomy
var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshLambertMaterial({color: 0xf0f0f0, wireframe: false}));
obj.layers.set(0);
obj.position.z = 0;
scene.add(obj);
var obj = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 1), new THREE.MeshLambertMaterial({color: 0x0000ff, wireframe: false}));
obj.position.z = 2.5;
obj.layers.set(0);
scene.add(obj);
var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshLambertMaterial({color: 0xf0f0f0, wireframe: false}));
obj.layers.set(0);
obj.position.z = 5;
scene.add(obj);
// bloomystuff
var objBloomRed = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
objBloomRed.position.z = -2.25;
objBloomRed.layers.set(1);
scene.add(objBloomRed);
var objBloomGreen = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false}));
objBloomGreen.position.z = 7.5;
objBloomGreen.layers.set(1);
scene.add(objBloomGreen);
// "fake" objects
var objRed = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
objRed.position.z = -2.5;
objRed.layers.set(0);
scene.add(objRed);
var objGreen = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false}));
objGreen.position.z = 7.5;
objGreen.layers.set(0);
scene.add(objGreen);
/** COMPOSER */
renderScene = new THREE.RenderPass( scene, camera )
effectFXAA = new THREE.ShaderPass( THREE.FXAAShader )
effectFXAA.uniforms.resolution.value.set( 1 / window.innerWidth, 1 / window.innerHeight )
bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 )
bloomPass.threshold = 0.21
bloomPass.strength = 1.2
bloomPass.radius = 0.55
bloomPass.renderToScreen = true
composer = new THREE.EffectComposer( renderer )
composer.setSize( window.innerWidth, window.innerHeight )
composer.addPass( renderScene )
composer.addPass( effectFXAA )
composer.addPass( bloomPass )
var delta = 0;
render();
function render(){
requestAnimationFrame(render);
delta += 0.05;
objBloomRed.material.color.g = Math.sin(delta);
objBloomRed.material.color.b = Math.cos(delta);
objRed.material.color.g = Math.sin(delta);
objRed.material.color.b = Math.cos(delta);
renderer.clear();
camera.layers.set(1);
composer.render();
renderer.clearDepth();
camera.layers.set(0);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src='https://threejs.org/examples/js/postprocessing/EffectComposer.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/RenderPass.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/ShaderPass.js'></script>
<script src='https://threejs.org/examples/js/shaders/CopyShader.js'></script>
<script src="https://threejs.org/examples/js/shaders/FXAAShader.js"></script>
<script src="https://threejs.org/examples/js/shaders/LuminosityHighPassShader.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/UnrealBloomPass.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Thank you.
Ok, I am did it as soon as possible. Let all who want, know how to do it! Just look into code how it is possible to solve the "bloom over not-bloom" issue:
var ENTIRE_SCENE = 0, BLOOM_SCENE = 1;
var bloomLayer = new THREE.Layers();
bloomLayer.set( BLOOM_SCENE );
var darkMaterial = new THREE.MeshBasicMaterial( { color: "yellow" } );
var materials = {};
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth/ window.innerHeight, 1, 1000);
camera.position.set(20, 0, -20);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.25));
// setup scene
scene.traverse(disposeMaterial);
scene.children.length = 0;
// not bloomy
var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshBasicMaterial({color: 0x444444, wireframe: false}));
obj.position.z = 0;
obj.layers.enable(ENTIRE_SCENE)
scene.add(obj);
var obj = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 1), new THREE.MeshBasicMaterial({color: 0x0000ff, wireframe: false}));
obj.position.z = 2.5;
obj.layers.enable(ENTIRE_SCENE)
scene.add(obj);
var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshBasicMaterial({color: 0x444444, wireframe: false}));
obj.position.z = 5;
obj.layers.enable(ENTIRE_SCENE)
scene.add(obj);
// bloomystuff
var objBloomRed = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
objBloomRed.position.z = -2.5;
objBloomRed.layers.enable(BLOOM_SCENE)
scene.add(objBloomRed);
var objBloomGreen = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false}));
objBloomGreen.position.z = 7.5;
objBloomGreen.layers.enable(BLOOM_SCENE)
scene.add(objBloomGreen);
window.onresize = function () {
var width = window.innerWidth;
var height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
bloomComposer.setSize(width, height);
finalComposer.setSize(width, height);
render();
};
/** COMPOSER */
renderScene = new THREE.RenderPass( scene, camera )
bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 )
bloomPass.threshold = 0.21
bloomPass.strength = 1.2
bloomPass.radius = 0.55
bloomComposer = new THREE.EffectComposer( renderer )
bloomComposer.setSize( window.innerWidth, window.innerHeight )
bloomComposer.renderToScreen = false;
bloomComposer.addPass( renderScene );
bloomComposer.addPass( bloomPass );
var finalPass = new THREE.ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: {value: null},
bloomTexture: {value: bloomComposer.renderTarget2.texture}
},
vertexShader: vertexshader.textContent,
fragmentShader: fragmentshader.textContent,
defines: {}
}), "baseTexture"
);
finalPass.needsSwap = true;
var finalComposer = new THREE.EffectComposer(renderer);
finalComposer.addPass(renderScene);
finalComposer.addPass(finalPass);
function disposeMaterial(obj) {
if (obj.material) {
obj.material.dispose();
}
}
function renderBloom(mask) {
if (mask === true) {
bloomComposer.render();
} else {
camera.layers.set(BLOOM_SCENE);
bloomComposer.render();
camera.layers.set(ENTIRE_SCENE);
}
}
var delta = 0;
render();
function render(){
requestAnimationFrame(render);
delta += 0.05;
objBloomRed.material.color.g = Math.sin(delta);
objBloomRed.material.color.b = Math.cos(delta);
renderBloom(true);
finalComposer.render();
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src='https://threejs.org/examples/js/postprocessing/EffectComposer.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/RenderPass.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/ShaderPass.js'></script>
<script src='https://threejs.org/examples/js/shaders/CopyShader.js'></script>
<script src="https://threejs.org/examples/js/shaders/FXAAShader.js"></script>
<script src="https://threejs.org/examples/js/shaders/LuminosityHighPassShader.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/UnrealBloomPass.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<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;
vec4 getTexture( sampler2D texelToLinearTexture ) {
return mapTexelToLinear( texture2D( texelToLinearTexture , vUv ) );
}
void main() {
gl_FragColor = ( getTexture( baseTexture ) + vec4( 1.0 ) * getTexture( bloomTexture ) );
}
</script>

Thickness for Tube geometry in THREE.js using concentric tubes

I am trying to apply thickness to THREE.js's Tube geometry. For that I am using two concentric tube geometries and try to combine them to create a thickness.
Please find the below code for the same.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - geometry - Tube</title>
<meta charset="utf-8">
<style>
body {
margin: 0px;
background-color: #2c3134;
overflow: hidden;
}
</style>
</head>
<body>
<script src="./three.min.js"></script>
<script src="./TrackballControls.js"></script>
<script>
var camera, scene, renderer;
var mesh,cameraControls;
var clock = new THREE.Clock();
var outerradius = 75;
var innerradius = 55;
var segments = 600;
var radiussegments = 360;
var tubecolor = new THREE.Color(0x848484);
var wireframe = true;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
camera = new THREE.PerspectiveCamera( 25, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 0, 1000 );
scene = new THREE.Scene();
var tubepath1 = [{"point" :new THREE.Vector3(-200,0,0)},{"point" :new THREE.Vector3(200,0,0)}];
var actualpoints =[];
for(var i=0; i<tubepath1.length; i++)
{
actualpoints.push(tubepath1[i].point);
}
var actualextrudePath = new THREE.SplineCurve3(actualpoints);
actualextrudePath.dynamic = true;
var outertube = new THREE.TubeGeometry(actualextrudePath, segments,outerradius ,radiussegments, false, false);
outertube.dynamic = true;
outertube.verticesNeedUpdate = true;
outertube.dynamic = true;
var outertubeMesh = new THREE.Mesh(outertube, new THREE.MeshBasicMaterial(
{ color: tubecolor, shading: THREE.SmoothShading, side: THREE.DoubleSide, wireframe: wireframe, transparent: true,vertexColors: THREE.FaceColors, overdraw: false
}));
outertubeMesh.name = "outertube";
outertubeMesh.dynamic = true;
outertubeMesh.needsUpdate = true;
outertubeMesh.useQuaternion = true;
renderer.sortObjects = false;
var innertube = new THREE.TubeGeometry(actualextrudePath, segments,innerradius ,radiussegments, false, false);
innertube.dynamic = true;
innertube.verticesNeedUpdate = true;
innertube.dynamic = true;
var innertubeMesh = new THREE.Mesh(innertube, new THREE.MeshBasicMaterial(
{ color: tubecolor, shading: THREE.SmoothShading, side: THREE.DoubleSide, wireframe: wireframe, transparent: true,vertexColors: THREE.FaceColors, overdraw: false
}));
innertubeMesh.name = "innertube";
innertubeMesh.dynamic = true;
innertubeMesh.needsUpdate = true;
innertubeMesh.useQuaternion = true;
renderer.sortObjects = false;
// CONTROLS
cameraControls = new THREE.TrackballControls(camera);
cameraControls.rotateSpeed = 1.0;
cameraControls.zoomSpeed = 1.2;
cameraControls.panSpeed = 0.8;
cameraControls.noZoom = false;
cameraControls.noPan = false;
cameraControls.staticMoving = true;
cameraControls.dynamicDampingFactor = 0.3;
cameraControls.target.set(0,0,0);
scene.add( outertubeMesh );
scene.add( innertubeMesh );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
window.requestAnimationFrame(animate);
render();
}
function render() {
var delta = clock.getDelta();
cameraControls.update(delta);
renderer.render(scene, camera);
}
</script>
</body>
</html>
Now, how to combine these two tubes so that i don't have allow gap in between the tubes.
Any help is appreciated.
Thanks in advance,
Pradeep
The easiest way is adding 2 geometry that create the endings like in
http://jsfiddle.net/gero3/rMaz5/1/
var first = new THREE.Geometry()
for (i = 0; i < radiussegments;i++){
var j = i;
var k= i*6;
first.vertices.push(outertube.vertices[j+0].clone());
first.vertices.push(outertube.vertices[j+1].clone());
first.vertices.push(innertube.vertices[j+0].clone());
first.faces.push( new THREE.Face3( k+0, k+1, k+2 ) );
first.vertices.push(innertube.vertices[j+0].clone());
first.vertices.push(innertube.vertices[j+1].clone());
first.vertices.push(outertube.vertices[j+1].clone());
first.faces.push( new THREE.Face3( k+3, k+4, k+5 ) );
};
first.mergeVertices()
var firstMesh = new THREE.Mesh(first, new THREE.MeshBasicMaterial(
{ color: endtubecolor, shading: THREE.SmoothShading, side: THREE.DoubleSide, wireframe: wireframe, transparent: true,vertexColors: THREE.FaceColors, overdraw: false}));
var second = new THREE.Geometry()
for (i = 0; i < radiussegments;i++){
var j = i;
var k= i*6;
second.vertices.push(outertube.vertices[outertube.vertices.length-2-j+0].clone());
second.vertices.push(outertube.vertices[outertube.vertices.length-2-j+1].clone());
second.vertices.push(innertube.vertices[outertube.vertices.length-2-j+0].clone());
second.faces.push( new THREE.Face3( k+0, k+1, k+2 ) );
second.vertices.push(innertube.vertices[outertube.vertices.length-2-j+0].clone());
second.vertices.push(innertube.vertices[outertube.vertices.length-2-j+1].clone());
second.vertices.push(outertube.vertices[outertube.vertices.length-2-j+1].clone());
second.faces.push( new THREE.Face3( k+3, k+4, k+5 ) );
};
second.mergeVertices()
var secondMesh = new THREE.Mesh(second, new THREE.MeshBasicMaterial(
{ color: endtubecolor, shading: THREE.SmoothShading, side: THREE.DoubleSide, wireframe: wireframe, transparent: true,vertexColors: THREE.FaceColors, overdraw: false}));

three.js set background image

How to create a static background image?
For default background:
scene = new THREE.Scene();
// ...
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setClearColor( scene.fog.color, 1 );
How to set a image for scene.fog, or set opacity for clearcolor?
If you are trying to set a static background image (even if you rotate your main camera, the background doesn't change), you have to create 2 scenes and 2 cameras.
The first scene will be composed of a basic plane on which a texture is applied.
The second scene will have all your objects.
Here is a code that would do it :
<html>
<body>
<script src="Three.js"></script>
<script>
var color = 0x000000;
// Create your main scene
var scene = new THREE.Scene();
// Create your main camera
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// Create lights
var light = new THREE.PointLight(0xEEEEEE);
light.position.set(20, 0, 20);
scene.add(light);
var lightAmb = new THREE.AmbientLight(0x777777);
scene.add(lightAmb);
// Create your renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Create a cube
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshLambertMaterial({
color: 0xff00ff,
ambient: 0x121212,
emissive: 0x121212
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// Set up the main camera
camera.position.z = 5;
// Load the background texture
var texture = THREE.ImageUtils.loadTexture( '1.jpg' );
var backgroundMesh = new THREE.Mesh(
new THREE.PlaneGeometry(2, 2, 0),
new THREE.MeshBasicMaterial({
map: texture
}));
backgroundMesh .material.depthTest = false;
backgroundMesh .material.depthWrite = false;
// Create your background scene
var backgroundScene = new THREE.Scene();
var backgroundCamera = new THREE.Camera();
backgroundScene .add(backgroundCamera );
backgroundScene .add(backgroundMesh );
// Rendering function
var render = function () {
requestAnimationFrame(render);
// Update the color to set
if (color < 0xdddddd) color += 0x0000ff;
// Update the cube color
cube.material.color.setHex(color);
// Update the cube rotations
cube.rotation.x += 0.05;
cube.rotation.y += 0.02;
renderer.autoClear = false;
renderer.clear();
renderer.render(backgroundScene , backgroundCamera );
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>
**Demo right here **
Hope this helps.
NOTE (2014/06/28): This code works with the latest release of Three.js: R67
Use Texture loader to load a any image as texture and then apply that to scene like this:
//Load background texture
const loader = new THREE.TextureLoader();
loader.load('https://images.pexels.com/photos/1205301/pexels-photo-1205301.jpeg' , function(texture)
{
scene.background = texture;
});
Result:
Demo:
See the Pen Flat Earth Three.JS by Hitesh Sahu (#hiteshsahu) on CodePen.
this run:
renderer = new THREE.WebGLRenderer({ antialias: false,alpha:true });
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor(0x000000, 0);
An background image can be set by setting the scene.background attribute of the THREE.Scene:
scene = new THREE.Scene();
bgTexture = loader.load("https://i.stack.imgur.com/vDUZz.jpg",
function ( texture ) {
var img = texture.image;
bgWidth= img.width;
bgHeight = img.height;
resize();
} );
scene.background = bgTexture;
bgTexture.wrapS = THREE.MirroredRepeatWrapping;
bgTexture.wrapT = THREE.MirroredRepeatWrapping;
The aspect ratio of the image can be adjusted to the aspect ratio of the canvas like this:
var aspect = window.innerWidth / window.innerHeight;
var texAspect = bgWidth / bgHeight;
var relAspect = aspect / texAspect;
bgTexture.repeat = new THREE.Vector2(
Math.max(relAspect, 1),
Math.max(1/relAspect,1) );
bgTexture.offset = new THREE.Vector2(
-Math.max(relAspect-1, 0)/2,
-Math.max(1/relAspect-1, 0)/2 );
See the code snippet:
(function onLoad() {
var container, loader, camera, scene, renderer, controls, bgTexture, bgWidth, bgHeight;
init();
animate();
function init() {
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(0, -4, -1.5);
loader = new THREE.TextureLoader();
loader.setCrossOrigin("");
scene = new THREE.Scene();
bgTexture = loader.load("https://raw.githubusercontent.com/Rabbid76/graphics-snippets/master/resource/texture/background.jpg",
function ( texture ) {
var img = texture.image;
bgWidth= img.width;
bgHeight = img.height;
resize();
}
);
scene.background = bgTexture;
bgTexture.wrapS = THREE.MirroredRepeatWrapping;
bgTexture.wrapT = THREE.MirroredRepeatWrapping;
scene.add(camera);
window.onresize = resize;
var ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.x = -0.75;
directionalLight.position.y = -0.5;
directionalLight.position.z = -1;
scene.add( directionalLight );
controls = new THREE.OrbitControls(camera, renderer.domElement);
createModel();
}
function createModel() {
var material = new THREE.MeshPhongMaterial({color:'#b090b0'});
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
function resize() {
var aspect = window.innerWidth / window.innerHeight;
var texAspect = bgWidth / bgHeight;
var relAspect = aspect / texAspect;
bgTexture.repeat = new THREE.Vector2( Math.max(relAspect, 1), Math.max(1/relAspect,1) );
bgTexture.offset = new THREE.Vector2( -Math.max(relAspect-1, 0)/2, -Math.max(1/relAspect-1, 0)/2 );
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
})();
<script src="https://threejs.org/build/three.min.js"></script>
<!--script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script-->
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="container"></div>
thank you ))
I found yet another solution:
<!DOCTYPE html>
<head>
<title>three.js webgl - orbit controls</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #000;
font-family:Monospace;
font-size:13px;
text-align:center;
font-weight: bold;
background-image:url(./foto.jpg);
margin: 0px;
overflow: hidden;
}
#info {
color:#000;
position: absolute;
top: 0px; width: 100%;
padding: 5px;
}
a {
color: red;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
three.js
</div>
<script src="./three.min.js"></script>
<script src="js/loaders/OBJLoader.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<!--ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ для Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ fps-->
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer;
var cross;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 90, window.innerWidth / window.innerHeight, 0.1, 2000 );
camera.position.z = 100;
controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'change', render );
scene = new THREE.Scene();
var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
var texture = new THREE.Texture();
var loader = new THREE.ImageLoader( manager );
loader.load( './kos.jpg', function ( image ) {
texture.image = image;
texture.needsUpdate = true;
} );
// model
var loader = new THREE.OBJLoader( manager );
loader.load( './skull.obj', function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material.map = texture;
}
} );
object.position.y = 10;
scene.add( object );
} );
// lights
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 1, 1 );
scene.add( light );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( -1, -1, -1 );
scene.add( light );
light = new THREE.AmbientLight( 0xffffff );
scene.add( light );
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
container = document.getElementById( 'container' );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
render();
}
function animate() {
requestAnimationFrame( animate );
controls.update();
}
function render() {
renderer.render( scene, camera );
stats.update();
}
</script>
</body>
It seems rather late in the day to be adding any contribution to this thread but here is my 'hap'orth':
<head>
<meta charset=utf-8>
<title>Temple7</title>
<style>
body { margin: 0;
}
canvas { width: 100%; height: 100%;
background-image:url(Clouds.jpg);
}
</style>
</head>
This rather simplistic approach has its limitations. The .jpg image retains its pixel dimensions so that, for different sizes of the browser window one sees different amounts of the image. If the canvas size exceeds the size of the .jpg, then tiling occurs.

ThreeJS object material showing blank

Below code renders the earth as BLACK globe. please note im a beginner in WebGL, also below 'Uniforms' & parameters section I found in someones code and utilized it.
If I add normal material it works, but with Shader it does not work.
Script links:
https://threejsdoc.appspot.com/doc/three.js/examples/js/ShaderExtras.js
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript" src="js/ShaderExtras.js"></script>
//Earth
var earthTexture = THREE.ImageUtils.loadTexture( "img/planets/earth_atmos_2048.jpg" );
var earthCloudsTexture = THREE.ImageUtils.loadTexture( "img/planets/earth_clouds_1024.png" );
var earthNormalTexture = THREE.ImageUtils.loadTexture( "img/planets/earth_normal_2048.jpg" );
var earthSpecularTexture = THREE.ImageUtils.loadTexture( "img/planets/earth_specular_2048.jpg" );
var earthShader = THREE.ShaderUtils.lib[ "normal" ];
var earthUniforms = THREE.UniformsUtils.clone( earthShader.uniforms );
earthUniforms[ "tNormal" ].texture = earthNormalTexture;
earthUniforms[ "uNormalScale" ].value = 0.85;
earthUniforms[ "tDiffuse" ].texture = earthNormalTexture;
earthUniforms[ "tSpecular" ].texture = earthSpecularTexture;
earthUniforms[ "enableAO" ].value = false;
earthUniforms[ "enableDiffuse" ].value = true;
earthUniforms[ "enableSpecular" ].value = true;
earthUniforms[ "uDiffuseColor" ].value.setHex( 0xffffff );
earthUniforms[ "uSpecularColor" ].value.setHex( 0x333333 );
earthUniforms[ "uAmbientColor" ].value.setHex( 0x000000 );
earthUniforms[ "uShininess" ].value = 15;
var earthParameters = {
fragmentShader: earthShader.fragmentShader,
vertexShader: earthShader.vertexShader,
uniforms: earthUniforms,
lights: true,
fog: true
};
var earth_mat = new THREE.ShaderMaterial( earthParameters );
var earth_geom = new THREE.SphereGeometry( 200, 32, 32 );
earth_geom.computeTangents();
var earth = new THREE.Mesh( earth_geom, earth_mat );
earth.position.x = 6000;
scene.add( earth );

Can't send a texture to a custom shader (ShaderPass/EffectComposer)

I'm currently playing with this great library, but I have some difficulties with the EffectComposer.
I can't send a texture to a postprocess shader introduced by a ShaderPass.
I think this is a bug... or I'm doing something stupid (needUpDate, warp,... ??)
(r54, W7, Nv9700mGT, FF 17.0.1 and Chrome 24.0.1312.52)
I used the "webgl_postprocessing.html" example to reproduce the phenomenon just by adding these shaders :
<script id="vertexShaderBasic" type="x-shader/x-vertex">
varying vec2 glTexCoord;
void main() {
glTexCoord = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fragmentShaderBlender" type="x-shader/x-fragment">
varying vec2 glTexCoord;
uniform sampler2D sprite1;
uniform sampler2D previousRender;
void main() {
vec3 color = texture2D( previousRender, glTexCoord ).rgb;
color += texture2D( sprite1, glTexCoord ).rgb;
gl_FragColor.rgb = color;
gl_FragColor.a = 1.0;
}
</script>
this at the begining of the main script to be sure the sprite is loaded :
var composer2;
function start() {
init();
animate();
}
var sprite1 = THREE.ImageUtils.loadTexture( "textures/sprite1.jpg", null, start );
this in the composer field, after :
composer.addPass( new THREE.RenderPass( scene, camera ) );
composer2 = new THREE.EffectComposer( renderer );
var uniforms1 = {
sprite1: { type: "t", value: sprite1 }, // <- something wrong here
previousRender: { type: "t", value: null }
};
var blenderShader = {
uniforms: uniforms1,
vertexShader: $( 'vertexShaderBasic' ).textContent,
fragmentShader: $( 'fragmentShaderBlender' ).textContent
};
// link with the previous render
blenderShader.uniforms.previousRender.value = composer.renderTarget2;
// the custom shader
var blenderPass = new THREE.ShaderPass( blenderShader );
blenderPass.renderToScreen = true;
composer2.addPass( blenderPass );
I also coment this, beacause it's not relevent any more :
//effect.renderToScreen = true;
and I add this at the end :
composer2.render();
The link between the two passes work well, but the sprite never appear on the EffectComposer quad that cover the screen...
Thanks and sorry for my english.
EDIT to recap :
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - postprocessing</title>
<meta charset="utf-8">
<style>
body {
margin: 0px;
background-color: #000000;
overflow: hidden;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/shaders/DotScreenShader.js"></script>
<script src="js/shaders/RGBShiftShader.js"></script>
<script src="js/postprocessing/EffectComposer.js"></script>
<script src="js/postprocessing/RenderPass.js"></script>
<script src="js/postprocessing/MaskPass.js"></script>
<script src="js/postprocessing/ShaderPass.js"></script>
<script id="vertexShaderBasic" type="x-shader/x-vertex">
varying vec2 glTexCoord;
void main() {
glTexCoord = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fragmentShaderBlender" type="x-shader/x-fragment">
varying vec2 glTexCoord;
uniform sampler2D sprite1;
uniform sampler2D previousRender;
void main() {
vec3 color = texture2D( previousRender, glTexCoord ).rgb;
color += texture2D( sprite1, glTexCoord ).rgb;
gl_FragColor.rgb = color;
gl_FragColor.a = 1.0;
}
</script>
<script>
var camera, scene, renderer, composer;
var composer2;
var object, light;
function start() {
init();
animate();
}
var sprite1 = THREE.ImageUtils.loadTexture( "textures/sprite1.jpg", null, start );
//var sprite1 = THREE.ImageUtils.loadTexture( "textures/sprite1.jpg", new THREE.UVMapping(), start ); // change anything
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 400;
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0x000000, 1, 1000 );
object = new THREE.Object3D();
scene.add( object );
var geometry = new THREE.SphereGeometry( 1, 4, 4 );
var material = new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading } );
for ( var i = 0; i < 100; i ++ ) {
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5 ).normalize();
mesh.position.multiplyScalar( Math.random() * 400 );
mesh.rotation.set( Math.random() * 2, Math.random() * 2, Math.random() * 2 );
mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 50;
object.add( mesh );
}
scene.add( new THREE.AmbientLight( 0x222222 ) );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 1, 1 );
scene.add( light );
// postprocessing
composer = new THREE.EffectComposer( renderer );
composer.addPass( new THREE.RenderPass( scene, camera ) );
/////////////////////////////////////
/////////////////////////////////////
composer2 = new THREE.EffectComposer( renderer );
var uniforms1 = {
sprite1: { type: "t", value: sprite1 },
previousRender: { type: "t", value: null }
};
//uniforms1.sprite1.value.wrapS = uniforms1.sprite1.value.wrapT = THREE.RepeatWrapping;
var blenderShader = {
uniforms: uniforms1,
vertexShader: $( 'vertexShaderBasic' ).textContent,
fragmentShader: $( 'fragmentShaderBlender' ).textContent
};
blenderShader.uniforms.previousRender.value = composer.renderTarget2;
var blenderPass = new THREE.ShaderPass( blenderShader );
blenderPass.renderToScreen = true;
composer2.addPass( blenderPass );
/////////////////////////////////////
/////////////////////////////////////
var effect = new THREE.ShaderPass( THREE.DotScreenShader );
effect.uniforms[ 'scale' ].value = 4;
composer.addPass( effect );
var effect = new THREE.ShaderPass( THREE.RGBShiftShader );
effect.uniforms[ 'amount' ].value = 0.0015;
//effect.renderToScreen = true;
composer.addPass( effect );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function $( id ) {
return document.getElementById( id );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
var time = Date.now();
object.rotation.x += 0.005;
object.rotation.y += 0.01;
composer.render();
composer2.render();
}
</script>
</body>
</html>
What I want :
Good
What I get :
NotGood
I had this issue too, and found a workaround.
I debugged it to determine that the texture ID for the extra texture is different in the shader pass than expected, which is bad. If you look in the ShaderPass constructor, you'll see it clones the uniforms. That seems to be the cause. If I edit that code to restore the original texture object in the cloned uniforms, it works as expected. So that should work for you too.
I'm trying to get some kind of (proper) bug fix integrated into the actual release.
Try this
var sprite1 = THREE.ImageUtils.loadTexture( "textures/sprite1.jpg", new THREE.UVMapping(), start );
three.js r.54

Resources