How can I map a texture image onto a shader geometry? - javascript

I have 2 scenes, in one of them I have mapped a texture image to a plane geometry and I have simply rendered it, in the other scene I have a cube with shader material, now I want the image texure shown in hte first scene to be mapped to the cube surface, but I dont know how can I do it, can anyone help?
actually there is not enough documentation on what I want to do and I am somehow new to three.js so I have no idea what should I do in my HTML file's vertex and fragment shaders, only have done what I mentioned earlir.
here are my texture image and plane geometry in the first scene and the cube in the other, and also my fragment and vertex shader:
this.vertShader = document.getElementById('vertexShader').innerHTML;
this.fragShader = document.getElementById('fragmentShader').innerHTML;
var geometry = new THREE.BoxGeometry( 0.5, 0.5 );
var material = new THREE.MeshLambertMaterial( { color: "blue", wireframe:
true} );
this.mesh = new THREE.Mesh( geometry, material );
this.scene.add( this.mesh );
var texture = new THREE.TextureLoader().load ('js/textures/earth.jpg');
var texMaterial = new THREE.MeshBasicMaterial( { map: texture } );
var texGeometry = new THREE.PlaneGeometry(1, 1);
this.texmesh = new THREE.Mesh(texGeometry, texMaterial);
this.texmesh.position.set(0,0,0);
this.texScene.add(this.texmesh);
vertex shader:
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix *
vec4(position,1.0);
}
fragment shader:
uniform sampler2D texture;
varying vec2 vUv;
void main() {
gl_FragColor = texture2D(texture, vUv);
}
I woud like the cube to be covered with the texture image.

In the fragment shader has to be declared a uniform variable of type sampler2D:
Vertex Shader:
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
Fragment Shader:
precision highp float;
uniform sampler2D u_texture; // <---------------------------------- texture sampler uniform
varying vec2 vUv;
void main(){
gl_FragColor = texture2D(u_texture, vUv);
}
With the shaders a THREE.ShaderMaterial can be created.
First load the texture:
var texture = new THREE.TextureLoader().load ('js/textures/earth.jpg');
Then specify the set of Uniforms (in this case there is the texture uniform only):
var uniforms = {
u_texture: {type: 't', value: texture}
};
Finally create the material:
var material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: document.getElementById('vertex-shader').textContent,
fragmentShader: document.getElementById('fragment-shader').textContent
});
The material can be used in the same manner as any other material, see the example:
(function onLoad() {
var loader, camera, scene, renderer, orbitControls;
init();
animate();
function createModel() {
var texture = new THREE.TextureLoader().load( 'https://raw.githubusercontent.com/Rabbid76/graphics-snippets/master/resource/texture/Gominolas.png' );
var uniforms = {
u_texture: {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.BoxGeometry( 1, 1, 1 );
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
function init() {
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(0, 1, -2);
loader = new THREE.TextureLoader();
loader.setCrossOrigin("");
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
scene.add(camera);
window.onresize = resize;
orbitControls = new THREE.OrbitControls(camera);
addGridHelper();
createModel();
}
function addGridHelper() {
var helper = new THREE.GridHelper(100, 100);
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
var axis = new THREE.AxesHelper(1000);
scene.add(axis);
}
function resize() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame(animate);
orbitControls.update();
render();
}
function render() {
renderer.render(scene, camera);
}
})();
<script type='x-shader/x-vertex' id='vertex-shader'>
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<script type='x-shader/x-fragment' id='fragment-shader'>
precision highp float;
uniform sampler2D u_texture;
varying vec2 vUv;
void main(){
gl_FragColor = texture2D(u_texture, vUv);
}
</script>
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

Related

How to apply HemisphereLight to ShaderMaterial?

I want to add HemisphereLight to light an object which is built with ShaderMaterial. But when I simply add the light to the screen, the object doesn't seem to be affected. In fact, I've tried with all the other lights and no one light is affecting the object. What do I have to set to make the object affected by the lights?
<script src="https://threejs.org/build/three.js"></script>
<script type="module">
var clock = new THREE.Clock()
function main() {
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 200, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var vShader = `
precision mediump float;
uniform float uTime;
void main() {
float z = 0.1*cos(uTime) * cos(position.y*40. - uTime) * position.y*sin(log(position.y))*0.5 + 0.5;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position.x, position.y, z, 1.0);
}
`
var fShader = `
precision mediump float;
uniform vec2 uRes;
void main() {
vec2 uv = 1.5*gl_FragCoord.xy/uRes;
gl_FragColor = vec4(uv.x, uv.y, 0.0, 1.0);
}
// `
var planeG = new THREE.PlaneGeometry(25, 60, 20, 20);
var planeM = new THREE.ShaderMaterial({
uniforms: {
//ambientLightColor: 0xffffff,
uTime: {
type:"f",
value:0.0,
},
uRes: {
type:"f",
value:new THREE.Vector2(window.innerWidth, window.innerHeight),
}
},
// wireframe:true,
//lights:true,
vertexShader:vShader,
fragmentShader:fShader,
side:THREE.DoubleSide,
});
var plane = new THREE.Mesh( planeG, planeM );
var light = new THREE.HemisphereLight(0xffffff, 0x000000, 2);
//var light = new THREE.AmbientLight(0xFFFFFF, 1.0)
scene.add(light);
scene.add(plane);
plane.rotateZ(Math.PI/2)
camera.position.z = 4;
scene.background = new THREE.Color(0xfffffff);
var render = function (time) {
requestAnimationFrame( render );
plane.material.uniforms.uTime.value = time/100;
renderer.render(scene, camera);
};
render();
};
main()
</script>
ShaderMaterial does not respond to lights because you're manually telling the shader what color to output when you assign values to gl_FragColor in the fragment shader. You're overriding the default behavior of materials, so all things like, position, rotation, color are up to you to control.
If you want a hemisphere light to affect your shader, then you'd have to manually write those calculations in GLSL, which is a pretty complex process. You'd have to feed the colors of the light as uniforms, then you'll have to figure out which triangles are facing up and down so they "reflect" those light colors accordingly.
Three.js has all its material shaders broken down throughout several files in "ShaderChunks", so it's pretty difficult to track down exactly where each step takes place.

Generate particle with 3 shades of the same color Three

Hello I have searched the internet but I have not found anything on, I am trying to make 1 globe in the form of particles with the mix of 3 colors pink, dark pink and white equal to that image down
I need the colors to look like this picture, normal pink, dark pink and whit
the problem is that my Globe is left with 1 single color instead of varios like the image, all help is grateful, thank you all at once
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth /
window.innerHeight, 1, 1000);
camera.position.z = 10;
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0x2675AD);
renderer.setSize(window.innerWidth, window.innerHeight);
var globe = document.getElementById('globe')
globe.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var geom = new THREE.SphereBufferGeometry(5, 320, 160);
var colors = [];
var color = new THREE.Color();
var q = 0xC83C84;
for (let i = 0; i < geom.attributes.position.count; i++) {
color.set(Math.random() * q);
color.toArray(colors, i * 3);
}
geom.addAttribute('color', new THREE.BufferAttribute(new
Float32Array(colors), 3));
var loader = new THREE.TextureLoader();
loader.setCrossOrigin('');
var texture = loader.load('../img/equirectangle_projection.png');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(1, 1);
var disk = loader.load('../img/circleround.png');
var points = new THREE.Points(geom, new THREE.ShaderMaterial({
vertexColors: THREE.VertexColors,
uniforms: {
visibility: {
value: texture
},
shift: {
value: 0
},
shape: {
value: disk
},
size: {
value: 0.125
},
scale: {
value: window.innerHeight / 2
}
},
vertexShader: `
uniform float scale;
uniform float size;
varying vec2 vUv;
varying vec3 vColor;
void main() {
vUv = uv;
vColor = color;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = size * ( scale / length( mvPosition.xyz ) );
gl_Position = projectionMatrix * mvPosition;
}
`,
fragmentShader: `
uniform sampler2D visibility;
uniform float shift;
uniform sampler2D shape;
varying vec2 vUv;
varying vec3 vColor;
void main() {
vec2 uv = vUv;
uv.x += shift;
vec4 v = texture2D(visibility, uv);
if (length(v.rgb) > 1.0) discard;
gl_FragColor = vec4( vColor, 1.0 );
vec4 shapeData = texture2D( shape, gl_PointCoord );
if (shapeData.a < 0.5) discard;
gl_FragColor = gl_FragColor * shapeData;
}
`,
transparent: true
}));
scene.add(points);
var blackGlobe = new THREE.Mesh(geom, new
THREE.MeshBasicMaterial({
color: 0x2675AD
}));
blackGlobe.scale.setScalar(0.99);
points.add(blackGlobe);
var clock = new THREE.Clock();
var time = 0;
render();
function render() {
requestAnimationFrame(render);
time += clock.getDelta();
points.rotation.y += 0.0009
renderer.render(scene, camera);
}
You can use an array of colour values and pick those values randomly:
var q = ["white", "pink", 0xb2497d, "gray"];
for (let i = 0; i < geom.attributes.position.count; i++) {
color.set(q[THREE.Math.randInt(0,3)]);
color.toArray(colors, i * 3);
}
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(1.25, 7, 7);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0x080808);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var geom = new THREE.SphereBufferGeometry(5, 120, 60);
var colors = [];
var color = new THREE.Color();
var q = ["white", "pink", 0xb2497d, "gray"];
for (let i = 0; i < geom.attributes.position.count; i++) {
color.set(q[THREE.Math.randInt(0,3)]);
color.toArray(colors, i * 3);
}
geom.addAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3));
var loader = new THREE.TextureLoader();
loader.setCrossOrigin('');
var texture = loader.load('http://learningthreejs.com/data/2013-09-16-how-to-make-the-earth-in-webgl/demo/bower_components/threex.planets/images/earthspec1k.jpg');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(1, 1);
var disk = loader.load('https://threejs.org/examples/textures/sprites/circle.png');
var points = new THREE.Points(geom, new THREE.ShaderMaterial({
vertexColors: THREE.VertexColors,
uniforms: {
visibility: {
value: texture
},
shift: {
value: 0
},
shape: {
value: disk
},
size: {
value: 0.125
},
scale: {
value: window.innerHeight / 2
}
},
vertexShader: `
uniform float scale;
uniform float size;
varying vec2 vUv;
varying vec3 vColor;
void main() {
vUv = uv;
vColor = color;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = size * ( scale / length( mvPosition.xyz ) );
gl_Position = projectionMatrix * mvPosition;
}
`,
fragmentShader: `
uniform sampler2D visibility;
uniform float shift;
uniform sampler2D shape;
varying vec2 vUv;
varying vec3 vColor;
void main() {
vec2 uv = vUv;
uv.x += shift;
vec4 v = texture2D(visibility, uv);
if (length(v.rgb) > 1.0) discard;
gl_FragColor = vec4( vColor, 1.0 );
vec4 shapeData = texture2D( shape, gl_PointCoord );
if (shapeData.a < 0.5) discard;
gl_FragColor = gl_FragColor * shapeData;
}
`,
transparent: true
}));
scene.add(points);
var blackGlobe = new THREE.Mesh(geom, new THREE.MeshBasicMaterial({
color: 0x000000
}));
blackGlobe.scale.setScalar(0.99);
points.add(blackGlobe);
var clock = new THREE.Clock();
var time = 0;
render();
function render() {
requestAnimationFrame(render);
time += clock.getDelta();
points.material.uniforms.shift.value = time * 0.1;
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

Three.js envmaps and vertex animation

I am making my first steps coding with JavaScript and playing with Three.js.
I am learning how to use Shaders and I have a week stuck with a vertex animation that doesn't work.
This one is my Vertex Shader:
uniform float fresnelBias;
uniform float amplitude;
uniform float fresnelScale;
uniform float fresnelPower;
attribute float displacement;
varying float vReflectionFactor;
varying vec3 vReflect;
void main() {
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
vec3 I = worldPosition.xyz - cameraPosition;
vReflect = reflect( I, worldNormal );
vReflectionFactor = fresnelBias + fresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), fresnelPower );
gl_Position = projectionMatrix * mvPosition;
}
and this one is Fragment Shader:
uniform vec3 color;
uniform samplerCube envMap;
varying vec3 vReflect;
varying float vReflectionFactor;
void main() {
vec4 envColor = textureCube( envMap, vec3( -vReflect.x, vReflect.yz ) );
gl_FragColor = vec4(mix(color, envColor.xyz, vec3(clamp( vReflectionFactor, 0.0, 1.0 ))), 1.0);
}
Then I declared a variable to my attributes and another to my uniforms to assign it to a geometry but when I load the site I don't see anything. The JavaScript console tells that in this line uniforms.amplitude.value = Math.sin(frame); uniforms is not defined.
Do you have some recomendation? Do you know something that I can do?
I let here my complete code I hope it could help:
<script id="vertexShader" type="x-shader/x-vertex">
uniform float fresnelBias;
uniform float amplitude;
uniform float fresnelScale;
uniform float fresnelPower;
attribute float displacement;
varying float vReflectionFactor;
varying vec3 vReflect;
void main() {
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
vec3 I = worldPosition.xyz - cameraPosition;
vReflect = reflect( I, worldNormal );
vReflectionFactor = fresnelBias + fresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), fresnelPower );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec3 color;
uniform samplerCube envMap;
varying vec3 vReflect;
varying float vReflectionFactor;
void main() {
vec4 envColor = textureCube( envMap, vec3( -vReflect.x, vReflect.yz ) );
gl_FragColor = vec4(mix(color, envColor.xyz, vec3(clamp( vReflectionFactor, 0.0, 1.0 ))), 1.0);
}
</script>
<script>
var camera, scene, renderer;
var mesh, material, controls, sky;
init();
animate();
function init(){
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setClearColor(0xfffff, 0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 400;
//controls = new THREE.TrackballControls( camera );
scene = new THREE.Scene();
var numberOfImages = 46, images = [];
for (var i = 1; i <= numberOfImages; i++) {
images.push('sources/instagram2/image' + i + ".jpg");
}
var urls = images.sort(function(){return .6 - Math.random()}).slice(0,6);
var textureCube = THREE.ImageUtils.loadTextureCube( urls );
// Skybox
var skyshader = THREE.ShaderLib[ "cube" ];
skyshader.uniforms[ "tCube" ].value = textureCube;
var skymaterial = new THREE.ShaderMaterial( {
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
uniforms: skyshader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
sky = new THREE.Mesh( new THREE.BoxGeometry( 1500, 1500, 1500 ), skymaterial );
sky.visible = false;
scene.add( sky );
var attributes = {
displacement: {
type: 'f', // a float
value: [] // an empty array
}
};
var uniforms = {
color: {
type: "c",
value: new THREE.Color(0x000000),
},
envMap: {
type: "t",
value: textureCube
},
fresnelBias: {
type: "f",
value: 0.1
},
fresnelScale: {
type: "f",
value: 1.0
},
fresnelPower: {
type: 'f',
value: 2.0
},
amplitude: {
type: 'f',
value: 0
}
};
var vertexShader = document.getElementById('vertexShader').text;
var fragmentShader = document.getElementById('fragmentShader').text;
material = new THREE.ShaderMaterial(
{
uniforms : uniforms,
vertexShader : vertexShader,
fragmentShader : fragmentShader,
});
var loader = new THREE.BinaryLoader();
loader.load( "sources/obj/mmlogo/mm_logo.js", function ( geometry ) {
mesh = new THREE.Mesh(geometry, material);
mesh.scale.set( 300, 300, 300 );
var vertices = mesh.geometry.vertices;
var values = attributes.displacement.value
for(var v = 0; v < vertices.length; v++) {
values.push(Math.random() * 10);
}
scene.add(mesh);
} );
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
var frame = 0;
function animate() {
uniforms.amplitude.value = Math.sin(frame);
frame += 0.01;
requestAnimationFrame(animate);
//controls.update();
//mesh.rotation.x += 0.005;
//mesh.rotation.y += 0.005;
renderer.render(scene, camera);
stats.update();
}
Update:
I Added the uniforms variable to the global scope and now the console doesn't show me any problem but I can't see the vertex animation:
<script id="vertexShader" type="x-shader/x-vertex">
uniform float fresnelBias;
uniform float amplitude;
uniform float fresnelScale;
uniform float fresnelPower;
attribute float displacement;
varying float vReflectionFactor;
varying vec3 vReflect;
void main() {
vec3 newPosition = position + normal * vec3(displacement * amplitude);
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
vec3 I = worldPosition.xyz - cameraPosition;
vReflect = reflect( I, worldNormal );
vReflectionFactor = fresnelBias + fresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), fresnelPower );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec3 color;
uniform samplerCube envMap;
varying vec3 vReflect;
varying float vReflectionFactor;
void main() {
vec4 envColor = textureCube( envMap, vec3( -vReflect.x, vReflect.yz ) );
gl_FragColor = vec4(mix(color, envColor.xyz, vec3(clamp( vReflectionFactor, 0.0, 1.0 ))), 1.0);
}
</script>
<script>
var camera, scene, renderer;
var mesh, material, controls, sky;
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setClearColor(0xfffff, 0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 400;
scene = new THREE.Scene();
var numberOfImages = 46, images = [];
for (var i = 1; i <= numberOfImages; i++) {
images.push('sources/instagram2/image' + i + ".jpg");
}
var urls = images.sort(function(){return .6 - Math.random()}).slice(0,6);
var textureCube = THREE.ImageUtils.loadTextureCube( urls );
var skyshader = THREE.ShaderLib[ "cube" ];
skyshader.uniforms[ "tCube" ].value = textureCube;
var skymaterial = new THREE.ShaderMaterial( {
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
uniforms: skyshader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
sky = new THREE.Mesh( new THREE.BoxGeometry( 1500, 1500, 1500 ), skymaterial );
sky.visible = false;
scene.add( sky );
var attributes = {
displacement: {
type: 'f',
value: []
}
};
var uniforms = {
color: {
type: "c",
value: new THREE.Color(0x000000),
},
envMap: {
type: "t",
value: textureCube
},
fresnelBias: {
type: "f",
value: 0.1
},
fresnelScale: {
type: "f",
value: 1.0
},
fresnelPower: {
type: 'f',
value: 2.0
},
amplitude: {
type: 'f',
value: 0
}
};
var vertexShader = document.getElementById('vertexShader').text;
var fragmentShader = document.getElementById('fragmentShader').text;
material = new THREE.ShaderMaterial(
{
uniforms : uniforms,
vertexShader : vertexShader,
fragmentShader : fragmentShader,
});
var loader = new THREE.BinaryLoader();
loader.load( "sources/obj/mmlogo/mm_logo.js", function ( geometry ) {
mesh = new THREE.Mesh(geometry, material);
mesh.scale.set( 100, 100, 100 );
var vertices = mesh.geometry.vertices;
var values = attributes.displacement.value
for(var v = 0; v < vertices.length; v++) {
values.push(Math.random() * 30);
}
scene.add(mesh);
} );
var light = new THREE.AmbientLight( 0x404040 );
scene.add( light );
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
var frame = 0;
function animate() {
uniforms.amplitude.value = Math.sin(frame);
frame += 0.1;
requestAnimationFrame(animate);
//controls.update();
//mesh.rotation.x += 0.005;
//mesh.rotation.y += 0.005;
renderer.render(scene, camera);
}
animate();
</script>
Do you have some conseil to make it?
You have defined the uniforms variable in the init() function so it's scope is within that function and can not be accessed in the animate() function.
Add the uniforms variable to the global scope and you should be fine.

Shaders doesn't work in Three.js app

I wrote a program with Three.js. I try to use shaders but, unfortunately, the app does not work. I tried to customized a application from threejs.org. This is the code:
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="ecma/three.js"></script>
<script type="text/javascript" src="ecma/jquery-1.9.0.js"></script>
<script type="text/javascript" src="ecma/OrbitControls.js"></script>
<style>
body{ margin: 0; overflow: hidden; }
</style>
</head>
<body>
<div id="WebGL-output">
</div>
<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 vUv;
void main()
{
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script id="fragment_shader1" type="x-shader/x-fragment">
uniform vec2 resolution;
uniform float time;
varying vec2 vUv;
void main(void)
{
vec2 p = -1.0 + 2.0 * vUv;
float a = time*100.0;
float d,e,f,g=1.0/40.0,h,i,r,q;
e=400.0*(p.x*0.5+0.5);
f=400.0*(p.y*0.5+0.5);
i=200.0+sin(e*g+a/150.0)*20.0;
d=200.0+cos(f*g/2.0)*18.0+cos(e*g)*7.0;
r=sqrt(pow(i-e,2.0)+pow(d-f,2.0));
q=f/r;
e=(r*cos(q))-a/2.0;f=(r*sin(q))-cos(a/2.0);
d=sin(e*g)*176.0+sin(e*g)*164.0+r;
h=((f+d)+a/2.0)*g;
i=cos(h+r*p.x/1.3)*(e+e+a)+cos(q*g*6.0)*(r+h/3.0);
h=sin(f*g)*144.0-sin(e*g)*212.0*p.x;
h=(h+(f-e)*q+sin(r-(a+h)/7.0)*10.0+i/4.0)*g;
i+=cos(h*2.3*sin(a/350.0-q))*184.0*sin(q-(r*4.3+a/12.0)*g)+tan(r*g+h)*184.0*cos(r*g+h);
i=mod(i/5.6,256.0)/64.0;
if(i<0.0) i+=4.0;
if(i>=2.0) i=4.0-i;
d=r/350.0;
d+=sin(d*d*8.0)*0.52;
f=(sin(a*g)+1.0)/2.0;
gl_FragColor=vec4(vec3(f*i/1.6,i/2.0+d/13.0,i)*d*p.x+vec3(i/1.3+d/8.0,i/2.0+d/18.0,i)*d*(1.0-p.x),0.0);
}
</script>
<script type="text/javascript">
$(function () {
var W = window.innerWidth, H = window.innerHeight;
var plane, planeGeom, planeMat;
var sphere, sphereGeom, shadedMat;
var scene, camera, renderer;
var clock;
var orbitControls;
var uniforms1;
init();
makeLights();
makeFloor();
makeSphere();
render();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, W / H, 0.1, 1000);
camera.position.set(-40, 30, 0);
camera.lookAt(new THREE.Vector3(0,0,0));
renderer = new THREE.WebGLRenderer();
renderer.setClearColorHex(0xEEEEEE);
renderer.setSize(W, H);
renderer.shadowMapEnabled = true;
orbitControls = new THREE.OrbitControls(camera);
orbitControls.autoRotate = false;
clock = new THREE.Clock();
}
function makeLights(){
makeAmbientLight();
makeSpotLight();
}
function makeAmbientLight(){
ambiColor = 0x141414;
ambientLight = new THREE.AmbientLight(ambiColor);
scene.add(ambientLight);
}
function makeSpotLight(){
var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( -40, 60, -10 );
spotLight.castShadow = true;
scene.add( spotLight );
}
function makeFloor(){
planeGeom = new THREE.PlaneGeometry(100,100);
planeMat = new THREE.MeshLambertMaterial();
var planeTex = THREE.ImageUtils.loadTexture("picim/checkerboard.jpg");
planeTex.wrapS = planeTex.wrapT = THREE.RepeatWrapping;
planeTex.repeat.set(50, 50);
planeMat.map = planeTex;
planeMat.side = THREE.DoubleSide;
plane = new THREE.Mesh(planeGeom, planeMat);
plane.rotation.x=-0.5*Math.PI;
plane.position.set(15, 0, 0);
plane.receiveShadow = true;
scene.add(plane);
}
function makeSphere(){
sphereGeom = new THREE.SphereGeometry(5,20,20);
uniforms1 = {
time: { type: "f", value: 1.0 },
resolution: { type: "v2", value: new THREE.Vector2() }
};
shadedMat = new THREE.ShaderMaterial({uniforms: uniforms1,
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragment_shader1').textContent,
});
sphere = new THREE.Mesh(sphereGeom, shadedMat);
sphere.position.set(0, 10, 0);
sphere.castShadow = true;
scene.add(sphere);
}
function render(){
var delta = clock.getDelta();
orbitControls.update(delta);
sphere.rotation.y += 0.02;
requestAnimationFrame(render);
renderer.render(scene, camera);
}
$("#WebGL-output").append(renderer.domElement);
});
</script>
</body>
</html>
The app must display the floor and a sphere, on which the shaders are used. But the app shows a bright white sphere. Could you help me to find the error ?
Thanks,
Ee
If you are seeing a white sphere with these crazy shader, then it means that the shader works no?
If you are asking why is that... shader (and it's quite a shader) rendering white, instead of all that math, it's doubtful that anyone can help you with the presented code.
you can add something like gl_FragColor.xyz=cos(gl_FragColor.xyz)*.5+.5; and you'll see if that white actually has a bigger meaning.

Gradation color in WebGL with GLSL shader

I would have black color in the middle of my disk with a gradation from the outside.
the 2 first parts are the GLSL code to make my shader, my problem is when i do : "gl_FragColor = vec4( vec3( vUv, 0.17 ), 1. ); "
`
varying vec2 vUv;
void main()
{
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 0.8);
}
'
'
varying vec2 vUv;
void main()
{
gl_FragColor = vec4( vec3( vUv, 0.17 ), 1. );
}
'
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, 1024 / 860, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer({ antialias: true});
camera.position.z = 30;
var my_shad = new THREE.ShaderMaterial({
vertexShader: document.getElementById( 'vertex' ).textContent,
fragmentShader: document.getElementById( 'frag' ).textContent
});
var radius = 8;
var segments = 80;
var circleGeometry = new THREE.CircleGeometry( radius, segments );
var disk = new THREE.Mesh(circleGeometry, my_shad);
scene.add(disk);
renderer.setSize( 1024, 860 );
document.body.appendChild( renderer.domElement );
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
'
Try doing something like this for starters:
void main(){
float uvD = length(vUv);
vec3 gradient = mix(color1, color2, uvD);
gl_FragColor = vec4(gradient,1.);
}

Categories

Resources