three 点位图
结果图
关键点
shader
const vertexShader = `
precision mediump float;varying vec3 vNormal;
varying vec3 vPosition;
varying vec2 vUv;
varying vec3 vColor;uniform vec2 uResolution;
uniform sampler2D uTexture;
uniform sampler2D uDispanecmentTexture;attribute float aParticlesIntensity;
attribute float aAngle ;void main(){vec3 newPosition=position;/*Dispanecment*/// 读取canvas纹理中的红色通道作为R,影响粒子偏移float dispanecmentIntensity=texture2D(uDispanecmentTexture,uv).r;// 关键点:smoothstep// 这里0.1是为了过滤掉一些极小值,让图像再鼠标悬浮后能够复原。//同时设置一个0.7,让鼠标离开后能够保留粒子偏移后的轨迹一段时间dispanecmentIntensity =smoothstep( 0.1,0.7,dispanecmentIntensity);// 粒子的偏移向量,这里在xy平面进行随机旋转,在z轴上进行随机偏移vec3 displacement=vec3(cos(aAngle)*0.2,sin(aAngle)*0.2,1.0);displacement=normalize(displacement);displacement*=dispanecmentIntensity;displacement*=3.0;displacement*=aParticlesIntensity;newPosition+=displacement;float picIntensity= texture2D(uTexture,uv).r;vec4 modelPosition=modelMatrix*vec4(newPosition,1.);vec4 viewPosition=viewMatrix*modelPosition;vec4 projectedPosition=projectionMatrix*viewPosition;gl_Position=projectedPosition;// 计算法线变换矩阵:逆矩阵并转置mat3 normalMatrix=transpose(inverse(mat3(modelMatrix)));// 使用法线变换矩阵变换法线vec3 transformedNormal=normalize(normalMatrix*normal);vNormal=transformedNormal;vPosition=modelPosition.xyz;// 粒子动画的初始模版gl_PointSize=0.08*picIntensity*uResolution.y;gl_PointSize*=(1./-viewPosition.z);vColor=vec3(pow(picIntensity,2.0 ));
}
`const fragmentShader = `
precision mediump float;uniform vec2 uResolution;uniform vec3 uSunDirection;
uniform vec3 uAtmosphereDayColor;
uniform vec3 uAtmosphereNightColor;
uniform sampler2D uTexture;varying vec3 vNormal;
varying vec3 vPosition;
varying vec3 vColor;void main(){vec3 viewDirection=normalize(vPosition-cameraPosition);vec3 color=vec3(0.6392, 0.0392, 0.0392);vec2 uv=gl_PointCoord;float distanceToCenter=distance(uv,vec2(0.5,0.5) );if(distanceToCenter>0.5)discard;// color=vec3(alpha);gl_FragColor=vec4(vColor,1.0);#include <tonemapping_fragment>#include <colorspace_fragment>
}
`const texture = textureLoader.load(// "https://coderfmc.github.io/three.js-demo/picture-1.png""../textures/kandao3.jpg");//modelconst material = new THREE.ShaderMaterial({vertexShader: vertexShader,fragmentShader: fragmentShader,uniforms: {uResolution: {value: sizes.resolution,},uTime: {value: 0,},uTexture: new THREE.Uniform(texture),uDispanecmentTexture: new THREE.Uniform(dispanecment.texture),},});
texture2D(uTexture, uv).r
是用于从纹理中采样像素值并提取红色通道的代码,常用于获取纹理的灰度信息(当纹理是灰度图时)
一些单词
Raycaster
是一个强大的工具,用于在 3D 场景中进行射线检测(射线与物体的碰撞检测)。它可以模拟 “光线投射”,判断射线是否与场景中的物体相交,常用于实现鼠标拾取(点击选中 3D 物体)、碰撞检测、视线检测等交互功能
displacementMap
(位移贴图)是一种能够通过纹理灰度值来改变几何体表面顶点位置的技术,从而创造出真实的表面凹凸效果。你提到的 uDisplacementTexture
通常是在自定义着色器材质中引用位移纹理的 uniform 变量名,用于在 GLSL 着色器中手动处理位移效果
GammaCorrectionPass
是用于处理 Gamma 校正的后期处理通道,它的主要作用是确保场景中的颜色在不同设备和显示环境下保持一致的视觉效果,解决画面过暗、色彩失真等问题
星星发光的效果
UnrealBloomPass
是 Three.js 中用于实现类似 Unreal Engine 风格 bloom(泛光 / 辉光)效果的后期处理通道,能为场景中的高亮区域添加柔和的发光效果,增强画面的视觉冲击力和氛围感
TubeGeometry
是一种用于生成 “管状几何体” 的基础几何类,核心功能是围绕一条自定义的 3D 路径(曲线)生成具有固定半径、管壁厚度的管状网格模型,广泛用于模拟管道、线缆、藤蔓、轨道等线性延伸的 3D 物体。