javascript
复制代码
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import gsap from 'gsap'
import theVertexShader from './shader/13/vertex.glsl?raw'
import theFragmentShader from './shader/13/fragment.glsl?raw'
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerHeight / window.innerHeight, 0.1, 1000)
camera.position.set(0, 0, 5)
camera.aspect = window.innerWidth / window.innerHeight
scene.add(camera)
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)
// ---------------------------------------------------------------------------
// 加载纹理
const textureLoader = new THREE.TextureLoader()
let texture = textureLoader.load('../public/assets/texture/particles/9.png')
let texture1 = textureLoader.load('../public/assets/texture/particles/10.png')
let texture2 = textureLoader.load('../public/assets/texture/particles/11.png')
const params = {
count: 1000, // 数量
size: 0.1, // 大小
radius: 5, // 半径
branch: 4, // 分支
color: '#ff6030',
outColor: '#1b3984'
}
let geometry = null
let material = null
let point = null
let galaxyColor = new THREE.Color(params.color)
let outGalaxyColor = new THREE.Color(params.outColor)
const generateGalaxy = () => {
// 如果已经存在这些顶点,那么先释放内存,在删除顶点数据
if (point !== null) {
geometry.dispose()
material.dispose()
scene.remove(point)
}
geometry = new THREE.BufferGeometry() // 生成顶点
const position = new Float32Array(params.count * 3) // 顶点位置
const colors = new Float32Array(params.count * 3) // 顶点颜色
const imgIndex = new Float32Array(params.count) // 贴图
const size_arr = new Float32Array(params.count) // 大小
for (let i = 0; i < params.count; i++) {
const current = i * 3
const branchAngel = (i % params.branch) * ((2 * Math.PI) / params.branch)
// 当前点,距离圆心的距离
const distance = Math.random() * params.radius
// 中心点多,外围的点少
const randomX = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5
const randomY = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5
const randomZ = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5
position[current] = Math.cos(branchAngel) * distance + randomX
position[current + 1] = 0 + randomY
position[current + 2] = Math.sin(branchAngel) * distance + randomZ
const mixColor = galaxyColor.clone()
mixColor.lerp(outGalaxyColor, distance / params.radius)
// 设置颜色
colors[current] = mixColor.r
colors[current + 1] = mixColor.g
colors[current + 2] = mixColor.b
// 根据索引值,设置不同的贴图
imgIndex[current] = i % 3
// 顶点的大小
size_arr[current] = Math.random()
}
geometry.setAttribute('position', new THREE.BufferAttribute(position, 3))
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3))
geometry.setAttribute('imgIndex', new THREE.BufferAttribute(imgIndex, 1))
geometry.setAttribute('asize', new THREE.BufferAttribute(size_arr, 1))
//#region 点材质
// material = new THREE.PointsMaterial({
// color: new THREE.Color(params.color),
// size: params.size,
// map: texture,
// transparent: true,
// alphaMap: texture,
// depthWrite: false,
// sizeAttenuation: true,
// blending: THREE.AdditiveBlending
// })
//#endregion
material = new THREE.ShaderMaterial({
vertexShader: theVertexShader,
fragmentShader: theFragmentShader,
transparent: true,
vertexColors: true,
depthWrite: false,
blending: THREE.AdditiveBlending,
uniforms: {
uTime: {
value: 0
},
uTexture: {
value: texture
},
uTexture1: {
value: texture1
},
uTexture2: {
value: texture2
},
uColor: {
value: galaxyColor
}
}
})
point = new THREE.Points(geometry, material)
scene.add(point)
}
generateGalaxy()
// ---------------------------------------------------------------------------
//#region
const renderer = new THREE.WebGLRenderer()
renderer.shadowMap.enabled = true
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
controls.dampingFactor = 0.01
const clock = new THREE.Clock()
function animate() {
// controls.update()
const elapsedTime = clock.getElapsedTime()
material.uniforms.uTime.value = elapsedTime
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(window.devicePixelRatio)
})
//#endregion
javascript
复制代码
precision lowp float;
uniform sampler2D uTexture;
uniform sampler2D uTexture1;
uniform sampler2D uTexture2;
varying float vImgIndex;
varying vec3 vColor;
void main() {
// 方案- 1
// gl_FragColor = vec4(gl_PointCoord, 0.0, 1.0);
// 方案- 2 - 设置渐变圆
// float strength = distance(gl_PointCoord,vec2(0.5));
// strength*=2.0;
// strength = 1.0-strength;
// gl_FragColor = vec4(strength);
// 方案- 3 - 圆形点
// float strength = 1.0-distance(gl_PointCoord, vec2(0.5));
// strength = step(0.5, strength);
// gl_FragColor = vec4(strength);
// 方案- 4 - 设置贴图
// vec4 textureColor = texture2D(uTexture, gl_PointCoord);
// gl_FragColor = vec4(textureColor.rgb, textureColor.r);
// 方案- 5 - 设置多种贴图
vec4 textureColor;
if(vImgIndex==0.0) {
textureColor = texture2D(uTexture, gl_PointCoord);
} else if(vImgIndex==1.0) {
textureColor = texture2D(uTexture1, gl_PointCoord);
} else {
textureColor = texture2D(uTexture2, gl_PointCoord);
}
gl_FragColor = vec4(vColor, textureColor.r);
}