three.js 实现一个咖啡效果的着色器

server/2024/10/17 23:29:23/

three.js 实现一个咖啡效果的着色器

源链接:https://threehub.cn/#/codeMirror?navigation=ThreeJS&classify=application&id=coffeeMug

国内站点预览: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 Stats from 'three/examples/jsm/libs/stats.module.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import {GUI} from 'dat.gui'const initializeScene = ({ root, antialias = true } = {}) => {// Create sceneconst scene = new THREE.Scene();// Create cameraconst camera = new THREE.PerspectiveCamera(35,window.innerWidth / window.innerHeight,0.1,1000,);camera.position.z = 110;// Create rendererconst renderer = new THREE.WebGLRenderer({ antialias });renderer.setSize(window.innerWidth, window.innerHeight);// renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));const controls = new OrbitControls(camera, renderer.domElement);controls.enableDamping = true;root.appendChild(renderer.domElement);const onWindowResize = () => {// Adjust camera and renderer on window resizecamera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();controls.update();renderer.setSize(window.innerWidth, window.innerHeight);renderer.render(scene, camera);};onWindowResize();window.addEventListener('resize', onWindowResize, false);// Create GUIconst gui = new GUI({ container: root });const stats = new Stats();stats.showPanel(0);root.appendChild(stats.domElement);return {scene,renderer,camera,controls,gui,stats,};
};const init = (root) => {const { scene, renderer, camera, gui, stats, controls } = initializeScene({root,});camera.position.set(12, 6, 12);const gltfLoader = new GLTFLoader();gltfLoader.load(`https://file.threehub.cn/` + 'examples/coffeeMug/coffeeMug.glb', (gltf) => {gltf.scene.getObjectByName('baked').material.map.anisotropy = 8;controls.target.y += 3;scene.add(gltf.scene);});const textureLoader = new THREE.TextureLoader();const perlinTexture = textureLoader.load(`https://file.threehub.cn/` + 'examples/coffeeMug/perlin.png');perlinTexture.wrapS = THREE.RepeatWrapping;perlinTexture.wrapT = THREE.RepeatWrapping;const smokeGeometry = new THREE.PlaneGeometry(1, 1, 16, 64);smokeGeometry.translate(0, 0.5, 0);smokeGeometry.scale(1.5, 6, 1.5);const smokeMaterial = new THREE.ShaderMaterial({// wireframe: true,vertexShader:`#define M_PI 3.1415926535897932384626433832795varying vec2 vUv;uniform float uTime;uniform sampler2D uPerlinTexture;vec2 rotate2D(vec2 value, float angle){float s = sin(angle);float c = cos(angle);mat2 m = mat2(c, s, -s, c);return m * value;}void main(){vUv = uv;vec3 newPosition = position;float angle = texture(uPerlinTexture,vec2(0.5, uv.y * 0.3 + uTime * 0.02)).x * 7.;newPosition.xz = rotate2D(position.xz, angle);vec2 windOffset = vec2(texture(uPerlinTexture, vec2(0.2, uTime * 0.02)).x - 0.5,texture(uPerlinTexture, vec2(0.7, uTime * 0.02)).x - 0.5);newPosition.xz += windOffset * pow(uv.y, 2.) * 8.;gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(newPosition, 1.0);}`,fragmentShader:`varying vec2 vUv;uniform float uTime;uniform sampler2D uPerlinTexture;void main(){vec2 uv = vec2(vUv.x * 0.5, vUv.y * 0.3 - uTime / 15.);float intensity = texture2D(uPerlinTexture, uv).x;intensity = smoothstep(0.4, 1.0, intensity);intensity *= smoothstep(0.0, 0.1, vUv.x);intensity *= smoothstep(1.0, 0.9, vUv.x);intensity *= smoothstep(0.0, 0.1, vUv.y);intensity *= smoothstep(1.0, 0.4, vUv.y);gl_FragColor = vec4(1.0, 0.8, 0.6, intensity);#include <tonemapping_fragment>#include <colorspace_fragment>}`,uniforms: {uTime: { value: 0 },uPerlinTexture: { value: perlinTexture },},transparent: true,depthWrite: false,side: THREE.DoubleSide,});const smoke = new THREE.Mesh(smokeGeometry, smokeMaterial);smoke.position.y = 1.83;scene.add(smoke);const clock = new THREE.Clock();const tick = () => {requestAnimationFrame(tick);stats.begin();controls.update();smokeMaterial.uniforms.uTime.value = clock.getElapsedTime();stats.end();renderer.render(scene, camera);};tick();return renderer;
};init(document.getElementById('box'));/*** 名称: 咖啡* 作者: kavalcio https://github.com/kavalcio
*/

http://www.ppmy.cn/server/131360.html

相关文章

HarmonyOS Next应用开发——抽屉布局SideBarContainer

抽屉布局SideBarContainer 提供侧边栏可以显示和隐藏的侧边栏容器&#xff0c;通过子组件定义侧边栏和内容区&#xff0c;第一个子组件表示侧边栏&#xff0c;第二个子组件表示内容区。 并且侧边栏可以出现在左侧也可以出现在右侧&#xff0c;侧边栏可以并列跟内容区一起展示…

H7-TOOL的LUA小程序教程第14期:任意波形信号发生器,0-20mA输出和微型数控电源(2024-10-11,已更新)

LUA脚本的好处是用户可以根据自己注册的一批API&#xff08;当前TOOL已经提供了几百个函数供大家使用&#xff09;&#xff0c;实现各种小程序&#xff0c;不再限制Flash里面已经下载的程序&#xff0c;就跟手机安装APP差不多&#xff0c;所以在H7-TOOL里面被广泛使用&#xff…

数通--3

一、动态路由 内部 路由器之间要互联互通&#xff0c;必须遵循相同的协议 企业内部用 IGP&#xff0c;企业之间用BGP RIP&#xff08;已淘汰&#xff0c;不考&#xff09; 距离就是长短&#xff0c;矢量就是方向&#xff0c;即路由的出接口 一台路由器 A 配好RIP&#xff0c;…

解析 wxPython 和 Pandas 实现的 XLSX 分析器和网页打开器

在本文中&#xff0c;我们将分析一个使用 wxPython 和 Pandas 库编写的 Python 应用程序&#xff0c;名为 “XLSX Analyzer and Web Opener”。该应用程序的核心功能是&#xff1a;从 Excel 文件中读取数据并显示在网格中&#xff0c;此外&#xff0c;还允许用户使用 Google Ch…

天气API接口调用

天气API接口&#xff1a; 天气API接口是一种用于获取实时或预报天气信息的应用程序编程接口&#xff08;API&#xff09;。开发者可以使用这种接口在他们的应用程序或网站上集成天气查询功能&#xff0c;比如查询某个地区的当前温度、降水量、风速等数据。 通常&#xff0c;你…

C#-使用Serilog框架快速实现日志及其相关扩展

目录 一、Serilog日志实现 1、实现 ILogEventSink接口 2、日志类Log 3、日志级别LogLevel 4、ILogger接口 5、日志服务实现 6、日志视图View 7、ViewModel 二、功能扩展 1、日志扩展方法 2、Trace追踪扩展日志 3、自动滚动至底部 一、Serilog日志实现 安装NuGet包…

每天一个数据分析题(五百零四)- 抽取样本

下列哪种方法&#xff0c;会重复抽取训练数据集中的数据&#xff0c;且每笔被抽中的概率始终保持一样&#xff1f; A. 袋装法&#xff08;Bagging&#xff09; B. 提升法&#xff08;Boosting&#xff09; C. 支持向量机&#xff08;SVM&#xff09; D. 以上皆是 数据分析…

Pyppeteer:如何在 Python 中使用 Puppeteer 和 Browserless?

Python 中的 Pyppeteer 是什么&#xff1f; Pyppeteer 是流行的 Node.js 库 Puppeteer 的 Python 移植版本&#xff0c;用于以编程方式控制无头 Chrome 或 Chromium 浏览器。 本质上&#xff0c;Pyppeteer 允许 Python 开发人员在 Web 浏览器中自动执行任务&#xff0c;例如抓…