添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
let angleOffset = Math.PI*2/segment; for(var i=0;i //更新为BufferGeometry let bottomPos = [ ] let topPos = [ ] let angleOffset = ( Math . PI * 2 ) / segment for ( var i = 0 ; i < segment ; i ++ ) { let x = Math . cos ( angleOffset * i ) * radius let z = Math . sin ( angleOffset * i ) * radius bottomPos . push ( x , 0 , z ) topPos . push ( x , height , z ) bottomPos = bottomPos . concat ( topPos ) let face = [ ] for ( var i = 0 ; i < segment ; i ++ ) { if ( i != segment - 1 ) { face . push ( i + segment + 1 , i , i + segment ) face . push ( i , i + segment + 1 , i + 1 ) } else { face . push ( segment , i , i + segment ) face . push ( i , segment , 0 ) let geo = new BufferGeometry ( ) geo . setAttribute ( 'position' , new BufferAttribute ( new Float32Array ( bottomPos ) , 3 ) ) geo . setIndex ( new BufferAttribute ( new Uint16Array ( face ) , 1 ) )

2、创建shader材质

            let c = new Color(color);
            let mat = new ShaderMaterial({
                uniforms: {
                    targetColor:{value:new Vector3(c.r,c.g,c.b)},
                    height: { value: height},
                side: DoubleSide,
                transparent:true,
                //depthTest:false,
                depthWrite:false,
                vertexShader: [
                    "varying vec3 modelPos;",
                    "void main() {",
                    "   modelPos = position;",
                    "	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
                ].join("\n"),
                fragmentShader: [
                    "uniform vec3 targetColor;",
                    "uniform float height;",
                    "varying vec3 modelPos;",
                    "void main() {",
                    "   gl_FragColor = vec4(targetColor.xyz,(1.0 - modelPos.y/height)*(1.0 - modelPos.y/height));",
                ].join("\n")
            });

需要注意的是使用双面渲染、打开透明、关闭深度写入以及alpha的获取(这里使用二次方程,比线性函数过度更自然)

三、完整代码

* 生成并返回柱状渐变光环 * @param {*} radius 半径 * @param {*} height 高度 * @param {*} color 颜色 * @returns getAureole(radius,height,color){ let geo,mat; let segment = 64; //geo /*let bottomPos = []; let topPos = []; let angleOffset = Math.PI*2/segment; for(var i=0;i<segment;i++){ let x = Math.cos(angleOffset * i)*radius; let z = Math.sin(angleOffset * i)*radius; bottomPos.push(new Vector3(x,0,z)); topPos.push(new Vector3(x,height,z)); bottomPos = bottomPos.concat(topPos); let face = [] for(var i=0;i<segment;i++){ if(i != segment - 1){ face.push(new Face3(i+segment+1,i,i+segment)); face.push(new Face3(i,i+segment+1,i+1)); else{ face.push(new Face3(segment,i,i+segment)); face.push(new Face3(i,segment,0)); geo = new Geometry(); geo.vertices = bottomPos; geo.faces = face;*/ //更新为BufferGeometry let bottomPos = [] let topPos = [] let angleOffset = (Math.PI * 2) / segment for (var i = 0; i < segment; i++) { let x = Math.cos(angleOffset * i) * radius let z = Math.sin(angleOffset * i) * radius bottomPos.push(x, 0, z) topPos.push(x, height, z) bottomPos = bottomPos.concat(topPos) let face = [] for (var i = 0; i < segment; i++) { if (i != segment - 1) { face.push(i + segment + 1, i, i + segment) face.push(i, i + segment + 1, i + 1) } else { face.push(segment, i, i + segment) face.push(i, segment, 0) let geo = new BufferGeometry() geo.setAttribute('position', new BufferAttribute(new Float32Array(bottomPos), 3)) geo.setIndex(new BufferAttribute(new Uint16Array(face), 1)) //mat let c = new Color(color); mat = new ShaderMaterial({ uniforms: { targetColor:{value:new Vector3(c.r,c.g,c.b)}, height: { value: height}, side: DoubleSide, transparent:true, //depthTest:false, depthWrite:false, vertexShader: [ "varying vec3 modelPos;", "void main() {", " modelPos = position;", " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", ].join("\n"), fragmentShader: [ "uniform vec3 targetColor;", "uniform float height;", "varying vec3 modelPos;", "void main() {", " gl_FragColor = vec4(targetColor.xyz,(1.0 - modelPos.y/height)*(1.0 - modelPos.y/height));", ].join("\n") }); let mesh = new Mesh(geo,mat); mesh.renderOrder = 9999 return mesh; 一、实现原理通过shader,将物体的透明度由下往上,从1到0渐变即可(只需要两圈顶点,底下一圈alpha设为1,上面一圈alpha设为0)二、实现步骤1、创建geometry这个几何体类似于圆柱,只是没有上下两个底面 let bottomPos = []; let topPos = []; let angleOffset = Math.PI*2/segment; for(var i=0;i&lt;segment;i++){ let x = . <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8 方案1利用两个光柱进行贴图,两两垂直成九十度。 depthWrite: false,注意把深度影响关了,官方解释: Whether rendering this material has any effect on the depth buffer. Default is true. .depthWrite : Boolean: When drawing 2D overlays it can be useful to disable the depth writing in order to lay let texture = new THREE.TextureLoader().load('./lightray_yellow.jpg'), material = new THREE.MeshBasicMaterial({ map: texture, transparent: true, const color = "#5588aa"; // 创建box const geometry = new THREE.PlaneBufferGeometry(width, width, 1, 1); const vertexShader = ` varying vec2 vUv;
要实现渐变色矩形,你可以使用Three.js渐变色材质(`THREE.MeshBasicMaterial`)和平面几何体(`THREE.PlaneGeometry`)。 首先,你需要创建一个渐变色材质,并将其作为参数传递给平面几何体的构造函数。在创建渐变色材质时,你可以设置其颜色属性,以指定从哪种颜色到哪种颜色的渐变。你还可以设置渐变的起始点和终止点,以控制渐变的方向和大小。 下面是一个实现渐变色矩形的基本代码示例: ```javascript // 创建渐变色材质 var material = new THREE.MeshBasicMaterial({ color: new THREE.Color(0xff0000), // 渐变起始颜色 vertexColors: THREE.VertexColors // 开启顶点颜色插值 // 创建平面几何体 var geometry = new THREE.PlaneGeometry(2, 2); // 设置顶点颜色 geometry.faces.forEach(function(face) { var colors = face.vertexColors; colors[0] = new THREE.Color(0xff0000); // 左上角为起点 colors[1] = new THREE.Color(0x00ff00); // 右上角为终点 colors[2] = new THREE.Color(0x0000ff); // 左下角为起点 // 创建渐变色矩形 var mesh = new THREE.Mesh(geometry, material); 这段代码会创建一个渐变色从红色到绿色再到蓝色的矩形。你可以根据需要修改起始颜色、终止颜色和顶点颜色来实现自定义的渐变效果