Hello I have a BufferGeometry created using a set of vertices.
https://jsfiddle.net/eg4bhym5/2/
I want to add black color which repeats itself after certain distance. Something like this.
And I want to change colors rather than adding any textures as I want to add different colors. Can someone help?
Hi!
Creativity is up to you
You can use a buffer attribute with colors for vertices and then use .vertexColors: THREE.VertexColors
of your material.
You can use shaders to change colors along any of uv coordinates to have such stripes.
1 Like
There is also an example that demonstrates how to generate the geometry data for using vertex colors: https://threejs.org/examples/webgl_geometry_colors
2 Likes
I got how to do it but I cannot get around a sharp change of colors though.
And what did you do to get this result?
Could you provide a live code example?
yombo
March 20, 2019, 8:18am
7
As sharp color transitions are needed, vertex color are not suitable IMHO.
A simpe two pixel texture with THREE.NearestFilter and THREE.RepeatWrapping is best.
Another possibility is to use mesh groups.
Why not? It works with non-indexed buffer geometry.
yombo
March 20, 2019, 8:23am
9
Because the triangles between two neighbour vertices of different colors will always be interpolated between red and white.
Sure
But if you have a triangle soup (non-indexed buffer geometry), you can set the same color of vertices of triangles. One triangle is red, another one is white and so on. No interpolation.
We just don’t know how things organized in OP’s code.
All we can do is just fortune telling
2 Likes
yombo
March 20, 2019, 8:33am
11
You’re right, I retract from what I said.
hofk
March 20, 2019, 9:43am
12
I still don’t know exactly what @Vimal_Rathod wants to achieve. But since its fiddle is forked by my example, you can easily add it.
The lines for the groups are only commented out in fiddle and have to be designed like this.
for ( var f = 0, p = 0; f < faceCount; f ++, p += 6) {
g.addGroup( p, 6, f % 8 );
}
Then use multi material:
var material = [
new THREE.MeshBasicMaterial( { color: 0x000000, side: THREE.DoubleSide} ),
new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.DoubleSide} ),
new THREE.MeshBasicMaterial( { color: 0xffffff, side: THREE.DoubleSide} ),
new THREE.MeshBasicMaterial( { color: 0x00ffff, side: THREE.DoubleSide} ),
new THREE.MeshBasicMaterial( { color: 0x00ff00, side: THREE.DoubleSide} ),
new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide} ),
new THREE.MeshBasicMaterial( { color: 0x0000ff, side: THREE.DoubleSide} ),
new THREE.MeshBasicMaterial( { color: 0xff00ff, side: THREE.DoubleSide} )
];
in function animate:
g.groups[ getRandomInt( faceCount - 1 ) ].materialIndex = getRandomInt( 7 );
g.groupsNeedUpdate = true; // to change materialIndex for multi material
You get what you see above in the short video.
Watch now live in the collection: http://discourse.threejs.hofk.de/2019/ColorStripeChanging/ColorStripeChanging.html
hofk
March 21, 2019, 5:11pm
13
Instead of a discussion post on vertexColors a simple example. http://discourse.threejs.hofk.de/2019/ColorStripeChanging2/ColorStripeChanging2.html
It is based on my basic example of BufferGeometry. http://discourse.threejs.hofk.de/2017/BufferGeometry/BufferGeometry.html
The whole code.
<!DOCTYPE html>
<!-- https://discourse.threejs.org/t/assign-different-colors-to-different-parts-of-buffergeometry/6604/12 -->
<head>
<title> ColorStripeChanging2 </title>
<meta charset="utf-8" />
<style> body { margin: 0;} </style>
</head>
<body>
<button type="button" id="newcolors"> new colors </button>
</body>
<script src="../js/three.min.102.js"></script>
<script src="../js/OrbitControls.js"></script>
<script>
// @author hofk
document.getElementById( "newcolors" ).onclick = newcolors;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 0.1, 100 );
camera.position.set( 5, -18, 30 );
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0x111111, 1 );
var container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
var controls = new THREE.OrbitControls( camera, renderer.domElement );
var clock = new THREE.Clock( );
var stripCount = 24;
var stripWidth = 1;
var stripHeight = 12;
var centerX = stripCount * stripWidth / 2;
var centerY = stripHeight / 2;
var faceCount = stripCount * 2;
// use THREE.VertexColors
var material = new THREE.MeshBasicMaterial( { side: THREE.DoubleSide, vertexColors: THREE.VertexColors, wireframe: false } );
var g = new THREE.BufferGeometry( ); // non indexed BufferGeometry
g.positions = new Float32Array( faceCount * 9 ); // 'triangle soup'
g.addAttribute( 'position', new THREE.BufferAttribute( g.positions, 3 ) );
g.colors = new Float32Array( faceCount * 9 );
g.addAttribute( 'color', new THREE.BufferAttribute( g.colors, 3 ) );
for ( var i = 0, j = 0; i < stripCount; i ++, j += 18 ) {
// left face
g.positions[ j ] = i * stripWidth - centerX;
g.positions[ j + 1 ] = 0 - centerY;
g.positions[ j + 2 ] = 8 * Math.sin( Math.PI * i / 25 );
g.positions[ j + 3 ] = ( i + 1 ) * stripWidth - centerX;
g.positions[ j + 4 ] = stripHeight - centerY;
g.positions[ j + 5 ] = 8 * Math.sin( Math.PI * ( i + 1 ) / 25 );
g.positions[ j + 6 ] = i * stripWidth - centerX;
g.positions[ j + 7 ] = stripHeight - centerY;
g.positions[ j + 8 ] = 8 * Math.sin( Math.PI * i / 25 );
// right face
g.positions[ j + 9 ] = i * stripWidth - centerX;
g.positions[ j + 10 ] = 0 - centerY;
g.positions[ j + 11 ] = 8 * Math.sin( Math.PI * i / 25 );
g.positions[ j + 12 ] = ( i + 1 ) * stripWidth - centerX;
g.positions[ j + 13 ] = 0 - centerY;
g.positions[ j + 14 ] = 8 * Math.sin( Math.PI * ( i + 1 ) / 25 );
g.positions[ j + 15 ] = ( i + 1 ) * stripWidth - centerX;
g.positions[ j + 16 ] = stripHeight - centerY;
g.positions[ j + 17 ] = 8 * Math.sin( Math.PI * ( i + 1 ) / 25 );
}
var mesh = new THREE.Mesh( g, material );
scene.add( mesh );
var t1 = 0;
var t2;
var c8;
var c = [];
newcolors( );
animate();
//..................................
function animate() {
t2 = clock.getElapsedTime ( );
requestAnimationFrame( animate );
renderer.render( scene, camera );
if ( t2 - t1 > 0.4 ) {
for ( var i = 0, j = 0; i < stripCount; i ++, j += 18 ) {
c8 = getRandomInt( 7 ) * 3;
for ( k = 0; k < 18; k ++ ) { // apply color
g.colors[ j + k ] = c[ k % 3 + c8 ];
}
}
t1 = t2;
}
g.attributes.color.needsUpdate = true;
controls.update();
}
function getRandomInt( max ) {
return Math.floor( Math.random( ) * Math.floor( max ) );
}
function newcolors( ) {
c = [];
for ( var i = 0; i < 8; i ++ ) { // random colors
c.push( Math.random( ), Math.random( ), Math.random( ) );
}
}
</script>
</html>
2 Likes
Really thanks for the info @hofk and others. I got how to do that using your example thanks to that.