一、雷达图
实现原理:图中是一个旋转的渐变扇形,可以通过先实现一个扇形、然后再实现一个渐变扇形,最后再将扇形旋转来达到最终效果
1. 实现一个夹角为O的扇形,已X轴正方向为单位向量M,UV点到(0,0)形成向量N,通过M和N的点乘就可以得到一个夹角,然后判断角度小于O就可以了
2. 实现扇形的渐变色,主要是通过smoothstep实现,smoothstep是在两个值之间取渐变值,这样就可以实现离X轴越远越暗的效果
3. 如何让扇形旋转起来呢,上面已经实现了一个扇形A,通过将扇形B按照一定角度旋转到A,就可以得到对应的渐变色颜色值了,这样一个渐变的旋转角度就可以实现一个旋转的渐变扇形
4. 实现蓝色线圈,也是通过smoothstep函数,一个smoothstep最后会生成0-1的跳变值,如果是两个smoothstep相减会生成一个波峰的颜色值
主要原理是先实现一个扇形渐变的区域,这个不是很复杂,然后通过不断渲染页面时,将该扇形旋转到某个角度即可
const vertex = '\varying vec2 vUv;\void main() {\vUv = uv;\vec4 modelPosition = modelMatrix * vec4(position, 1.0);\gl_Position = projectionMatrix * viewMatrix * modelPosition;\}\';const frag = '\uniform float uTime;\varying vec2 vUv;\float drawCircle(vec2 vUv, float radius) {\float res = length(vUv);\float width = 0.005;\return smoothstep(radius - width, radius, res) - smoothstep(radius, radius + width, res);\}\float drawSector(vec2 vUv, float radius) {\float angle = uTime;\vec2 newvUv = mat2(cos(angle), sin(angle), -sin(angle), cos(angle)) * vUv;\vec2 x = vec2(1.0, 0.0);\vec2 y = vec2(0.0, 1.0);\float res = dot(newvUv, y);\float angle2 = acos(dot(x, normalize(newvUv)));\if (angle2 > 0.0 && angle2 < 1.5707 && length(newvUv) < 0.45 && res > 0.0) {\return 1.0 - smoothstep(0.0, 1.5707, angle2);\} else {\return 0.0;\}\}\void main() {\vec2 newvUv = vUv;\newvUv -= vec2(0.5);\vec3 color = vec3(0.0, 0.0, 0.0);\float circle = drawCircle(newvUv, 0.45);\float circle2 = drawCircle(newvUv, 0.3);\float circle3 = drawCircle(newvUv, 0.1);\color += circle + circle2 + circle3;\color += drawSector(newvUv, 0.45);\gl_FragColor = vec4(color * vec3(0.0, 1.0, 0.0), 1.0);\}\';
三、遮罩层
1. 第一种方法:采用shader中法向量的概念,取法向量和球体上各个坐标点与相机形成的向量之间的点积,离相机位置越近,
越靠近相机位置,点积值越大,且为正值,反之越远,则点积越小,同时可能为负值,这时候用产生的点积数据作为透明度,
即可得到渐变的效果
var vertex ='varying vec3 vVertexWorldPosition;\varying vec3 vVertexNormal;\varying vec4 vFragColor;\void main(){\vVertexNormal = normalize(normalMatrix * normal);\vVertexWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\}';var frag ='uniform vec3 glowColor;\uniform float coeficient;\varying vec3 vVertexNormal;\varying vec3 vVertexWorldPosition;\varying vec4 vFragColor;\void main(){\vec3 worldVertexToCamera = cameraPosition - vVertexWorldPosition;\vec3 viewCameraToVertex = (viewMatrix * vec4(worldVertexToCamera, 0.0)).xyz;\viewCameraToVertex = normalize(viewCameraToVertex);\float intensity = coeficient + dot(vVertexNormal, viewCameraToVertex);\if (intensity < 0.0) {\gl_FragColor = vec4(vec3(0.0, 1.0, 0.0), 1.0);\} else {\gl_FragColor = vec4(glowColor, intensity);\}\}';
2. 第二种方法通过ThreeJS官方提供的样例,使用EffectCompose的方式来实现,其中也是通过添加shader着色器的原理实现的