Three.js animation stops if using "skinning = true" with THREE.ShaderMaterial - javascript

I am using three.js to write a game using WebGL and i need skin shader for my character models. But if i use THREE.ShaderMaterial animation stops.
Can anybody help?
SkinShaderSimple = function (mapColor, mapHeight, mapSpecular, composer)
{
if (mapColor === undefined) return new THREE.MeshPhongMaterial();
if (mapHeight === undefined) return new THREE.MeshPhongMaterial();
if (mapSpecular === undefined) return new THREE.MeshPhongMaterial();
if (composer === undefined) return new THREE.MeshPhongMaterial();
var shader = THREE.ShaderSkin[ "skinSimple" ];
var fragmentShader = shader.fragmentShader;
var vertexShader = shader.vertexShader;
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
uniforms[ "enableBump" ].value = true;
uniforms[ "enableSpecular" ].value = true;
uniforms[ "tBeckmann" ].value = composer.renderTarget1;
uniforms[ "tDiffuse" ].value = mapColor;
uniforms[ "bumpMap" ].value = mapHeight;
uniforms[ "specularMap" ].value = mapSpecular;
uniforms[ "diffuse" ].value.setHex( 0xa0a0a0 );
uniforms[ "specular" ].value.setHex( 0xa0a0a0 );
uniforms[ "uRoughness" ].value = 0.145;
uniforms[ "uSpecularBrightness" ].value = 0.75;
uniforms[ "bumpScale" ].value = 16;
uniforms[ "offsetRepeat" ].value.set( 0.001, 0.001, 0.998, 0.998 );
var mat = new THREE.ShaderMaterial( { fragmentShader: fragmentShader,vertexShader: vertexShader, uniforms: uniforms, lights: true, skinning : true} );
return mat;
};`
then i am loading character
and use this material for it
loadMainChar = function()
{
//tmp loader
var loader = new THREE.JSONLoader();
//loader with callback function
loader.load( "content/models/character/Goblin.13.js",
function ( geometry, materials )
{
// Tell the material that it has bone weights
var mtl = MaterialsLibrary.CharacterSkinShaderSimple;
mtl.skinning = true;
// Create a new SkinnedMesh (important! Not a animatedMesh!)
mainCharacter = new THREE.SkinnedMesh( geometry, mtl );
mainCharacter.position.set(0,0,0);
mainCharacter.scale.set(1,1,1);
// Instantiate the animation
mainCharAnimation=new THREE.Animation(mainCharacter, geometry.animation);
mainCharacter.castShadow = true;
mainCharacter.receiveShadow = true;
// Start playing the animation
mainCharAnimation.play();
//add char to scene
scene.add(mainCharacter);
}
);
loader.onLoadComplete = function () {CheckLoadingMeshes();};
};

This chunk of code should get anyone going with THREE.WebGLRenderer 82.
<script type="x-shader/x-vertex" class="vs">
varying vec2 vUv;
uniform mat4 bindMatrix;
uniform mat4 bindMatrixInverse;
uniform mat4 boneMatrices[ MAX_BONES ];
mat4 getBoneMatrix( const in float i ) {
mat4 bone = boneMatrices[ int(i) ];
return bone;
}
void main() {
vUv = uv;
mat4 boneMatX = getBoneMatrix( skinIndex.x );
mat4 boneMatY = getBoneMatrix( skinIndex.y );
mat4 boneMatZ = getBoneMatrix( skinIndex.z );
mat4 boneMatW = getBoneMatrix( skinIndex.w );
mat4 skinMatrix = mat4( 0.0 );
skinMatrix += skinWeight.x * boneMatX;
skinMatrix += skinWeight.y * boneMatY;
skinMatrix += skinWeight.z * boneMatZ;
skinMatrix += skinWeight.w * boneMatW;
skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;
vec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );
vec3 objectNormal = skinnedNormal.xyz;
vec3 transformedNormal = normalMatrix * objectNormal;
vec4 skinVertex = bindMatrix * vec4( position, 1.0 );
vec4 skinned = vec4( 0.0 );
skinned += boneMatX * skinVertex * skinWeight.x;
skinned += boneMatY * skinVertex * skinWeight.y;
skinned += boneMatZ * skinVertex * skinWeight.z;
skinned += boneMatW * skinVertex * skinWeight.w;
skinned = bindMatrixInverse * skinned;
vec4 mvPosition = modelViewMatrix * skinned;
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script type="x-shader/x-fragment" class="fs">
varying vec2 vUv;
void main() {
gl_FragColor = vec4(1, vUv.x, 0, 1.0);
}
</script>
<script>
material = new THREE.ShaderMaterial( {
vertexShader: document.querySelector( '.vs' ).textContent,
fragmentShader: document.querySelector( '.fs' ).textContent,
skinning:true
});
</script>

Related

How to get correct shadow on ShaderMaterial

I have used InstancedBufferGeometry to create a lot of box then update position with Perlin noise. But the mesh has cast and has received wrong shadow. How to calculate a right shadow?
vertexShader
attribute vec3 offset;
attribute vec4 orientation;
attribute vec3 color;
varying vec3 pos;
varying vec3 vNormal;
varying vec3 vWorldPosition;
varying vec3 vColor;
vec3 applyQuaternionToVector( vec4 q, vec3 v ){
return v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );
}
THREE.ShaderChunk["common"]
THREE.ShaderChunk["shadowmap_pars_vertex"]
void main() {
vColor = color;
vec3 vPosition = applyQuaternionToVector( orientation, position );
pos = vPosition + offset;
vNormal = normalMatrix * vec3(normal + normalize(offset) * 0.3);
vec4 worldPosition = modelMatrix * vec4(pos, 1.0);
vWorldPosition = worldPosition.xyz;
gl_Position = projectionMatrix * modelViewMatrix * worldPosition;
THREE.ShaderChunk["shadowmap_vertex"]
}
fragmentShader
THREE.ShaderChunk['common']
THREE.ShaderChunk['packing']
varying vec3 pos;
varying vec3 vNormal;
varying vec3 vWorldPosition;
varying vec3 vColor;
uniform vec3 lightPosition;
THREE.ShaderChunk['shadowmap_pars_fragment']
void main() {
vec3 lightDirection = normalize(lightPosition + pos);
float c = max(0.0, dot(vNormal, lightDirection)) * 2.;
gl_FragColor = vec4(.3+c , .3+c , .3+c , 1.);
THREE.ShaderChunk['shadowmap_fragment']
}
demo link is here
three.js r.106
Thanks
var scene, camera, renderer;
var plane, temp, vnh, point;
var radius = 10;
var stats = new Stats();
var start = Date.now();
var options = {
scale: 200,
density: 2.5
}
var currentQ = new THREE.Quaternion();
var initedBoxes = false;
var init = function() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 25;
var controls = new THREE.OrbitControls(camera);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
var gui = new dat.GUI({
width: 300
});
gui.add(options, 'scale').min(0).max(200).name('Scale');
gui.add(options, 'density').min(0).max(10).name('Density');
// stats
stats.showPanel(0);
stats.domElement.style.position = 'fixed';
stats.domElement.style.top = 0;
document.body.appendChild(stats.domElement);
initLights();
initSphere();
initBoxes();
renderer.setAnimationLoop(function() {
update();
render();
});
}
var initLights = function() {
var ambientLight = new THREE.AmbientLight(0x555555);
scene.add(ambientLight);
light1 = new THREE.SpotLight(0xffffff, 2, 200, 10);
light1.position.set(-30, 30, 40);
light1.castShadow = true;
scene.add(light1);
light1Helper = new THREE.SpotLightHelper(light1, 0xffffff);
scene.add(light1Helper);
}
var initSphere = function() {
var geometry = new THREE.IcosahedronGeometry(radius, 3);
var material = new THREE.MeshPhongMaterial({
color: 0x999999,
wireframe: false
});
material.shininess = 0;
sphere = new THREE.Mesh(geometry, material);
// sphere.castShadow = true;
// sphere.receiveShadow = true;
// scene.add(sphere);
tempGeo = new THREE.Geometry();
tempGeo.copy(geometry);
temp = new THREE.Mesh(tempGeo, material);
var pGeo = new THREE.PlaneGeometry(100, 100, 1, 1);
plane = new THREE.Mesh(pGeo, material);
plane.receiveShadow = true;
plane.position.y = -radius - 3;
plane.rotation.x = -90 * Math.PI / 180;
scene.add(plane);
}
var initBoxes = function() {
initedBoxes = true;
var bufferGeometry = new THREE.BoxBufferGeometry(1, 1, 1);
var geometry = new THREE.InstancedBufferGeometry();
geometry.index = bufferGeometry.index;
geometry.attributes.position = bufferGeometry.attributes.position;
// geometry.attributes.normal = bufferGeometry.attributes.normal;
// per instance data
var offsets = [];
var orientations = [];
var colors = [];
var vector = new THREE.Vector4();
var x, y, z, w;
var cscale = chroma.scale(['#ff0000', '#00ff00', '#0000ff']).classes(10);
for (var i = 0; i < sphere.geometry.faces.length; i++) {
center = getCenter(sphere.geometry.faces[i]);
x = center.x;
y = center.y;
z = center.z;
vector.set(x, y, z, 0).normalize();
offsets.push(x + vector.x, y + vector.y, z + vector.z);
// rotate
rotation = getRotation(sphere.geometry.faces[i].normal);
vector.copy(rotation).normalize();
orientations.push(vector.x, vector.y, vector.z, vector.w);
var color = chroma(cscale(THREE.Math.randFloat(0, 1))).brighten(1).hex();
color = new THREE.Color(color);
colors.push(color.r, color.g, color.b);
}
offsetAttribute = new THREE.InstancedBufferAttribute(new Float32Array(offsets), 3);
orientationAttribute = new THREE.InstancedBufferAttribute(new Float32Array(orientations), 4);
colorAttribute = new THREE.InstancedBufferAttribute(new Float32Array(colors), 3);
geometry.addAttribute('offset', offsetAttribute);
geometry.addAttribute('orientation', orientationAttribute);
geometry.addAttribute('color', colorAttribute);
var material = new THREE.ShaderMaterial({
lights: true,
uniforms: THREE.UniformsUtils.merge([
THREE.UniformsLib["shadowmap"],
THREE.UniformsLib["lights"],
{
lightPosition: {
type: 'v3',
value: light1.position
},
time: {
type: 'f',
value: 0
}
}
]),
vertexShader: [
'attribute vec3 offset;',
'attribute vec4 orientation;',
'attribute vec3 color;',
'varying vec3 pos;',
'varying vec3 vNormal;',
'varying vec3 vWorldPosition;',
'varying vec3 vColor;',
'vec3 applyQuaternionToVector( vec4 q, vec3 v ){',
'return v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );',
'}',
THREE.ShaderChunk["common"],
THREE.ShaderChunk["shadowmap_pars_vertex"],
'void main() {',
'vColor = color;',
'vec3 vPosition = applyQuaternionToVector( orientation, position );',
'pos = vPosition + offset;',
'vNormal = normalMatrix * vec3(normal + normalize(offset) * 0.3);',
'vec4 worldPosition = modelMatrix * vec4(pos, 1.0);',
'vWorldPosition = worldPosition.xyz;',
'gl_Position = projectionMatrix * modelViewMatrix * worldPosition;',
THREE.ShaderChunk["shadowmap_vertex"],
'}'
].join('\n'),
fragmentShader: [
THREE.ShaderChunk['common'],
THREE.ShaderChunk['packing'],
'varying vec3 pos;',
'varying vec3 vNormal;',
'varying vec3 vWorldPosition;',
'varying vec3 vColor;',
'uniform vec3 lightPosition;',
THREE.ShaderChunk['shadowmap_pars_fragment'],
'void main() {',
'vec3 lightDirection = normalize(lightPosition + pos);',
'float c = max(0.0, dot(vNormal, lightDirection)) * 2.;',
// 'gl_FragColor = vec4(vColor.r + c , vColor.g + c , vColor.b + c , 1.);',
'gl_FragColor = vec4(.3+c , .3+c , .3+c , 1.);',
THREE.ShaderChunk['shadowmap_fragment'],
'}'
].join('\n')
});
boxes = new THREE.Mesh(geometry, material);
boxes.castShadow = true;
boxes.receiveShadow = true;
scene.add(boxes);
}
// find center position from 3 vertices
function getCenter(face) {
var centroid = new THREE.Vector3(0, 0, 0);
centroid.add(sphere.geometry.vertices[face.a]);
centroid.add(sphere.geometry.vertices[face.b]);
centroid.add(sphere.geometry.vertices[face.c]);
centroid.divideScalar(3);
return centroid;
}
function getRotation(normal) {
var planeVector1 = new THREE.Vector3(0, 1, 0);
var matrix1 = new THREE.Matrix4();
var quaternion = new THREE.Quaternion().setFromUnitVectors(planeVector1, normal);
var matrix = new THREE.Matrix4().makeRotationFromQuaternion(quaternion);
var a = new THREE.Euler();
a.setFromRotationMatrix(matrix, 'XYZ')
// return a.toVector3();
return quaternion;
}
// noise.seed(Math.random());
var update = function() {
stats.update();
var timer = (Date.now() - start) * .0002;
// animate vertices of sphere with noise
for (var i = 0; i < sphere.geometry.vertices.length; i++) {
var p = sphere.geometry.vertices[i];
var tp = temp.geometry.vertices[i];
var n = noise.perlin3(tp.x / (10 - options.density) + timer, tp.y / (10 - options.density) + timer, tp.z / (10 - options.density) + timer) * options.scale;
// move vertices with noise
p.normalize().multiplyScalar(radius + n / 100);
}
sphere.geometry.verticesNeedUpdate = true;
sphere.geometry.normalsNeedUpdate = true;
sphere.geometry.computeVertexNormals();
sphere.geometry.computeFaceNormals();
// animate boxes
if (initedBoxes) {
for (var i = 0; i < sphere.geometry.faces.length; i++) {
center = getCenter(sphere.geometry.faces[i]);
x = center.x;
y = center.y;
z = center.z;
offsetAttribute.setXYZ(i, center.x, center.y, center.z);
rotation = getRotation(sphere.geometry.faces[i].normal);
currentQ.copy(rotation).normalize();
orientationAttribute.setXYZW(i, currentQ.x, currentQ.y, currentQ.z, currentQ.w);
}
offsetAttribute.needsUpdate = true;
orientationAttribute.needsUpdate = true;
}
}
var animate = function() {
draw();
}
var render = function() {
renderer.render(scene, camera);
}
init();
<html>
<head>
<title>Instanced buffer test</title>
<style>
* {
padding: 0px;
margin: 0px;
}
html,
body {
overflow: hidden;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/106/three.min.js"></script>
<script src="https://josephg.github.io/noisejs/perlin.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.0.3/chroma.min.js"></script>
<script src="https://unpkg.com/three#0.85.0/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
</head>
<body>
</body>
</html>
If you want that the mesh casts proper shadow, it is not sufficient to use a ShaderMaterial for the .material property of the mesh.
The shadow of point lights depends on the .customDepthMaterial property. This means you've to write a shader (ShaderMaterial) which renders the object with the model transformations to the shadow map.
The shadow of the mesh is partially clipped by the near plane of the shadow camera.
Use a closer near plane (e.g. 0.1 rather than 0.5) by setting the .near property of the perspective shadow camera (light1.shadow.camera), to solve the issue:
light1 = new THREE.SpotLight( 0xffffff, 2, 200, 10 );
light1.position.set( -30, 30, 40 );
light1.castShadow = true;
light1.shadow.mapSize.x = 2048;
light1.shadow.mapSize.y = 2048;
light1.shadow.camera.near = 0.1;
scene.add(light1);
Further there are some issues in the shader. The statement
vec3 lightDirection = normalize(lightPosition + pos);
doesn't make any sense, because a direction is the vector from an point to another point, which is calculated by the (-)-operator (e.g. lightPosition - pos).
But that won't fix the issue, because lightPosition is a point in world space and pos is a point in model space.
You've to calculate the vector in view space, because in
float c = max(0.0, dot(vNormal, lightDirection)) * 2.;
vNormal is a vector in view space.
I recommend to calculate the light direction in the vertex shader (vLightDir) and to pass it to the fragment shader.
Calculate the direction in world space and transform it by the upper 3x3 of the view matrix (mat3(viewMatrix)):
vLightDir = mat3(viewMatrix) * (lightPosition - vWorldPosition);
Since worldPosition (as the name indicates) is is a position in world space, it has to be transformed by the viewMatrix rather than the modelViewMatrix:
gl_Position = projectionMatrix * viewMatrix * worldPosition;
Note, the modelViewMatrix transforms from object space to view space. The viewMatrix transforms from world space to view space. See also WebGLProgram .
Vertex shader:
vertexShader:
[
'attribute vec3 offset;',
'attribute vec4 orientation;',
'attribute vec3 color;',
'varying vec3 pos;',
'varying vec3 vNormal;',
'varying vec3 vWorldPosition;',
'varying vec3 vColor;',
'varying vec3 vLightDir;',
'uniform vec3 lightPosition;',
'vec3 applyQuaternionToVector( vec4 q, vec3 v ){',
'return v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );',
'}',
THREE.ShaderChunk["common"],
THREE.ShaderChunk["shadowmap_pars_vertex"],
'void main() {',
'vColor = color;',
'vec3 vPosition = applyQuaternionToVector( orientation, position );',
'pos = vPosition + offset;',
'vNormal = normalMatrix * vec3(normal + normalize(offset) * 0.3);',
'vec4 worldPosition = modelMatrix * vec4(pos, 1.0);',
'vWorldPosition = worldPosition.xyz;',
'vLightDir = mat3(viewMatrix) * (lightPosition - vWorldPosition);',
'gl_Position = projectionMatrix * viewMatrix * worldPosition;',
THREE.ShaderChunk["shadowmap_vertex"],
'}'
].join('\n')
Fragmetn shader:
fragmentShader:
[
THREE.ShaderChunk['common'],
THREE.ShaderChunk['packing'],
'varying vec3 pos;',
'varying vec3 vNormal;',
'varying vec3 vWorldPosition;',
'varying vec3 vColor;',
'varying vec3 vLightDir;',
THREE.ShaderChunk['shadowmap_pars_fragment'],
'void main() {',
'vec3 lightDirection = normalize(vLightDir);',
'float c = max(0.0, dot(vNormal, lightDirection)) * 2.;',
// 'gl_FragColor = vec4(vColor.r + c , vColor.g + c , vColor.b + c , 1.);',
'gl_FragColor = vec4(.3+c , .3+c , .3+c , 1.);',
THREE.ShaderChunk['shadowmap_fragment'],
'}'
].join('\n')
var scene,camera,renderer;
var plane, temp, vnh, point;
var radius = 10;
var stats = new Stats();
var start = Date.now();
var options = {
scale:200,
density:2.5
}
var currentQ = new THREE.Quaternion();
var initedBoxes = false;
var init = function(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.z = 25;
var controls = new THREE.OrbitControls( camera );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild( renderer.domElement );
window.onresize = function() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
var gui = new dat.GUI({width: 300});
gui.add(options,'scale').min(0).max(200).name('Scale');
gui.add(options,'density').min(0).max(10).name('Density');
// stats
stats.showPanel(0);
stats.domElement.style.position = 'fixed';
stats.domElement.style.top = 0;
document.body.appendChild( stats.domElement );
initLights();
initSphere();
initBoxes();
renderer.setAnimationLoop(function(){
update();
render();
});
}
var initLights = function(){
var ambientLight = new THREE.AmbientLight( 0x555555 );
scene.add( ambientLight );
light1 = new THREE.SpotLight( 0xffffff, 2, 200, 10 );
light1.position.set( -30, 30, 40 );
light1.castShadow = true;
light1.shadow.mapSize.x = 2048;
light1.shadow.mapSize.y = 2048;
light1.shadow.camera.near = 0.1;
scene.add(light1);
light1Helper = new THREE.SpotLightHelper(light1, 0xffffff);
scene.add(light1Helper);
}
var initSphere = function(){
var geometry = new THREE.IcosahedronGeometry( radius, 3 );
var material = new THREE.MeshPhongMaterial( {color: 0x999999, wireframe:false} );
// var material = new THREE.ShaderMaterial({
// vertexShader: document.getElementById('vertexShader').innerHTML,
// fragmentShader: document.getElementById('fragmentShader').innerHTML
// });
material.shininess = 0;
sphere = new THREE.Mesh( geometry, material );
sphere.castShadow = true;
sphere.receiveShadow = true;
// scene.add(sphere);
tempGeo = new THREE.Geometry();
tempGeo.copy(geometry);
temp = new THREE.Mesh( tempGeo, material );
var pGeo = new THREE.PlaneGeometry(200, 200, 1, 1);
plane = new THREE.Mesh( pGeo, material );
plane.receiveShadow = true;
plane.position.y = -radius - 10;
plane.rotation.x = -90 * Math.PI/180;
scene.add(plane);
}
var initBoxes = function(){
initedBoxes = true;
var bufferGeometry = new THREE.BoxBufferGeometry(1,1,1);
var geometry = new THREE.InstancedBufferGeometry();
geometry.index = bufferGeometry.index;
geometry.attributes.position = bufferGeometry.attributes.position;
// geometry.attributes.normal = bufferGeometry.attributes.normal;
// per instance data
var offsets = [];
var orientations = [];
var colors = [];
var vector = new THREE.Vector4();
var x, y, z, w;
var cscale = chroma.scale(['#ff0000','#00ff00','#0000ff']).classes(10);
for(var i=0; i<sphere.geometry.faces.length; i++){
center = getCenter(sphere.geometry.faces[i]);
x = center.x;
y = center.y;
z = center.z;
vector.set( x, y, z, 0 ).normalize();
offsets.push( x + vector.x, y + vector.y, z + vector.z );
// rotate
rotation = getRotation(sphere.geometry.faces[i].normal);
vector.copy(rotation).normalize();
orientations.push( vector.x, vector.y, vector.z, vector.w );
var color = chroma(cscale(THREE.Math.randFloat(0,1))).brighten(1).hex();
color = new THREE.Color(color);
colors.push(color.r, color.g, color.b);
}
offsetAttribute = new THREE.InstancedBufferAttribute( new Float32Array( offsets ), 3 );
orientationAttribute = new THREE.InstancedBufferAttribute( new Float32Array( orientations ), 4 );
colorAttribute = new THREE.InstancedBufferAttribute( new Float32Array( colors ), 3 );
geometry.addAttribute( 'offset', offsetAttribute );
geometry.addAttribute( 'orientation', orientationAttribute );
geometry.addAttribute( 'color', colorAttribute );
var material = new THREE.ShaderMaterial( {
lights: true,
uniforms: THREE.UniformsUtils.merge([
// THREE.UniformsLib["shadowmap"],
THREE.UniformsLib["lights"],
{
lightPosition: {type: 'v3', value: light1.position},
time: {type: 'f', value: 0}
}
]),
vertexShader:
[
'attribute vec3 offset;',
'attribute vec4 orientation;',
'attribute vec3 color;',
'varying vec3 pos;',
'varying vec3 vNormal;',
'varying vec3 vWorldPosition;',
'varying vec3 vColor;',
'varying vec3 vLightDir;',
'uniform vec3 lightPosition;',
'vec3 applyQuaternionToVector( vec4 q, vec3 v ){',
'return v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );',
'}',
THREE.ShaderChunk["common"],
THREE.ShaderChunk["shadowmap_pars_vertex"],
'void main() {',
'vColor = color;',
'vec3 vPosition = applyQuaternionToVector( orientation, position );',
'pos = vPosition + offset;',
'vNormal = normalMatrix * vec3(normal + normalize(offset) * 0.3);',
'vec4 worldPosition = modelMatrix * vec4(pos, 1.0);',
'vWorldPosition = worldPosition.xyz;',
'vLightDir = mat3(viewMatrix) * (lightPosition - vWorldPosition);',
'gl_Position = projectionMatrix * viewMatrix * worldPosition;',
THREE.ShaderChunk["shadowmap_vertex"],
'}'
].join('\n')
,
fragmentShader:
[
THREE.ShaderChunk['common'],
THREE.ShaderChunk['packing'],
'varying vec3 pos;',
'varying vec3 vNormal;',
'varying vec3 vWorldPosition;',
'varying vec3 vColor;',
'varying vec3 vLightDir;',
THREE.ShaderChunk['shadowmap_pars_fragment'],
'void main() {',
'vec3 lightDirection = normalize(vLightDir);',
'float c = max(0.0, dot(vNormal, lightDirection)) * 2.;',
// 'gl_FragColor = vec4(vColor.r + c , vColor.g + c , vColor.b + c , 1.);',
'gl_FragColor = vec4(.3+c , .3+c , .3+c , 1.);',
THREE.ShaderChunk['shadowmap_fragment'],
'}'
].join('\n')
});
boxes = new THREE.Mesh( geometry, material );
boxes.castShadow = true;
boxes.receiveShadow = true;
boxes.customDepthMaterial = new THREE.ShaderMaterial({
vertexShader:
[
'attribute vec3 offset;',
'attribute vec4 orientation;',
'varying vec3 vWorldPosition;',
'vec3 applyQuaternionToVector( vec4 q, vec3 v ){',
'return v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );',
'}',
'void main() {',
'vec3 vPosition = applyQuaternionToVector( orientation, position );',
'vec3 pos = vPosition + offset;',
'vec4 worldPosition = modelMatrix * vec4(pos, 1.0);',
'vWorldPosition = worldPosition.xyz;',
'gl_Position = projectionMatrix * viewMatrix * worldPosition;',
'}',
].join('\n')
,
fragmentShader: THREE.ShaderLib.distanceRGBA.fragmentShader,
uniforms: material.uniforms
});
scene.add(boxes);
}
// find center position from 3 vertices
function getCenter(face){
var centroid = new THREE.Vector3(0,0,0);
centroid.add(sphere.geometry.vertices[face.a]);
centroid.add(sphere.geometry.vertices[face.b]);
centroid.add(sphere.geometry.vertices[face.c]);
centroid.divideScalar(3);
return centroid;
}
function getRotation(normal){
var planeVector1 = new THREE.Vector3(0,1,0);
var matrix1 = new THREE.Matrix4();
var quaternion = new THREE.Quaternion().setFromUnitVectors(planeVector1, normal);
var matrix = new THREE.Matrix4().makeRotationFromQuaternion(quaternion);
var a = new THREE.Euler( );
a.setFromRotationMatrix ( matrix, 'XYZ' )
// return a.toVector3();
return quaternion;
}
// noise.seed(Math.random());
var update = function(){
stats.update();
var timer = (Date.now() - start) * .0002;
// animate vertices of sphere with noise
for(var i=0; i<sphere.geometry.vertices.length; i++){
var p = sphere.geometry.vertices[i];
var tp = temp.geometry.vertices[i];
var n = noise.perlin3(tp.x / (10-options.density) + timer, tp.y / (10-options.density) + timer, tp.z / (10-options.density) + timer) * options.scale;
// move vertices with noise
p.normalize().multiplyScalar(radius + n/100);
}
sphere.geometry.verticesNeedUpdate = true;
sphere.geometry.normalsNeedUpdate = true;
sphere.geometry.computeVertexNormals();
sphere.geometry.computeFaceNormals();
// animate boxes
if(initedBoxes){
for(var i=0; i<sphere.geometry.faces.length; i++){
center = getCenter(sphere.geometry.faces[i]);
x = center.x;
y = center.y;
z = center.z;
offsetAttribute.setXYZ(i, center.x, center.y, center.z);
rotation = getRotation(sphere.geometry.faces[i].normal);
currentQ.copy(rotation).normalize();
orientationAttribute.setXYZW( i, currentQ.x, currentQ.y, currentQ.z, currentQ.w );
}
offsetAttribute.needsUpdate = true;
orientationAttribute.needsUpdate = true;
}
}
var animate = function(){
draw();
}
var render = function(){
renderer.render( scene, camera );
}
init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/106/three.min.js"></script>
<script src="https://josephg.github.io/noisejs/perlin.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.0.3/chroma.min.js"></script>
<script src="https://unpkg.com/three#0.85.0/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>

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 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.

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