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

three.js利用着色器实现波浪效果

效果演示

着色器旗帜

1、实现步骤

1.1创建项目

// 创建一个空项目
import * as THREE from 'three'
//导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'//1、创建场景
const scene = new THREE.Scene()//2、创建相机
const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000
) // 参数分别代表,相机角度、屏幕宽高比、近端点,远端点//设置相机位置
camera.position.set(0, 0, 10)
scene.add(camera)//添加环境光和平行光
const ambientLight = new THREE.AmbientLight(0xffffff, 1)
const dirLight = new THREE.DirectionalLight(0xffffff, 1)
dirLight.castShadow = true
scene.add(ambientLight)
scene.add(dirLight)//初始化渲染器
const renderer = new THREE.WebGLRenderer()//设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
renderer.physicallyCorrectLights = true//将webGL渲染的canvas添加到app中
document.getElementById('app').appendChild(renderer.domElement)//创建控制器
const controls = new OrbitControls(camera, renderer.domElement)//设置控制器阻尼,让滑动更有真实感
controls.enableDamping = true//创建坐标轴
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)//设置时钟
const clock = new THREE.Clock()render()//渲染函数
function render() {const time = clock.getElapsedTime()controls.update()renderer.render(scene, camera)//下一帧渲染完毕再次执行,保证每一帧都渲染requestAnimationFrame(render)
}

1.2创建顶点着色器和片元着色器

新建文件夹shader/raw/vertexShader.glslshader/raw/fragmentShader.glsl分别存储顶点着色器和片元着色器

// shader/raw/vertexShader.glsl
precision lowp float;
attribute vec3 position;
attribute vec2 uv;uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform float uTime;//拿到传过来的uTimevarying vec2 vUv;
varying float vElevation;void main() {vUv = uv;vec4 modelPosition = modelMatrix * vec4(position,1.0);//波浪modelPosition.z = sin((modelPosition.x + uTime) * 10.0) * 0.05;modelPosition.z += sin((modelPosition.y + uTime)* 10.0) * 0.05;vElevation = modelPosition.z;gl_Position = projectionMatrix * viewMatrix * modelPosition;
}
// shader/raw/fragmentShader.gls
precision highp float;
varying vec2 vUv;
varying float vElevation;
uniform sampler2D uTexture;void main(){// gl_FragColor = vec4(vUv,0.0,1.0);// float height = vElevation + 0.05 * 10.0;// gl_FragColor = vec4(1.0 * height,0.0,0.0,1.0);//根据uv,取出对应的颜色vec4 textureColor = texture2D(uTexture,vUv);float height = vElevation + 0.05 * 20.0;textureColor.rgb *= height;gl_FragColor = textureColor;
}

1.3导入着色器和纹理

//导入顶点着色器
import basicVertexShader from '@/shader/raw/vertexShader.glsl?raw'
//导入片元着色器
import basicFragmentShader from '@/shader/raw/fragmentShader.glsl?raw'
//导入纹理
const textureLoader = new THREE.TextureLoader()
const imgTexture = textureLoader.load('/static/imgs/ca.jpeg')

1.4创建物体和材质


//创建平面
const floorGeometry = new THREE.PlaneGeometry(1, 1, 64, 64)
// const floorMaterial = new THREE.MeshBasicMaterial({ color: '#00ff00' })
//创建着色器材质
const floorMaterial = new THREE.RawShaderMaterial({//让着色器材质跟随相机等转,顶点着色器vertexShader: basicVertexShader,//片源着色器fragmentShader: basicFragmentShader,// wireframe: true,side: THREE.DoubleSide,//给顶点着色器传的值uniformsuniforms: {uTime: {value: 0,},uTexture: {value: imgTexture,},},
})const floorMesh = new THREE.Mesh(floorGeometry, floorMaterial)
scene.add(floorMesh)

1.5让物体动起来

//渲染函数
function render() {const time = clock.getElapsedTime()floorMaterial.uniforms.uTime.value = time //给片元着色器传的controls.update()renderer.render(scene, camera)//下一帧渲染完毕再次执行,保证每一帧都渲染requestAnimationFrame(render)
}

2、全部代码

import * as THREE from 'three'//目标:学习着色器变量//导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'//导入顶点着色器
import basicVertexShader from '@/shader/raw/vertexShader.glsl?raw'
//导入片元着色器
import basicFragmentShader from '@/shader/raw/fragmentShader.glsl?raw'//1、创建场景
const scene = new THREE.Scene()//2、创建相机
const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000
) // 参数分别代表,相机角度、屏幕宽高比、近端点,远端点//设置相机位置
camera.position.set(0, 0, 10)
scene.add(camera)//导入纹理
const textureLoader = new THREE.TextureLoader()
const imgTexture = textureLoader.load('/static/imgs/ca.jpeg')//创建平面
const floorGeometry = new THREE.PlaneGeometry(1, 1, 64, 64)
// const floorMaterial = new THREE.MeshBasicMaterial({ color: '#00ff00' })
//创建着色器材质
const floorMaterial = new THREE.RawShaderMaterial({//让着色器材质跟随相机等转,顶点着色器vertexShader: basicVertexShader,//片源着色器fragmentShader: basicFragmentShader,// wireframe: true,side: THREE.DoubleSide,//给顶点着色器传的值uniformsuniforms: {uTime: {value: 0,},uTexture: {value: imgTexture,},},
})const floorMesh = new THREE.Mesh(floorGeometry, floorMaterial)
scene.add(floorMesh)//添加环境光和平行光
const ambientLight = new THREE.AmbientLight(0xffffff, 1)
const dirLight = new THREE.DirectionalLight(0xffffff, 1)
dirLight.castShadow = true
scene.add(ambientLight)
scene.add(dirLight)//初始化渲染器
const renderer = new THREE.WebGLRenderer()//设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
renderer.physicallyCorrectLights = true//将webGL渲染的canvas添加到app中
document.getElementById('app').appendChild(renderer.domElement)//创建控制器
const controls = new OrbitControls(camera, renderer.domElement)//设置控制器阻尼,让滑动更有真实感
controls.enableDamping = true//创建坐标轴
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)//设置时钟
const clock = new THREE.Clock()render()//渲染函数
function render() {const time = clock.getElapsedTime()floorMaterial.uniforms.uTime.value = timecontrols.update()renderer.render(scene, camera)//下一帧渲染完毕再次执行,保证每一帧都渲染requestAnimationFrame(render)
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 新手教学系列——慎用Flask-SQLAlchemy慢日志记录
  • C++_STL---list
  • 构建现代医疗:互联网医院系统源码与电子处方小程序开发教学
  • 身边的故事(十三):阿文的故事:出现
  • js 复制文本带样式
  • Transformation(转换)开发-switch/case组件
  • 【简单讲解下npm常用命令】
  • go Channel 原理 (一)
  • 初学Spring之 IOC 控制反转
  • Git使用[推送大于100M的文件后解救办法]
  • k8s 答疑
  • vector模拟实现【C++】
  • 【Git】GitIgnore不生效
  • 【OpenSSH】紧急警报!新发现的OpenSSH漏洞,安全界面临严峻考验
  • .NET之C#编程:懒汉模式的终结,单例模式的正确打开方式
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • android图片蒙层
  • ES10 特性的完整指南
  • javascript 总结(常用工具类的封装)
  • JavaScript设计模式系列一:工厂模式
  • Material Design
  • 构造函数(constructor)与原型链(prototype)关系
  • 警报:线上事故之CountDownLatch的威力
  • 聊聊flink的BlobWriter
  • 微服务框架lagom
  • 微信小程序--------语音识别(前端自己也能玩)
  • FaaS 的简单实践
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • ​虚拟化系列介绍(十)
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #考研#计算机文化知识1(局域网及网络互联)
  • $GOPATH/go.mod exists but should not goland
  • (02)vite环境变量配置
  • (11)MATLAB PCA+SVM 人脸识别
  • (C语言)fread与fwrite详解
  • (多级缓存)缓存同步
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (学习总结16)C++模版2
  • (转)德国人的记事本
  • .bat文件调用java类的main方法
  • .Net 8.0 新的变化
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .net 微服务 服务保护 自动重试 Polly
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .NET业务框架的构建
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • @Autowired注解的实现原理
  • [ vulhub漏洞复现篇 ] JBOSS AS 4.x以下反序列化远程代码执行漏洞CVE-2017-7504
  • [30期] 我的学习方法
  • [AIGC] HashMap的扩容与缩容:动态调整容量以提高性能