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);
}