【threejs开发随笔】利用shaderMaterial制作草地

0.前言

最近的一个threejs项目需要草地的效果,遂参考各路大神的方法制作了一个
1.al-ro
2.spacejack

大体的思路是用shaderMaterial实现顶点动画,模拟草叶随风摇摆的样子,利用InstancedMesh来大规模产生草叶。利用math库里的MeshSurfaceSampler对象来吧草铺到指定mesh上去。
点击查看演示示例
点击下载示例文件

1.先说用法

用法很简单,引入makeGrass对象,然后new一个,传入场景、需要生成草的mesh以及生成草的数量:

        const grasses = new makeGrass(this.scene, // 场景model.scene.getObjectByName('平面') as Mesh, // 需要生草的mesh,类型需为Mesh250000 // 生草数量)

然后在渲染循环中执行makeGrass实例的公共方法update()

    ...this.renderer.setAnimationLoop(() => { this.renderLoop() }) 执行渲染循环方法。...// 渲染循环private renderLoop () {this.renderer.render(this.scene, this.camera)this.grasses?.update()this.controls?.update()}

2. 再说实现

首先我们新建一个makeGrass.ts文件,导入所需依赖

import { Clock, DoubleSide, InstancedMesh, Mesh, Object3D, PlaneGeometry, Scene, ShaderMaterial, Vector3 } from "three"
import { MeshSurfaceSampler } from "three/examples/jsm/math/MeshSurfaceSampler"

新建一个makeGrass类

export default class makeGrass {private scene:Sceneprivate mesh:Meshprivate leavesMaterial: ShaderMaterialprivate clock = new Clockprivate sampler!:MeshSurfaceSamplerprivate grassesAmount!:numberconstructor(scene:Scene,mesh:Mesh,grassesAmount:number,) {this.scene = scenethis.mesh = mesh}
}

写一个方法用来初始化草叶的shader材质并返回

private initleavesMaterial() {const vertexShader = `varying vec2 vUv;uniform float time;// 噪波float N (vec2 st) {return fract( sin( dot( st.xy, vec2(12.9898,78.233 ) ) ) *  43758.5453123);}float smoothNoise( vec2 ip ){vec2 lv = fract( ip );vec2 id = floor( ip );lv = lv * lv * ( 3. - 2. * lv );float bl = N( id );float br = N( id + vec2( 1, 0 ));float b = mix( bl, br, lv.x );float tl = N( id + vec2( 0, 1 ));float tr = N( id + vec2( 1, 1 ));float t = mix( tl, tr, lv.x );return mix( b, t, lv.y );}void main() {vUv = uv;float t = time * 2.;// 顶点位置vec4 mvPosition = vec4( position, 1.0 );#ifdef USE_INSTANCINGmvPosition = instanceMatrix * mvPosition;#endif// 移动float noise = smoothNoise(mvPosition.xz * 0.5 + vec2(0., t));noise = pow(noise * 0.5 + 0.5, 2.) * 2.;// 叶片顶部晃动力度.float dispPower = 1. - cos( uv.y * 3.1416 * 0.5 );float displacement = noise * ( 0.3 * dispPower );mvPosition.z -= displacement;//vec4 modelViewPosition = modelViewMatrix * mvPosition;gl_Position = projectionMatrix * modelViewPosition;}`;const fragmentShader = `varying vec2 vUv;void main() {vec3 baseColor = vec3( 0.41, 1.0, 0.5 );float clarity = ( vUv.y * 0.5 ) + 0.5;gl_FragColor = vec4( baseColor * clarity, 1 );}`;const uniforms = {time: {value: 0}}const leavesMaterial = new ShaderMaterial({vertexShader,fragmentShader,uniforms,side: DoubleSide});return leavesMaterial}

在构造函数中调用initleavesMaterial方法并赋值给类实例leavesMaterial

this.leavesMaterial = this.initleavesMaterial()

初始化网格表面取样器,用来在需要生成草的mesh上随机取点,通过取到的点的位置来生成草

private initSampler(){this.sampler = new MeshSurfaceSampler(this.mesh).setWeightAttribute(null).build()}

在构造函数中调用initSampler方法

this.initSampler()

写一个生成草的方法makegrasses

  private makegrasses(grassesAmount:number){const instanceNumber = grassesAmount;const dummy = new Object3D();const geometry = new PlaneGeometry( 0.1, 1, 1, 1 );geometry.translate( 0, 0.5, 0 ); // 吧草叶的最低点设置到0.const instancedMesh = new InstancedMesh( geometry, this.leavesMaterial, instanceNumber );this.scene.add(instancedMesh)const _position = new Vector3();const_normal = new Vector3();for ( let i=0 ; i<instanceNumber ; i++ ) {this.sampler.sample(_position,_normal)_normal.add(_position)dummy.position.set(_position.x,_position.y,_position.z)dummy.scale.setScalar( 0.2 + Math.random() *0.6 );dummy.rotation.y = Math.random()* Math.PI;dummy.updateMatrix();instancedMesh.setMatrixAt( i, dummy.matrix );}}

这里的草叶模型我们实例化一个简单的PlaneGeometry,heightSegments参数控制草叶的高度分段,分段越多草叶在摇摆的时候的弧度越精细。而分段越多场景的总面数也就越多,出于性能考虑我分段只给了1,这样草叶是笔直的在晃动。

最后我们写一个公共方法update,用来刷新草叶动画。

  public update(){this.leavesMaterial.uniforms.time.value = this.clock.getElapsedTime();this.leavesMaterial.uniformsNeedUpdate = true;}

【threejs开发随笔】利用shaderMaterial制作草地相关推荐

  1. android打地鼠设计报告,android开发中利用handler制作一个打地鼠小游戏

    android开发中利用handler制作一个打地鼠小游戏 发布时间:2020-11-25 15:21:11 来源:亿速云 阅读:136 作者:Leah 这期内容当中小编将会给大家带来有关androi ...

  2. 【threejs开发随笔】three.js基于八叉树的碰撞检测

    0.前言 相信大家在看threejs官网案例的时候会觉得里面那个fps的小例子碰撞检测感觉很丝滑,还有一定的类似物理的效果,不像之前简单的利用射线进行碰撞检测顶到墙之后劈里啪啦卡顿. 之前一个大哥吧这 ...

  3. background 覆盖 内容_web开发:利用background制作拉窗帘效果

    本文同步发表在我的个人博客中: 沧沧凉凉​www.cclliang.com 往往利用CSS可以做出一些意想不到的效果,比如说下面的这个示例: 为了演示随手做的,官网并不是这样 滚动鼠标滚轮,就有一种背 ...

  4. 利用InstallShield制作AE(ArcGIS Engine 打包)开发的应用程序的安装包

    原文:http://blog.csdn.net/swfcsunboy/article/details/2314249 利用InstallShield制作AE(ArcGIS Engine 打包)开发的应 ...

  5. 动态给a标签赋值_怎样利用Excel制作抖音上的心形动态函数图像?

    最近在抖音上看到有用Excel制作心形动态函数图像,感觉很新奇,闲来无事,准备自己动手做做,遂网上搜了教程,按照教程一步步做,前面都很顺利,但到最后一部确卡壳,问了公司Excel大牛也未找到原因,知道 ...

  6. 利用Python制作王者荣耀出装小助手,引来了老板的注意!

    导语 T_T并不玩这些游戏... 单纯来蹭个热点... 大概是因为蹭热点需要的技术含量比较低? 就这样吧~~~ 利用Python制作命令行版的王者荣耀出装小助手. Let's Go! 开发工具 Pyt ...

  7. python拼图_利用python制作拼图小游戏的全过程

    开发工具 Python版本:3.6.4 相关模块: pygame模块: 以及一些Python自带的模块 关注公众号:Python学习指南,回复"拼图"即可获取源码 环境搭建 安装P ...

  8. 利用JS制作抖音同款3D照片墙(three.js)

    利用JS制作抖音同款3D照片墙(three.js) 520快到了,跟我一起学习threeJS 用threeJS制作抖音同款3D照片墙 源码下载:3D照片墙源码下载地址

  9. 软件开发随笔系列一——分布式架构实现

    软件开发随笔系列一--分布式架构实现 文章目录 软件开发随笔系列一--分布式架构实现 理论基础 分布式架构的实现 内核框架 应用开发 基础设施 服务接入 监控 日志监控 调用链监控 度量指标监控 健康 ...

  10. 如何利用蜂鸣器制作MIDI音乐

    目录 蜂鸣器简介 MIDI音乐制作原理 <小星星>制作代码展示 引言:在单片机开发中我们经常会用到蜂鸣器实现一些简单提示的功能,但如何利用单片机制作一些更有趣的事情呢,今天我们将利用蜂鸣器 ...

最新文章

  1. linux i2c 读写函数,Linux下读写芯片的I2C寄存器
  2. 《JAVA与模式》之合成模式
  3. 数据结构---队列C语言实现
  4. Android 动态设置 layout_centerInParent
  5. gsettings命令使用简介
  6. 推荐一个IT老鸟肝了2月有余的免费开源WPF企业级开发框架
  7. 有关循环和判断的几个小问题
  8. 怎么创建java项目?新建java项目的步骤
  9. Android 计步器 - 手机自带系统级的 健康运动App 授权
  10. Pdf 转 word 和 word 转 pdf 等
  11. UPDATE的两个实例
  12. 第三章 标准单元库(上)
  13. 内网环境部署zabbix5.0版本监控(一)
  14. 一张我为写植物大战僵尸外.挂而画的草稿图...
  15. 解决windows10 ping不通问题(请求超时)
  16. Splay(splay模板)
  17. Python 爬取前程无忧
  18. 怎么用js改变html里面的图片大小,网页中图片属性固定宽度,如何用js改变大小...
  19. 前端复习记录(前端基础 JavaScript)一
  20. LeetCode高频题:《逆水寒》在地图的制作中,美术在地图上刷一片连通区域,连通区域自动填充,请你判断给定几个点位置,他们是否属于被刷区域

热门文章

  1. 计算机会计信息系统的数据处理方式一般,《会计信息系统复习资料.doc
  2. JAVA面试技巧之项目介绍
  3. 计算机系统分析师高级试题及答案,2013年计算机软考系统分析师试题及答案1
  4. 华为手机线刷工具_手机刷机、救砖教程
  5. Java微服务面试题及答案2022,微服务面试题2022
  6. 计算机专业专科生毕业论文题目,★专科生计算机专业论文题目专科生计算机专业毕业论文题目大全专科生计算机专业论文选题参考...
  7. 京东联盟API-二合一链接转链接口-线报转链-京粉转链接口
  8. MFC Windows程序设计源代码免费下载
  9. 工时测量有哪些方法,传统测量太繁琐?VIOOVI工时分析软件强势来袭!
  10. Web前端工程师修炼之道(原书第4版) 中文pdf扫描版