【Three.js】粒子爱心

文章目录

  • 前言
  • 三维心形函数
  • 发光shader
  • 使用对象键值对去重思路
  • 最后
  • 相关项目


【Three.js】粒子爱心_第1张图片

前言

最近很火的电视剧《点燃我,温暖你》男主角学神和女主角课代表计算机考试实现的跳动的爱心,那我也来做一个粒子爱心送给女朋友。因为不想直接加载心形的模型文件作为基础,所以主要思路是三维直角坐标系内,通过心形函数绘制图形。然后呢,细化到空间中坐标粒子的发光闪烁特效。实现思路讲完了,讲一下性能优化,因为通过函数找心形表面粒子的过程是需要遍历的(没办法令函数直接 = 0,只能取<0的数据点,取最大、最小值,再去重),多层遍历嵌套会降低页面加载速度,所以这里的思想是构建对象,因为去掉了一层循环,肯定是快很多的,只牺牲一点点内存构建对象。由于对象的键值对查找几乎不用时间,不受下标影响,就可以将性能发挥到极致。

三维心形函数

// Get surface points
// Calc xRange: [-1.12, 1.12]; yRange: [-0.96, 1.2]; zRange: [-0.64, 0.64]
// f() = (x^2 + 9/4 * z^2 + y^2 + 1)^3 - x^2 * y^3 - 9/80 * z^2 * y^3
const func = Math.pow(Math.pow(x, 2) + 9 / 4 * Math.pow(z, 2) + Math.pow(y, 2) - 1, 3) - Math.pow(x, 2) * Math.pow(y, 3) - 9 / 80 * Math.pow(z, 2) * Math.pow(y, 3)
if (func == 0) {
	// you know
}

发光shader

<script type="x-shader/x-vertex" id="vertexshader">
 varying vec2 vUv;
  void main() {
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  }
script>
<script type="x-shader/x-fragment" id="fragmentshader">
  uniform sampler2D baseTexture;
  uniform sampler2D bloomTexture;
  varying vec2 vUv;
  void main() {
    gl_FragColor = (texture2D(baseTexture, vUv) + vec4(1.0) * texture2D(bloomTexture, vUv));
  }
script>

使用对象键值对去重思路

function objArrDistinct(objArr) {
  let resultArr = [], itemKeyVal = {}
  objArr.forEach(item => {
    if (!itemKeyVal[`${item.x}_${item.y}_${item.z}`]) {
      itemKeyVal[`${item.x}_${item.y}_${item.z}`] = true
      resultArr.push(item)
    }
  })
  return resultArr
}

最后

对比一下,谁的爱心更好看呢?(●ˇ∀ˇ●)

相关项目

——坦克大战
—— 立体库房
—— 圣诞树
✅—— 程序员升职记
—— 投个篮吧
——粒子爱心

你可能感兴趣的:(three.js,前端,javascript)