Threejs渐变光柱效果
一、实现原理
通过shader,将物体的透明度由下往上,从1到0渐变即可(只需要两圈顶点,底下一圈alpha设为1,上面一圈alpha设为0)
二、实现步骤
1、创建geometry
这个几何体类似于圆柱,只是没有上下两个底面
/*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));}}let geo = new Geometry();geo.vertices = bottomPos;geo.faces = face;*///更新为BufferGeometrylet bottomPos = []let topPos = []let angleOffset = (Math.PI * 2) / segmentfor (var i = 0; i < segment; i++) {let x = Math.cos(angleOffset * i) * radiuslet z = Math.sin(angleOffset * i) * radiusbottomPos.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;*///更新为BufferGeometrylet bottomPos = []let topPos = []let angleOffset = (Math.PI * 2) / segmentfor (var i = 0; i < segment; i++) {let x = Math.cos(angleOffset * i) * radiuslet z = Math.sin(angleOffset * i) * radiusbottomPos.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 = 9999return mesh;}
Threejs渐变光柱效果相关推荐
- 悬停渐变特效html,CSS3 transition属性实现hover渐变动画效果
CSS3 transition属性实现hover渐变动画效果 我们知道许多网页动态特效都是由FLASH或JQUERY之类的JS特效库实现的实际上现在CSS3也能实现很多类似效果了,只是在各种浏览器中兼 ...
- ps怎么制作流体_PS教程:制作渐变流体效果海报
相信大家都看到过一些很酷的使用渐变流体的海报,此类海报一般都充满活力,而且色彩的饱和度都很高,因为这样更能让作品脱颖而出. 看到这些非常有立体感的渐变色彩,大家可能以为只有用很复杂的三维软件才能够做出 ...
- python打出由边框包围的_python opencv 图像边框(填充)添加及图像混合的实现方法(末尾实现类似幻灯片渐变的效果)...
图像边框的实现 图像边框设计的主要函数 cv.copyMakeBorder()--实现边框填充 主要参数如下: 参数一:源图像--如:读取的img 参数二--参数五分别是:上下左右边的宽度--单位:像 ...
- jQuery中的渐变动画效果
jQuery中的渐变动画效果jQuery中的渐变动画效果 转载于:https://www.cnblogs.com/DreamDrive/p/5780292.html
- CSS和JS两种颜色渐变文字效果代码
js实现颜色渐变文字效果代码: <!-- js颜色渐变色文字 --> <div id="moml"> <div style="text-al ...
- android 底部tab效果,Android 仿微信底部渐变Tab效果
先来看一下效果图 除了第三个的发现Tab有所差别外,其他的基本还原了微信的底部Tab渐变效果 每个Tab都是一个自定义View,根据ImageView的tint属性来实现颜色渐变效果,tint属性的使 ...
- Flutter SliverAnimatedOpacity 透明渐变动画效果
志在巅峰的攀登者,不会陶醉在沿途的某个脚印之中,在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天.每周,都会留下一些脚印,就是这些创作的 ...
- Flutter透明度渐变动画Opacity实现透明度渐变动画效果
题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 在Flutter 中实 ...
- Flutter透明度渐变动画FadeTransition实现透明度渐变动画效果
题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 在Flutter 中实 ...
最新文章
- R语言包_reshape2
- hdu 3183 st表
- I春秋——web Write up(二)
- 数据库四种事务隔离级别详解
- 存储过程 传 datatable
- 产品经理有哪些类型?
- android 键盘遮盖输入框_Android软键盘挡住输入框的终极解决方案
- 浅谈C# Socket编程及C#如何使用多线程
- Storyboard使用心得
- 情侣的网站代码java_GitHub - Mutiantian/lovers-website: 程序员的情侣网站 (programmer's website of lovers)...
- hsql转换oracle,Hive系列之HSQL转换成MapReduce过程
- A-PDF Watermark
- 思科服务器如何进入网站,思科路由器怎么进入设置网站
- Failed to list versions for
- NYOJ779 兰州烧饼
- ei指什么_今天说一下EI是什么
- [Windows10]Win10如何获取最高管理员权限
- 联想拯救者y9000p和r9000p的区别
- Windows批处理脚本(BAT,CMD)简明教程
- 格里高利历java_java – 从Hijri日期字符串中获取格里高利日期