点(Points)
一个用于显示点的类。 由WebGLRenderer渲染的点使用?gl.POINTS。
构造器
Points( geometry :?Geometry, material :?Material?)
geometry?—— (可选)是一个Geometry或者BufferGeometry的实例,默认值是一个新的BufferGeometry。 material?—— (可选) 是一个对象,默认值是一个具有随机颜色的新的PointsMaterial。
点材质(PointsMaterial)
Points使用的默认材质。
PointsMaterial( parameters :?Object?)
parameters?- (可选)用于定义材质外观的对象,具有一个或多个属性。 材质的任何属性都可以从此处传入(包括从Material继承的任何属性)。
属性color例外,其可以作为十六进制字符串传递,默认情况下为?0xffffff(白色),内部调用Color.set(color)。
利用 形状 创建粒子
例:?
const count=50
const particlesGeometry=new THREE.SphereBufferGeometry(1,32,32);
const particlesMaterial=new THREE.PointsMaterial();
particlesMaterial.size=0.2;
particlesMaterial.sizeAttenuation=false
const particles=new THREE.Points(particlesGeometry,particlesMaterial)
scene.add(particles)
?
指定点的大小是否因相机深度而衰减。(仅限透视摄像头。)默认为true。
particlesMaterial.sizeAttenuation=true
?
?利用数组创建粒子
?
const count=500
// const particlesGeometry=new THREE.SphereBufferGeometry(1,32,32);
const particlesGeometry=new THREE.BufferGeometry();
const positions=new Float32Array(count*3)
for(let i=0;i<count*3;i++){
positions[i]=Math.random()
}
particlesGeometry.setAttribute("position",
new THREE.BufferAttribute(positions,3)
)
const particlesMaterial=new THREE.PointsMaterial();
particlesMaterial.size=0.2;
particlesMaterial.sizeAttenuation=false
const particles=new THREE.Points(particlesGeometry,particlesMaterial)
scene.add(particles)
?设置例子材质贴图
贴纸素材:
?
const textureLoader=new THREE.TextureLoader();
const textures=textureLoader.load('textures/particles/2.png')
const count=50000
// const particlesGeometry=new THREE.SphereBufferGeometry(1,32,32);
const particlesGeometry=new THREE.BufferGeometry();
const positions=new Float32Array(count*3)
for(let i=0;i<count*3;i++){
positions[i]=(Math.random()-0.5)*10
}
particlesGeometry.setAttribute("position",
new THREE.BufferAttribute(positions,3)
)
const particlesMaterial=new THREE.PointsMaterial();
particlesMaterial.size=0.2;
particlesMaterial.sizeAttenuation=true
particlesMaterial.color=new THREE.Color('red')
particlesMaterial.map=textures
const particles=new THREE.Points(particlesGeometry,particlesMaterial)
scene.add(particles)
?
问题 存在着边缘
?加入alphMap
const textureLoader=new THREE.TextureLoader();
const textures=textureLoader.load('textures/particles/2.png')
particlesMaterial.transparent=true
particlesMaterial.alphaMap=textures
?好了一些但是依然存在
?
设置运行alphaTest时要使用的alpha值。如果不透明度低于此值,则不会渲染材质。默认值为0。
particlesMaterial.alphaTest=0.001;
这样就好了很多?
?但是依然有边出现
?particlesMaterial.depthWrite=false;
.depthTest?:?Boolean
是否在渲染此材质时启用深度测试。默认为?true。
渲染此材质是否对深度缓冲区有任何影响。默认为true。
这样就没有问题了?
让每个小圈圈不同颜色?
在使用此材质显示对象时要使用何种混合。 必须将其设置为CustomBlending才能使用自定义blendSrc,?blendDst?或者 [page:Constant blendEquation]。 混合模式所有可能的取值请参阅constants。默认值为NormalBlending。
是否使用顶点着色。默认值为THREE.NoColors。 其他选项有THREE.VertexColors?和?THREE.FaceColors。
const textureLoader=new THREE.TextureLoader();
const textures=textureLoader.load('textures/particles/2.png')
const count=5000
// const particlesGeometry=new THREE.SphereBufferGeometry(1,32,32);
const particlesGeometry=new THREE.BufferGeometry();
const positions=new Float32Array(count*3)
const colors=new Float32Array(count*3)
for(let i=0;i<count*3;i++){
positions[i]=(Math.random()-0.5)*10
colors[i]=Math.random()
}
particlesGeometry.setAttribute("position",
new THREE.BufferAttribute(positions,3)
)
particlesGeometry.setAttribute("color",
new THREE.BufferAttribute(colors,3)
)
const particlesMaterial=new THREE.PointsMaterial();
particlesMaterial.size=0.2;
particlesMaterial.sizeAttenuation=true
particlesMaterial.color=new THREE.Color('#ff88cc')
particlesMaterial.transparent=true
particlesMaterial.alphaMap=textures
particlesMaterial.blending=THREE.AdditiveBlending
particlesMaterial.vertexColors=true
particlesMaterial.depthWrite=false;
const particles=new THREE.Points(particlesGeometry,particlesMaterial)
scene.add(particles)
?粒子动画
该标志位指明当前 attribute 已经被修改过,且需要再次送入 GPU 处理。当开发者改变了该队列的值,则标志位需要设置为 true。
?
const tick = () => {
const elapsedTime = clock.getElapsedTime();
for(let i=0;i<count;i++){
const x=particlesGeometry.attributes.position.array[i*3]
particlesGeometry.attributes.position.array[i*3+1]=Math.sin(elapsedTime+x)
}
particlesGeometry.attributes.position.needsUpdate=true
// Update controls
controls.update();
// Render
renderer.render(scene, camera);
// Call tick again on the next frame
window.requestAnimationFrame(tick);
};
今日完整代码
import "./style.css";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import * as dat from "dat.gui";
import ky from "kyouka";
/**
* Base
*/
// Debug
const gui = new dat.GUI();
// Canvas
const canvas = document.querySelector("canvas.webgl");
// Scene
const scene = new THREE.Scene();
/**
* Textures
*/
const textureLoader=new THREE.TextureLoader();
const textures=textureLoader.load('textures/particles/2.png')
const count=5000
// const particlesGeometry=new THREE.SphereBufferGeometry(1,32,32);
const particlesGeometry=new THREE.BufferGeometry();
const positions=new Float32Array(count*3)
const colors=new Float32Array(count*3)
for(let i=0;i<count*3;i++){
positions[i]=(Math.random()-0.5)*10
colors[i]=Math.random()
}
particlesGeometry.setAttribute("position",
new THREE.BufferAttribute(positions,3)
)
particlesGeometry.setAttribute("color",
new THREE.BufferAttribute(colors,3)
)
const particlesMaterial=new THREE.PointsMaterial();
particlesMaterial.size=0.2;
particlesMaterial.sizeAttenuation=true
particlesMaterial.color=new THREE.Color('#ff88cc')
particlesMaterial.transparent=true
particlesMaterial.alphaMap=textures
particlesMaterial.blending=THREE.AdditiveBlending
particlesMaterial.vertexColors=true
particlesMaterial.depthWrite=false;
const particles=new THREE.Points(particlesGeometry,particlesMaterial)
scene.add(particles)
/**
* Sizes
*/
const sizes = {
width: window.innerWidth,
height: window.innerHeight,
};
window.addEventListener("resize", () => {
// Update sizes
sizes.width = window.innerWidth;
sizes.height = window.innerHeight;
// Update camera
camera.aspect = sizes.width / sizes.height;
camera.updateProjectionMatrix();
// Update renderer
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
});
/**
* Camera
*/
// Base camera
const camera = new THREE.PerspectiveCamera(
75,
sizes.width / sizes.height,
0.1,
100
);
camera.position.z = 3;
scene.add(camera);
// Controls
const controls = new OrbitControls(camera, canvas);
controls.enableDamping = true;
/**
* Renderer
*/
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
});
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
/**
* Animate
*/
const clock = new THREE.Clock();
const tick = () => {
const elapsedTime = clock.getElapsedTime();
for(let i=0;i<count;i++){
const x=particlesGeometry.attributes.position.array[i*3]
particlesGeometry.attributes.position.array[i*3+1]=Math.sin(elapsedTime+x)
}
particlesGeometry.attributes.position.needsUpdate=true
// Update controls
controls.update();
// Render
renderer.render(scene, camera);
// Call tick again on the next frame
window.requestAnimationFrame(tick);
};
tick();
|