一、雷達圖
實現原理:圖中是一個旋轉的漸變扇形,可以透過先實現一個扇形、然後再實現一個漸變扇形,最後再將扇形旋轉來達到最終效果
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著色器的原理實現的