当前位置: 首页 > news >正文

使用three.js 实现蜡烛效果

使用three.js 实现蜡烛效果

在这里插入图片描述

import * as THREE from "three"
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(3, 5, 8).setLength(15);
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x101005);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {camera.aspect = innerWidth / innerHeight;camera.updateProjectionMatrix()renderer.setSize(innerWidth, innerHeight);
})var controls = new OrbitControls(camera, renderer.domElement);
controls.enablePan = false;
controls.minPolarAngle = THREE.MathUtils.degToRad(60);
controls.maxPolarAngle = THREE.MathUtils.degToRad(95);
controls.minDistance = 4;
controls.maxDistance = 20;
controls.autoRotate = true;
controls.autoRotateSpeed = 1;
controls.target.set(0, 2, 0);
controls.update();var light = new THREE.DirectionalLight(0xffffff, 0.025);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.0625));var casePath = new THREE.Path();
casePath.moveTo(0, 0);
casePath.lineTo(0, 0);
casePath.absarc(1.5, 0.5, 0.5, Math.PI * 1.5, Math.PI * 2);
casePath.lineTo(2, 1.5);
casePath.lineTo(1.99, 1.5);
casePath.lineTo(1.9, 0.5);
var caseGeo = new THREE.LatheGeometry(casePath.getPoints(), 64);
var caseMat = new THREE.MeshStandardMaterial({ color: "silver" });
var caseMesh = new THREE.Mesh(caseGeo, caseMat);
caseMesh.castShadow = true;var paraffinPath = new THREE.Path();
paraffinPath.moveTo(0, -.25);
paraffinPath.lineTo(0, -.25);
paraffinPath.absarc(1, 0, 0.25, Math.PI * 1.5, Math.PI * 2);
paraffinPath.lineTo(1.25, 0);
paraffinPath.absarc(1.89, 0.1, 0.1, Math.PI * 1.5, Math.PI * 2);
var paraffinGeo = new THREE.LatheGeometry(paraffinPath.getPoints(), 64);
paraffinGeo.translate(0, 1.25, 0);
var paraffinMat = new THREE.MeshStandardMaterial({ color: 0xffff99, side: THREE.BackSide, metalness: 0, roughness: 0.75 });
var paraffinMesh = new THREE.Mesh(paraffinGeo, paraffinMat);
caseMesh.add(paraffinMesh);var candlewickProfile = new THREE.Shape();
candlewickProfile.absarc(0, 0, 0.0625, 0, Math.PI * 2);var candlewickCurve = new THREE.CatmullRomCurve3([new THREE.Vector3(0, 0, 0),new THREE.Vector3(0, 0.5, -0.0625),new THREE.Vector3(0.25, 0.5, 0.125)
]);var candlewickGeo = new THREE.ExtrudeGeometry(candlewickProfile, {steps: 8,bevelEnabled: false,extrudePath: candlewickCurve
});var colors = [];
var color1 = new THREE.Color("black");
var color2 = new THREE.Color(0x994411);
var color3 = new THREE.Color(0xffff44);
for (let i = 0; i < candlewickGeo.attributes.position.count; i++) {if (candlewickGeo.attributes.position.getY(i) < 0.4) {color1.toArray(colors, i * 3);}else {color2.toArray(colors, i * 3);};if (candlewickGeo.attributes.position.getY(i) < 0.15) color3.toArray(colors, i * 3);
}
candlewickGeo.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3));
candlewickGeo.translate(0, 0.95, 0);
var candlewickMat = new THREE.MeshBasicMaterial({ vertexColors: true });var candlewickMesh = new THREE.Mesh(candlewickGeo, candlewickMat);
caseMesh.add(candlewickMesh);// candle light
var candleLight = new THREE.PointLight(0xffaa33, 1, 5, 2);
candleLight.position.set(0, 3, 0);
candleLight.castShadow = true;
caseMesh.add(candleLight);
var candleLight2 = new THREE.PointLight(0xffaa33, 1, 10, 2);
candleLight2.position.set(0, 4, 0);
candleLight2.castShadow = true;
caseMesh.add(candleLight2);var flameMaterials = [];
function flame(isFrontSide) {let flameGeo = new THREE.SphereGeometry(0.5, 32, 32);flameGeo.translate(0, 0.5, 0);let flameMat = getFlameMaterial(true);flameMaterials.push(flameMat);let flame = new THREE.Mesh(flameGeo, flameMat);flame.position.set(0.06, 1.2, 0.06);flame.rotation.y = THREE.MathUtils.degToRad(-45);caseMesh.add(flame);
}flame(false);
flame(true);// table
var tableGeo = new THREE.CylinderGeometry(14, 14, 0.5, 64);
tableGeo.translate(0, -0.25, 0);
var tableMat = new THREE.MeshStandardMaterial({ map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/hardwood2_diffuse.jpg"), metalness: 0, roughness: 0.75 });
var tableMesh = new THREE.Mesh(tableGeo, tableMat);
tableMesh.receiveShadow = true;tableMesh.add(caseMesh);
scene.add(tableMesh);var clock = new THREE.Clock();
var time = 0;render();
function render() {requestAnimationFrame(render);time += clock.getDelta();flameMaterials[0].uniforms.time.value = time;flameMaterials[1].uniforms.time.value = time;candleLight2.position.x = Math.sin(time * Math.PI) * 0.25;candleLight2.position.z = Math.cos(time * Math.PI * 0.75) * 0.25;candleLight2.intensity = 2 + Math.sin(time * Math.PI * 2) * Math.cos(time * Math.PI * 1.5) * 0.25;controls.update();renderer.render(scene, camera);
}function getFlameMaterial(isFrontSide) {let side = isFrontSide ? THREE.FrontSide : THREE.BackSide;return new THREE.ShaderMaterial({uniforms: {time: { value: 0 }},vertexShader: `uniform float time;varying vec2 vUv;varying float hValue;float random (in vec2 st) {return fract(sin(dot(st.xy,vec2(12.9898,78.233)))* 43758.5453123);}float noise (in vec2 st) {vec2 i = floor(st);vec2 f = fract(st);// Four corners in 2D of a tilefloat a = random(i);float b = random(i + vec2(1.0, 0.0));float c = random(i + vec2(0.0, 1.0));float d = random(i + vec2(1.0, 1.0));// Smooth Interpolation// Cubic Hermine Curve.  Same as SmoothStep()vec2 u = f*f*(3.0-2.0*f);// u = smoothstep(0.,1.,f);// Mix 4 coorners percentagesreturn mix(a, b, u.x) +(c - a)* u.y * (1.0 - u.x) +(d - b) * u.x * u.y;}void main() {vUv = uv;vec3 pos = position;pos *= vec3(0.8, 2, 0.725);hValue = position.y;//float sinT = sin(time * 2.) * 0.5 + 0.5;float posXZlen = length(position.xz);pos.y *= 1. + (cos((posXZlen + 0.25) * 3.1415926) * 0.25 + noise(vec2(0, time)) * 0.125 + noise(vec2(position.x + time, position.z + time)) * 0.5) * position.y; // flame heightpos.x += noise(vec2(time * 2., (position.y - time) * 4.0)) * hValue * 0.0312; // flame tremblingpos.z += noise(vec2((position.y - time) * 4.0, time * 2.)) * hValue * 0.0312; // flame tremblinggl_Position = projectionMatrix * modelViewMatrix * vec4(pos,1.0);}`,fragmentShader: `varying float hValue;varying vec2 vUv;// honestly stolen from https://www.shadertoy.com/view/4dsSzrvec3 heatmapGradient(float t) {return clamp((pow(t, 1.5) * 0.8 + 0.2) * vec3(smoothstep(0.0, 0.35, t) + t * 0.5, smoothstep(0.5, 1.0, t), max(1.0 - t * 1.7, t * 7.0 - 6.0)), 0.0, 1.0);}void main() {float v = abs(smoothstep(0.0, 0.4, hValue) - 1.);float alpha = (1. - v) * 0.99; // bottom transparencyalpha -= 1. - smoothstep(1.0, 0.97, hValue); // tip transparencygl_FragColor = vec4(heatmapGradient(smoothstep(0.0, 0.3, hValue)) * vec3(0.95,0.95,0.4), alpha) ;gl_FragColor.rgb = mix(vec3(0,0,1), gl_FragColor.rgb, smoothstep(0.0, 0.3, hValue)); // blueish for bottomgl_FragColor.rgb += vec3(1, 0.9, 0.5) * (1.25 - vUv.y); // make the midst brightergl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.66, 0.32, 0.03), smoothstep(0.95, 1., hValue)); // tip}`,transparent: true,side: side})}/*** 名称: 蜡烛* 作者: 优雅永不过时 https://github.com/z2586300277
*/

相关文章:

使用three.js 实现蜡烛效果

使用three.js 实现蜡烛效果 import * as THREE from "three" import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"var scene new THREE.Scene(); var camera new THREE.PerspectiveCamera(60, window.innerWidth / window.in…...

手动在Linux服务器上部署并运行SpringBoot项目(新手向)

背景 当我们在本地开发完应用并且测试通过后&#xff0c;接着就要部署在服务器上启动。 步骤 1.先用maven将SpringBoot应用当成jar包 2.生成jar文件并复制此文件 3.xshell远程连接linux服务器&#xff0c;在xftp将文件粘贴到linux服务器&#xff0c;这里我放在/usr/local…...

自媒体短视频如何制作?

从0到1打造爆款短视频!300条视频创作经验分享,助你玩转自媒体! 想用短视频玩转自媒体却不知道从何下手?别担心!从21年开始接触短视频的我,断断续续创作了300多条视频,踩过不少坑,也收获了一些心得,核心秘诀就是:账号内容垂直化 + 明确受众群体! 我将从主题确定、脚本…...

2024年河南省职业技能竞赛(网络建设与运维赛项)

模块二&#xff1a;网络建设与调试 说明&#xff1a; 1.所网络设备在创建之后都可以直接通过 SecureCRT 软件 telnet 远程连接操作。 2.要求在全员化竞赛平台中保留竞赛生成的所有虚拟主机。 3.题目中所有所有的密码均为 Pass-1234&#xff0c;若未按照要求设置&#xff0c;涉 …...

git--git reset

HEAD 单独一个HEAD eg:git diff HEAD 表示当前结点。 HEAD~ HEAD~只处理当前分支。 注意&#xff1a;master分支的上一个结点是tmp分支的所在的结点fc11b74, 79f109e才是master的第二个父节点。 HEAD~ 当前结点的父节点。 HEAD~1 当前结点的父节点。 HEAD~n 当前结点索…...

Spring Boot的实用内置功能详解

Spring Boot作为一款备受欢迎的Java框架&#xff0c;以其简洁、高效和易用的特点&#xff0c;赢得了广大开发者的青睐。其内置的多种功能更是为开发者提供了极大的便利&#xff0c;本文将详细介绍Spring Boot中记录请求数据、请求/响应包装器、特殊的过滤器Filter以及Controlle…...

撸猫变梳毛?怎么解决猫咪掉毛问题?好用的宠物空气净化器推荐

秋风一吹&#xff0c;新一轮的猫咪换毛季又到了&#xff0c;这也意味着我失去了撸猫自由。我每天的治愈方式就是下班撸猫&#xff0c;抚摸着柔软的毛发&#xff0c;好像一天的烦恼都消除了。可是一到换毛季&#xff0c;猫还没撸两下&#xff0c;先从猫咪身上带下一手毛&#xf…...

人声分离免费软件,六款好用软件处理音乐更轻松!

在这个数字化音乐时代&#xff0c;无论是专业音乐人还是音乐爱好者&#xff0c;都渴望在创作与编辑过程中拥有更多便捷高效的工具。人声分离技术&#xff0c;作为音乐后期制作中的一项关键技术&#xff0c;能够精准地将歌曲中的人声与伴奏分离&#xff0c;极大地拓宽了音乐创作…...

数据分析Power BI设置万为单位的数据

玩过Power BI的同学都知道&#xff0c;power BI在度量值设置单位里&#xff0c;唯独没有万这个单位&#xff0c;但是我们可以自定义&#xff0c;操作过程如下&#xff1a; 1.用DAX新建单位表 单位 SELECTCOLUMNS( { ( "元", 1), ("万",10000), ("千…...

(AI 生成) 新时代游击方式: 利用 “灵活就业“ 红利

注意: 本文内容为 AI 大模型生成, 仅供参考. 提示词: 写一篇短文, 500 字左右, 标题为: 新时代游击方式: 利用 “灵活就业” 红利 1 豆包 《新时代游击方式&#xff1a;利用“灵活就业”红利》 在新时代的大舞台上&#xff0c;“灵活就业”犹如一块熠熠生辉的宝藏&#xff0c…...

Unity UndoRedo(撤销重做)功能

需求 撤销与重做功能 思考 关于记录的数据的两点思考&#xff1a; 记录操作记录影响显示和逻辑的所有数据 很显然这里就要考虑取舍了&#xff1a; 记录操作 这种方案只需要记录每一步的操作&#xff0c;具体这个操作要怎么渲染和实现出来完全需要自己去实现&#xff0c;这…...

28条有关人工智能的名言

当谈到人工智能&#xff08;AI&#xff09;的潜力和潜在风险&#xff0c;以及无人类干预的机器学习和推理过程时&#xff0c;目前尚存在许多不同的观点。 只有时间会告诉我们&#xff0c;这些语录中哪一条是最接近未来的真实情况的。在我们尚未到达目的地之前&#xff0c;想一想…...

搞机器视觉项目看不起搞机器视觉培训的,实际上怎么样

搞机器视觉项目第一要务就是验收回款&#xff0c;往往欠款的非常严重&#xff0c;多数还要打通人际关系需要大量的成本。大多数机器视觉检测项目具有一定的风险&#xff0c;客户要求不明确&#xff0c;技术评估不充分&#xff0c;往往伴随着失败的可能性。所以做项目又累又担风…...

使用Jenkins部署项目

部署中的痛点 为什么要用Jenkins&#xff1f;我说下我以前开发的痛点&#xff0c;在一些中小型企业&#xff0c;每次开发一个项目完成后&#xff0c;需要打包部署&#xff0c;可能没有专门的运维人员&#xff0c;只能开发人员去把项目打成一个exe包&#xff0c;可能这个项目已…...

【机器学习与神经网络荣获诺贝尔奖】科学边界的扩展及技术革新

【机器学习与神经网络荣获诺贝尔奖】科学边界的扩展及技术革新 1&#xff09;科学交叉融合的体现2&#xff09;方法论的创新3&#xff09;社会影响的考量 一、机器学习与神经网络的发展前景1&#xff09;生产制造领域2&#xff09;金融领域3&#xff09;医疗领域 二、机器学习和…...

Javascript扩展符号(...)使用说明

在 ES6 中&#xff0c;扩展运算符&#xff08;spread operator&#xff09;... 可以用于在函数调用、数组字面量或对象字面量中展开数组或对象。以下是扩展运算符的一些常见用法&#xff1a; 1. 在函数调用中使用扩展运算符 扩展运算符可以在函数调用时展开数组或对象&#x…...

giugughk

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…...

【微服务】网关 - Gateway(下)(day8)

网关过滤工厂 在上一篇文章中&#xff0c;主要是对网关进行了一个总体的介绍&#xff0c;然后对网关中的断言进行了一个描述。在这篇文章中&#xff0c;主要是对网关中的最后一大核心——过滤进行介绍。 当客户端发送过来的请求经过断言之后&#xff0c;如果还想在请求前后添…...

【C#】创建一个控制台应用程序来管理学生成绩

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 在C#中创建一个控制台应用程序来管理学生成绩编写程序程序解释 在C#中创建一个控制台应用程序来管理学生成绩 在这篇文章中&#xff0c;我将向你展示如何使用C#创建…...

鸿蒙开发之ArkUI 界面篇 三十四 容器组件Tabs 自定义TabBar

如果需要修改Tabs的图标和文字之间的距离我们该怎么办呢&#xff1f;好在tabBar是联合类型&#xff0c;提供了自定义tabBar&#xff0c;这里就可以显示特殊图标或者是文字图片&#xff0c;如下图&#xff1a; 这里定义了myBuilder的函数&#xff0c;用了 来修饰&#xff0c;没有…...

AI核身-金融场景凭证篡改检测YOLO原理

引言 YOLO (You Only Look Once) 模型是一种先进的实时目标检测算法&#xff0c;它在计算机视觉领域具有重要的地位。YOLO以其速度和准确性而闻名&#xff0c;能够快速识别图像和视频中的各种物体。这使得它在自动驾驶、安全监控、机器人技术、医学影像分析等众多领域都有着广…...

鹅厂JS面试题——0.1+0.2=0.3吗?

首先公布答案:在JavaScript 中&#xff0c;0.1 0.2 ≠ 0.3 为什么&#xff1f; JavaScript 中的数字使用 IEEE 754 标准的双精度浮点数&#xff08;64 位&#xff09;进行表示。这种表示方式在处理十进制小数时&#xff0c;不能精确地表示某些数字。比如0.1 和 0.2 这样的十进…...

软件功能测试重点和流程有哪些?专业软件测评服务公司推荐

软件功能测试就是对产品的各功能进行验证&#xff0c;根据功能测试用例&#xff0c;逐项测试&#xff0c;检查产品是否达到用户要求的功能。功能测试也叫黑盒测试或数据驱动测试&#xff0c;只需考虑需要测试的各个功能&#xff0c;不需要考虑整个软件的内部结构及代码.一般从软…...

【数据结构】AVL树(C++实现)

文章目录 前言AVL树节点的定义AVL树的插入AVL树的旋转AVL树的验证AVL树的删除AVL树的性能与源码 前言 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&…...

AMD新推EPYC与MI325X,挑战英伟达AI市场地位

在人工智能&#xff08;AI&#xff09;加速器领域&#xff0c;AMD近日于美国旧金山举办的“推进人工智能”&#xff08;Advancing AI Event&#xff09;活动中&#xff0c;宣布了一系列新产品的发布&#xff0c;直接对标英伟达&#xff0c;意图在AI芯片市场占据更大份额。 AMD新…...

电脑桌面文件不见了怎么恢复?8个方法帮你解决问题

电脑桌面文件突然不见了凭空消失了怎么恢复&#xff1f;电脑桌面文件日常使用电脑时&#xff0c;很多用户喜欢将重要文件、快捷方式存放在桌面上&#xff0c;以方便快速访问。然而&#xff0c;有时我们会突然发现桌面上的文件不见了。桌面文件消失可能有多种原因&#xff0c;例…...

如果想转行AI领域却不知如何开始?可以试试这五步,超详细_ai行业怎么入行

我看了计算机科学家大卫格维茨写的一篇博客&#xff0c;里面介绍了如果想从事AI行业&#xff0c;却不知道如何开始的话&#xff0c;可以走下面五步&#xff0c;从而达到转行的目的。因为这是个国外作家写的&#xff0c;跟我们国内的情况有一些出入&#xff0c;但是大思路是没有…...

个人博客搭建 | Hexo框架

文章目录 1.Hexo安装2.创建博客3.将博客通过GitHub来部署4.更换主题 1.Hexo安装 Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown&#xff08;或其他标记语言&#xff09;解析文章&#xff0c;在几秒内&#xff0c;即可利用靓丽的主题生成静态网页。搭建Hexo首先要…...

[Gtk] layout.ui

播放器layout&#xff1a; # <?xml version"1.0" encoding"UTF-8"?> <!-- Generated with glade 3.38.2 --> <interface> <requires lib"gtk" version"3.20"/> <object class"GtkWindow"…...

Spring MVC:精通JSON数据返回的几种高效方式

前言 在实际开发中&#xff0c;我们在前后端传送数据通常使用Json格式&#xff0c;而在Spring MVC中返回Json格式的方式有多种&#xff0c;接下来我将介绍其中一些。 准备工作 为了演示Json格式的数据&#xff0c;我们准备一个实体类&#xff0c;例如User&#xff0c;这些可以测…...