three.js 实现一个心形的着色器

embedded/2024/10/20 8:01:57/

three.js 实现一个心形的着色器

源链接:https://z2586300277.github.io/three-cesium-examples/#/codeMirror?navigation=ThreeJS&classify=shader&id=heartShader

国内站点预览:http://threehub.cn

github地址: https://github.com/z2586300277/three-cesium-examples

在这里插入图片描述

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';const box = document.getElementById('box')const scene = new THREE.Scene()const camera = new THREE.PerspectiveCamera(75, box.clientWidth / box.clientHeight, 0.1, 1000)camera.position.set(0, 0, 20)const renderer = new THREE.WebGLRenderer()renderer.setSize(box.clientWidth, box.clientHeight)box.appendChild(renderer.domElement)new OrbitControls(camera, renderer.domElement)const composer = new EffectComposer(renderer);const renderPass = new RenderPass(scene, camera);composer.addPass(renderPass);const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 5, 1.2, 0)composer.addPass(bloomPass);window.onresize = () => {renderer.setSize(box.clientWidth, box.clientHeight)camera.aspect = box.clientWidth / box.clientHeightcamera.updateProjectionMatrix()}class HeartCurve extends THREE.Curve {constructor(scale = 1) {super();this.scale = scale;}getPoint(a, optionalTarget = new THREE.Vector3()) {const t = a * Math.PI * 2;const tx = 16 * Math.pow(Math.sin(t), 3);const ty = 13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t);const tz = 0;return optionalTarget.set(tx, ty, tz).multiplyScalar(this.scale);}
}const geometry = new THREE.TubeGeometry(new HeartCurve(0.5), 100, 0.1, 30, false);const vertexShader = `varying vec2 vUv;void main(void) {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);}`;
const fragmentShader = `varying vec2 vUv;uniform float uSpeed;uniform float uTime;uniform vec2 uFade;uniform vec3 uColor;uniform float uDirection;void main() {vec3 color =uColor;float s=0.0;float v=0.0;if(uDirection==1.0){v=vUv.x;s=-uTime*uSpeed;}else{v= -vUv.x;s= -uTime*uSpeed;}float d=mod(  (v + s) ,1.0) ;if(d>uFade.y)discard;else{float alpha = smoothstep(uFade.x, uFade.y, d);if (alpha < 0.0001) discard;gl_FragColor =  vec4(color,alpha);}
} `;const getMaterial = (uniforms) => {return new THREE.ShaderMaterial({uniforms,vertexShader,fragmentShader,transparent: true});
}const material1 = getMaterial({uColor: { value: new THREE.Color('pink') },uTime: { value: 0 },uDirection: { value: 1 },uSpeed: { value: 1 },uFade: { value: new THREE.Vector2(0, 0.5) },uDirection: { value: 1 },uSpeed: { value: 1 }
})const material2 = getMaterial({uColor: { value: new THREE.Color('#00BFFF') },uTime: { value: 0.5 },uDirection: { value: 1 },uSpeed: { value: 1 },uFade: { value: new THREE.Vector2(0, 0.5) },uDirection: { value: 1 },uSpeed: { value: 1 }
})const mesh = new THREE.Mesh(geometry, material1)
const mesh2 = new THREE.Mesh(geometry, material2)scene.add(mesh);scene.add(mesh2)animate()function animate() {material1.uniforms.uTime.value += 0.002material2.uniforms.uTime.value += 0.002requestAnimationFrame(animate)renderer.render(scene, camera)composer.render();}/*** 名称: 心* 作者: 优雅永不过时 https://github.com/z2586300277* 参照来源:https://github.com/xiaolidan00/my-earth?tab=readme-ov-file */

http://www.ppmy.cn/embedded/128936.html

相关文章

【C++】C++当中的复合类型——引用和指针

C当中的复合类型 最近开始系统地学习 C 的语法&#xff0c;参考的主要资料来自于 C Primer 第五版&#xff0c;对于学习过程中所遇到的较难理解的点&#xff0c;我会以blog的形式对问题和内容进行记录&#xff0c;并进行进一步地探讨。 这一部分的内容对应于参考资料 C Prime…

电子物证的数字化时代:龙信科技引领取证技术革新

文章关键词&#xff1a;电子物证、手机取证、云取证、介质取证、电子数据取证 在信息技术飞速发展的今天&#xff0c;电子物证在司法领域扮演着越来越重要的角色。电子物证是指以存储于介质载体中的电磁记录或光电记录对案件事实起证明作用的电子信息数据及其附属物。与传统物…

leetcode.3194.最小元素和最大元素的最小平均值

#简单 你有一个初始为空的浮点数数组 averages。另给你一个包含 n 个整数的数组 nums&#xff0c;其中 n 为偶数。 你需要重复以下步骤 n / 2 次&#xff1a; 从 nums 中移除 最小 的元素 minElement 和 最大 的元素 maxElement。将 (minElement maxElement) / 2 加入到 avera…

宏基因组分析软件

humann2有参物种功能定量流程 合并质控后的双端数据 conda install humman2 wd/db/humann2 mkdir -p $wd humann2_databases #显示可用数据库 humann2_databases --download chocophlan full $wd #微生物物种核心基因5.37G humann2_databases --download uniref uniref90_di…

React Strict DOM:React Native 通用应用程序的未来

Meta宣布发布了 react-strict-dom。从根本上讲&#xff0c;这将改变我们使用 React Native&#xff08;以及在网页上使用 React&#xff09;的方式。它提供了一套统一的 UI 原语&#xff0c;带有样式&#xff0c;可以在网页和移动设备上通用使用&#xff01;现在&#xff0c;“…

IDEA中我常用的快捷键

多选:Ctrl Alt 鼠标左键 该相同变量名: Shift F6 查询形参(参数) : Ctrl P 继承父类的方法 : Alt InsScrLk 重命名 : Shift F6 查找方法 : Ctrl N / Ctrl F12 创建方法 : Ctrl Alt M 回到之前所在 : Ctrl Alt <-- 完整对象 Ctrl Alt V 代码上移:shift…

NativeWebRequest 转 HttpServletRequest

NativeWebRequest 转 HttpServletRequest 在使用HandlerMethodArgumentResolver时获取HttpServletRequest // 获取 NativeWebRequest 中的 HttpServletRequestHttpServletRequest httpServletRequest request.getNativeRequest(HttpServletRequest.class);

Excel中Ctrl+e的用法

重点&#xff1a;想要使用ctrle&#xff0c;前提是整合或拆分后的结果放置的单元格必须和被提取信息的单元格相邻&#xff0c;且被提取信息的单元格也必须相连。 下图为错误示例 这样则可以使用ctrle 1、信息整合 2、提取信息 3、添加符号 4、信息顺序调换 5、数字提取 crtle还…