Three js custom material affected by light - javascript

I have this material:
<script id="vertexShader2" type="x-shader/x-vertex">
varying vec2 vUv;
void main()
{
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<!-- fragment shader a.k.a. pixel shader -->
<script id="fragmentShader2" type="x-shader/x-vertex">
uniform sampler2D baseTexture;
uniform float baseSpeed;
uniform sampler2D noiseTexture;
uniform float noiseScale;
uniform float alpha;
uniform float time;
varying vec2 vUv;
void main()
{
vec2 uvTimeShift = vUv + vec2( -0.7, 1.5 ) * time * baseSpeed;
vec4 noiseGeneratorTimeShift = texture2D( noiseTexture, uvTimeShift );
vec2 uvNoiseTimeShift = vUv + noiseScale * vec2( noiseGeneratorTimeShift.r, noiseGeneratorTimeShift.b );
vec4 baseColor = texture2D( baseTexture, uvNoiseTimeShift );
baseColor.a = alpha;
gl_FragColor = baseColor;
}
</script>
var noiseTexture = new THREE.ImageUtils.loadTexture( 'img/wormholes/cloud.png' );
noiseTexture.wrapS = noiseTexture.wrapT = THREE.RepeatWrapping;
var lavaTexture = new THREE.ImageUtils.loadTexture( "img/planets/"+value['texture_clouds'] );
lavaTexture.wrapS = lavaTexture.wrapT = THREE.RepeatWrapping;
this.earthUniforms = {
baseTexture: { type: "t", value: lavaTexture },
baseSpeed: { type: "f", value: 0.001 },
noiseTexture: { type: "t", value: noiseTexture },
noiseScale: { type: "f", value: 0.07337 },
alpha: { type: "f", value: 10.0 },
time: { type: "f", value: 1.0 }
};
animatedSurfaces.push(earthUniforms);
var customMaterial = new THREE.ShaderMaterial(
{
uniforms: earthUniforms,
vertexShader: document.getElementById( 'vertexShader2' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader2' ).textContent,
specular : new THREE.Color("rgb(255,255,255)"),
shininess : 0.1,
depthTest : 0,
blending : 1,
transparent: true,
bumpScale : 1, //0.8
bumpMap : THREE.ImageUtils.loadTexture( "img/planets/"+value['texture_clouds_alpha'] ),
map : THREE.ImageUtils.loadTexture( "img/planets/"+value['texture_clouds'] ),
color : 0xffffff,
//opacity : 0.1,
emissive : new THREE.Color("rgb(30,22,20)"),
alphaMap : THREE.ImageUtils.loadTexture( "img/planets/"+value['texture_clouds_alpha']),
});
It is reacting with light like MeshBasic material.
I need to react like MeshLambert material with alpha map.
It means to configure material black color in "lavatexture" to be transparent, and reacting on light source. Lighted side to have diffuse color, and side in shadow to have specular color.
How to solve this, when uniforms don't let material to behive like meshLambertMaterial, i cant set diffuse and specular color.
But i need that uniforms effect. (lava effect http://stemkoski.github.io/Three.js/Shader-Animate.html)
r71

Related

My THREE.js RawShaderMaterial isn't Working

I have had no problems loading others' shaders into THREE.js, but I seem to have run into a problem creating and running my own.
The shader works on the site I used to create it (https://shaderfrog.com/app/view/5460), but not when I tried to implement it.
I am not sure whether it is a javascript, three.js or GLSL problem, so all help would be greatly appreciated.
Here is my js code:
function newCube(colour=0xffffff,height=1,width=height,depth=height){
const geometry = new THREE.CubeGeometry(height,depth,width);
const material = new THREE.MeshBasicMaterial( {color: colour} );
return(new THREE.Mesh( geometry, material ));
}
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60,window.innerWidth / window.innerHeight,1,10000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xaaaaaa, 1);
document.body.appendChild(renderer.domElement);
const cube = newCube(0x220033,1);
var material= new THREE.RawShaderMaterial({
"id": 5472,
"name": "Fragmented",
"fragmentShader": "precision highp float;\nprecision highp int;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nuniform float time;\nuniform vec3 color;\nuniform vec3 lightPosition;\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec3 vColor;\nvarying vec2 vUv;\nvarying vec2 vUv2;\n\nvoid main() {\n vec3 worldPosition = ( modelMatrix * vec4( vPosition, 1.0 )).xyz;\n vec3 worldNormal = normalize( vec3( modelMatrix * vec4( vNormal, 0.0 ) ) );\n vec3 lightVector = normalize( lightPosition - worldPosition );\n float brightness = dot( worldNormal, lightVector );\n gl_FragColor = vec4( color * brightness, 1.0 );\n}",
"vertexShader": "precision highp float;\nprecision highp int;\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nuniform float time;\nuniform vec3 color;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\nattribute vec2 uv2;\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec2 vUv2;\nvoid main() {\n vNormal = normal;\n vUv = uv;\n vUv2 = uv2;\n vPosition = position;\n gl_Position= projectionMatrix * modelViewMatrix * vec4( position+sin(position*time)/10., 1. );\n}",
"uniforms": {
"time": {
"name": "time",
"displayName": null,
"type": "f",
"glslType": "float",
"useGridHelper": false,
"useRange": false,
"range": null,
"isRandom": false,
"randomRange": null,
"useToggle": false,
"toggle": null,
"description": "",
"value":0
},
"color": {
"name": "color",
"displayName": null,
"type": "c",
"glslType": "vec3",
"useGridHelper": false,
"useRange": false,
"range": null,
"isRandom": false,
"randomRange": null,
"useToggle": false,
"toggle": null,
"description": "Example light color"
},
"lightPosition": {
"name": "lightPosition",
"displayName": null,
"type": "v3",
"glslType": "vec3",
"useGridHelper": false,
"useRange": false,
"range": null,
"isRandom": false,
"randomRange": null,
"useToggle": false,
"toggle": null,
"description": ""
}
}
});
scene.add(cube);
cube.material=material;
camera.position.z = 3;
function render() {
cube.material.uniforms.time.value+=0.1;
renderer.render(scene, camera);
cube.mesh.rotation.x += 0.05;
cube.mesh.rotation.y -= 0.05;
requestAnimationFrame(render);
}
render();
I modified your code, so at least it shows something:
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three#0.133";
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60,window.innerWidth / window.innerHeight,1,10000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xaaaaaa, 1);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry();
var material= new THREE.RawShaderMaterial({
"fragmentShader": "precision highp float;\nprecision highp int;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nuniform float time;\nuniform vec3 color;\nuniform vec3 lightPosition;\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec3 vColor;\nvarying vec2 vUv;\nvarying vec2 vUv2;\n\nvoid main() {\n vec3 worldPosition = ( modelMatrix * vec4( vPosition, 1.0 )).xyz;\n vec3 worldNormal = normalize( vec3( modelMatrix * vec4( vNormal, 0.0 ) ) );\n vec3 lightVector = normalize( lightPosition - worldPosition );\n float brightness = dot( worldNormal, lightVector );\n gl_FragColor = vec4( color * brightness, 1.0 );\n}",
"vertexShader": "precision highp float;\nprecision highp int;\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nuniform float time;\nuniform vec3 color;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\nattribute vec2 uv2;\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec2 vUv2;\nvoid main() {\n vNormal = normal;\n vUv = uv;\n vUv2 = uv2;\n vPosition = position;\n gl_Position= projectionMatrix * modelViewMatrix * vec4( position+sin(position*time)/10., 1. );\n}",
"uniforms": {
"time": {
"value":0
},
"color": {
"value": new THREE.Color(0x320064)
},
"lightPosition": {
"value": new THREE.Vector3().setScalar(5)
}
}
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 3;
function render() {
cube.material.uniforms.time.value+=0.1;
renderer.render(scene, camera);
cube.rotation.x += 0.01;
cube.rotation.y -= 0.01;
requestAnimationFrame(render);
}
render();
</script>

THREE.js vertexShader color mix based on height

How do I set the color to the mesh only when the height is zero?
As for now, i just mixed the colors:
The problem is that this kind on mixing is not precise. I just want the color blue only when the height is zero (so only inside that red path I made with paint).
I created a custom material for the mesh, like so:
material = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.merge([
THREE.UniformsLib['lights'],
{
lightIntensity: {type: 'f', value: 1.0},
diffuse: {type: 'c', value: new THREE.Color(0x0000ff)},
color0: {
value: new THREE.Color("blue")
},
color1: {
value: new THREE.Color("green")
},
color2: {
value: new THREE.Color("brown")
},
color3: {
value: new THREE.Color("black")
},
bboxMin: {
value: geom.boundingBox.min
},
bboxMax: {
value: geom.boundingBox.max
}
}
]),
vertexShader: `
uniform vec3 bboxMin;
uniform vec3 bboxMax;
varying vec2 vUv;
varying vec3 vPos;
varying vec3 vNormal;
void main() {
vPos = (modelMatrix * vec4(position, 1.0 )).xyz;
vNormal = normalMatrix * normal;
vUv.y = (position.y - bboxMin.y) / (bboxMax.y - bboxMin.y);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`,
fragmentShader: `
uniform vec3 color1;
uniform vec3 color2;
uniform vec3 color3;
uniform vec3 color0;
varying vec2 vUv;
uniform vec3 diffuse;
varying vec3 vPos;
varying vec3 vNormal;
struct PointLight {
vec3 position;
vec3 color;
};
uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
void main() {
vec4 addedLights = vec4(0.1, 0.1, 0.1, 1.0);
for(int l = 0; l < NUM_POINT_LIGHTS; l++) {
vec3 adjustedLight = pointLights[l].position + cameraPosition;
vec3 lightDirection = normalize(vPos - adjustedLight);
addedLights.rgb += clamp(dot(-lightDirection, vNormal), 0.0, 1.0) * pointLights[l].color;
}
gl_FragColor = mix(vec4(mix(mix(mix(color0, color1, vUv.y), color1, vUv.y), mix(color1, color2, vUv.y), vUv.y), 1.0),addedLights, addedLights);
}
`,
lights: true
});
Try using the step() function. Here's a definition to help you understand it. Here's how it works:
float step(float edge, float x)
It takes in a constant to declare the edge, and x, which is your variable.
If x is below the edge, you get 0, and if x is above the edge, you get 1.
Here's a simplified use of it. When height is below 0.2, you'll get blue, and when height is above 0.2, you'll get green.
vec3 green = vec3(0.0, 1.0, 0.0);
vec3 blue = vec3(0.0, 0.0, 1.0);
float edge = 0.2;
float colorMix = step(edge, height);
vec3 finalColor = mix(blue, green, colorMix);
I picked 0.2 to give the blue band some thickness, otherwise it wouldn't be visible.

Three.js wrong texture on ShaderMaterial

I'm trying to use a shaderMaterial to adjust the brightness and contrast on one object (the sphere for VR video)
Here is how I implement the ShaderMaterial
var geometry = new THREE.SphereGeometry( 500, 60, 40 );
var panoTexture = new THREE.VideoTexture( video );
panoTexture.minFilter = THREE.LinearFilter;
panoTexture.magFilter = THREE.LinearFilter;
panoTexture.format = THREE.RGBFormat;
// var material = new THREE.MeshLambertMaterial( { map : texture } );
var shader = THREE.BrightnessContrastShader;
shader.uniforms[ "contrast" ].value = 0.0;
shader.uniforms[ "brightness" ].value = 0.0;
shader.uniforms[ "texture" ].texture = panoTexture;
var panoMaterial = new THREE.ShaderMaterial(shader);
panoVideoMesh = new THREE.Mesh( geometry, panoMaterial );
And here is the code I'm using for the shader
THREE.BrightnessContrastShader = {
uniforms: {
"tDiffuse": { type: "t", value: null },
"brightness": { type: "f", value: 0 },
"contrast": { type: "f", value: 0 },
"texture": { type: "t", value: 0 }
},
vertexShader: [
"varying vec2 vUv;",
"void main() {",
"vUv = uv;",
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
"}"
].join("\n"),
fragmentShader: [
"uniform sampler2D tDiffuse;",
"uniform float brightness;",
"uniform float contrast;",
"varying vec2 vUv;",
"void main() {",
"gl_FragColor = texture2D( tDiffuse, vUv );",
"gl_FragColor.rgb += brightness;",
"if (contrast > 0.0) {",
"gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) / (1.0 - contrast) + 0.5;",
"} else {",
"gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) * (1.0 + contrast) + 0.5;",
"}",
"}"
].join("\n")
};
When the sphere is rendered it's using another more recently generated texture that is for another part of the scene.
How do I keep the video texture on the panoTexture, is this possible and and am I going about this the right way?
This worked
shader.uniforms[ "tDiffuse" ].value = panoTexture;

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.

three.js change texture on material

I'm setting up a texture on a mesh in three.js and when it loads it looks how I want it too:
texture = THREE.ImageUtils.loadTexture("textures/hash.png");
texture.needsUpdate = true;
uniforms = {
color: { type: "c", value: new THREE.Color( 0xffffff ) },
texture: { type: "t", value: texture },
},
vertexShader = "varying vec2 vUv; void main() {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );}",
fragmentShader = "uniform vec3 color; uniform sampler2D texture; varying vec2 vUv; void main() { vec4 tColor = texture2D( texture, vUv ); gl_FragColor = vec4( mix( color, tColor.rgb, tColor.a ), 1.0 );}",
material = new THREE.ShaderMaterial({
uniforms : uniforms,
vertexShader : vertexShader,
fragmentShader : fragmentShader
});
but I want to change the texture that is on this mesh later on, I have tried this:
obj.mesh.material.uniforms.texture = THREE.ImageUtils.loadTexture("textures/1.png");
obj.mesh.material.uniforms.texture.needsUpdate = true;
but this doesn't change the texture being displayed on the mesh, how can I change a texture on a THREE.ShaderMaterial ?
Assign the texture to obj.mesh.material.uniforms.texture.value instead. Also consider setting the needsUpdate flag after the texture has successfully loaded (by subscribing to the load event).

Categories

Resources