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

湖南网站seo北京网站优化技术

湖南网站seo,北京网站优化技术,网站优化软件robots,网站建设的基本步骤和过程【Threejs进阶教程-着色器篇】9.顶点着色器入门 本系列教程第一篇地址,建议按顺序学习认识顶点着色器varying介绍顶点着色器与片元着色器分别的作用Threejs在Shader中的内置变量各种矩阵gl_Position 尝试使用顶点着色器增加分段数增强效果 制作平面鼓包效果鼓包效果…

【Threejs进阶教程-着色器篇】9.顶点着色器入门

  • 本系列教程第一篇地址,建议按顺序学习
  • 认识顶点着色器
    • varying介绍
    • 顶点着色器与片元着色器分别的作用
    • Threejs在Shader中的内置变量
    • 各种矩阵
    • gl_Position
  • 尝试使用顶点着色器
    • 增加分段数增强效果
  • 制作平面鼓包效果
    • 鼓包效果分析
    • 路障效果
    • 让路障效果变得圆滑
    • uniform 控制鼓包效果
  • 完整源码

本系列教程第一篇地址,建议按顺序学习

本系列目前已累计第九篇,这里直接省略了2到8篇,可以通过上方专栏来查阅前面的教程
【Threejs进阶教程-着色器篇】1. Shader入门(ShadertoyShader和ThreejsShader入门)

本篇使用到的模板代码,从这里自取一个shader模板代码即可
【模板代码】用于编写Threejs Demo的模板代码

认识顶点着色器

首先我们把着色器部分的代码拎出来逐一分析

<script type="x-shader/x-vertex" id="vertexShader">varying vec2 vUv;void main(){vUv = vec2(uv.x,uv.y);vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );gl_Position = projectionMatrix * mvPosition;}</script>
<script type="x-shader/x-fragment" id="fragmentShader">varying vec2 vUv;void main(){gl_FragColor = vec4(1.0,0.0,0.0,1.0);}
</script>

varying介绍

有人发现顶点着色器的第一行与片元着色器的第一行,完全一致,那么这个varying用来做什么的呢?

这里我们直接借用webgl编程指南211页的介绍
在这里插入图片描述

varying主要用于 顶点着色器到片元着色器传输数据,是个全局变量

现阶段,我们只需要认识到,varying声明的变量,要在顶点着色器和片元着色器都要存在,且初始值需要在顶点着色器中设置即可

了解了varying之后,我们发现,其实uv的值是从顶点着色器中传递给片元着色器的

顶点着色器与片元着色器分别的作用

现阶段我这里不打算讲渲染原理和管线那些,太繁琐,这里先简单的总结一句
后续在讲到后处理的时候,这部分内容会再细讲

顶点着色器决定外型
片元着色器决定色彩

Threejs在Shader中的内置变量

顶点着色器中使用到了几个threejs的内置变量,在下面的官方文档中有说明
Threejs内置变量-WebGLProgram
一般来说我们最需要关注的几个:
position,模型的顶点信息会传递到这里,常用于计算模型的外观和最终渲染的外型
uv,模型的uv信息会传递到这里,常用于传递给顶点着色器用于计算颜色
normal,模型的法线信息会传递到这里,常用于计算光照等高级计算

如果看完了前面的BufferGeometry教程,有没有发现这里很熟悉?
【ThreeJS基础教程-高级几何体篇】2.6 BufferGeometry与BufferAttribute

你们想的没错,这些就是threejs向shader系统传递的数据,如果这里不懂BufferGeometry的,要继续下去学习Shader,就需要去前面补一下BufferGeometry的相关知识了

各种矩阵

在顶点着色器模板代码中的第四行第五行,分别出现了modelViewMatrix和projectionMatrix这两个矩阵,现阶段先不用管,只需要记住顶点着色器最终计算是这样即可

现阶段顶点着色器的代码,在模板代码的最后两行,除了**vec4(position,1.0);**会稍作改变,其他时间不会发生大的变动

gl_Position

一般来说,顶点着色器也需要有个固定输出,gl_Position就是顶点着色器的最终输出结果,最终结果也是一个vec4类型的对象

这样,顶点着色器的代码我们就介绍完毕了,接下来我们要尝试修改一下顶点着色器,感受一下顶点着色器带来的效果

尝试使用顶点着色器

我们用个最简单的方式来操作顶点

<script type="x-shader/x-vertex" id="vertexShader">varying vec2 vUv;void main(){vUv = vec2(uv.x,uv.y);vec3 aPosition = position;//这里我们直接操作顶点的z轴,偏移的激进一点aPosition.z = sin(aPosition.x * aPosition.y) * 10.0;vec4 mvPosition = modelViewMatrix * vec4( aPosition , 1.0 );gl_Position = projectionMatrix * mvPosition;}</script>

在这里插入图片描述
然后,我们运行起来之后,发现,我们的平面,扭曲了,这是因为我们的z轴发生了改变

增加分段数增强效果

这里我们修改一下addMesh()

    function addMesh() {//增加到100分段let geometry = new THREE.PlaneGeometry(10,10,3,3);let material = new THREE.ShaderMaterial({uniforms,vertexShader:document.getElementById('vertexShader').textContent,fragmentShader:document.getElementById('fragmentShader').textContent,transparent:true})let mesh = new THREE.Mesh(geometry,material);scene.add(mesh);}

在这里插入图片描述
我们可以发现,增加了分段和顶点之后,我们的这个平面变化巨大,已经不再是最初的PlaneGeometry了

这样,我们就完成了一次顶点着色器的尝试

制作平面鼓包效果

首先我们把平面横过来,然后需要做一个数据变换,分段数增加到100,然后设定材质的线框模式开,不然我们等一下不好看到效果
然后修改回最初的顶点着色器代码

addMesh

    function addMesh() {//注意这里必须旋转几何体,旋转了几何体,我们的数据才是正确的//mesh.rotation是在矩阵层面修改了旋转方向,最终会传递到modelViewMatrix中//顶点着色器的所有教程,除非特殊说明,否则全部使用旋转几何体let geometry = new THREE.PlaneGeometry(10,10,100,100).rotateX(-Math.PI/2);let material = new THREE.ShaderMaterial({uniforms,vertexShader:document.getElementById('vertexShader').textContent,fragmentShader:document.getElementById('fragmentShader').textContent,transparent:true,wireframe:true})let mesh = new THREE.Mesh(geometry,material);scene.add(mesh);}

顶点着色器

<script type="x-shader/x-vertex" id="vertexShader">varying vec2 vUv;void main(){vUv = vec2(uv.x,uv.y);vec3 aPosition = position;vec4 mvPosition = modelViewMatrix * vec4( aPosition , 1.0 );gl_Position = projectionMatrix * mvPosition;}
</script>

在这里插入图片描述

鼓包效果分析

既然要制作鼓包效果,那么,我们需要一个鼓包顶点,然后鼓包顶点处的高度最高,然后依次递减,所以我们这里直接从顶点着色器来定义这个鼓包点

<script type="x-shader/x-vertex" id="vertexShader">varying vec2 vUv;void main(){vUv = vec2(uv.x,uv.y);vec3 aPosition = position;//0 为int类型,0.0为float类型, 如果写0,threejs会报错// 可以写成 .0 来替代0.0以及任何 0.X 的数字, 但是个人不是很喜欢这种写法,看着太混乱vec3 swelling = vec3(0.0);//计算鼓包点到顶点的距离float dis = distance(swelling,aPosition);dis = clamp(dis,0.0,5.0);aPosition.y = 5.0 - dis;vec4 mvPosition = modelViewMatrix * vec4( aPosition , 1.0 );gl_Position = projectionMatrix * mvPosition;}
</script>

路障效果

这里,我们先声明了鼓包点在中心点,然后,我们计算鼓包点到四周的距离,但是要做一下限制,如果大于5.0的值,则直接赋值为5.0,紧接着直接把这个计算出来的dis值丢给aPosition.y,我们得到了一个漏斗型
在这里插入图片描述
既然我们计算的dis的最大值为5,那么,我们把大小做一下交换即可,用5.0 - dis,即可把漏斗形改成路障型
在这里插入图片描述

让路障效果变得圆滑

这里我们使用指数函数来优化

我们现在知道了最高点是5,最低点为0,那么,我们就可以计算它的高度比例,然后把线性的比例换成指数型比例
在这里插入图片描述
保持最高点和最低点不变,然后我们直接带入图像上面的数学公式,即可得到我们的鼓包效果

<script type="x-shader/x-vertex" id="vertexShader">varying vec2 vUv;void main(){vUv = vec2(uv.x,uv.y);vec3 aPosition = position;//0 为int类型,0.0为float类型, 如果写0,threejs会报错// 可以写成 .0 来替代0.0以及任何 0.X 的数字, 但是个人不是很喜欢这种写法,看着太混乱vec3 swelling = vec3(0.0);//计算鼓包点到顶点的距离float dis = distance(swelling,aPosition);dis = clamp(dis,0.0,5.0);dis = pow( dis / 5.0, 2.0 ) * 5.0;aPosition.y = 5.0 - dis;vec4 mvPosition = modelViewMatrix * vec4( aPosition , 1.0 );gl_Position = projectionMatrix * mvPosition;}
</script>

在这里插入图片描述

uniform 控制鼓包效果

uniform亦可用于顶点着色器

我们在代码中多次使用到5.0,这个实际上是鼓包的最大高度,这里我们抽出来这个常数作为鼓包最大高度,指数函数用的2次幂,这个参数可以抽出一个参数为鼓包圆滑率,我们写到uniform和lil.gui来调试
当然,我们的鼓包中心点,也可以单独拎出来放到uniform中

顶点着色器中编写uniform与片元着色器基本一致

修改后的顶点着色器

<script type="x-shader/x-vertex" id="vertexShader">varying vec2 vUv;uniform float maxSwelling;uniform vec3 swellingCenter;uniform float swellingPower;void main(){vUv = vec2(uv.x,uv.y);vec3 aPosition = position;//计算鼓包点到顶点的距离float dis = distance(swellingCenter,aPosition);dis = clamp(dis,0.0,maxSwelling);dis = pow( dis / maxSwelling, swellingPower ) * maxSwelling;aPosition.y = maxSwelling - dis;vec4 mvPosition = modelViewMatrix * vec4( aPosition , 1.0 );gl_Position = projectionMatrix * mvPosition;}
</script>

修改后的addMesh()和uniforms

let uniforms = {maxSwelling:{value:5.0},swellingCenter:{value:new THREE.Vector3()},swellingPower:{value:2.0}}function addMesh() {//注意这里必须旋转几何体,旋转了几何体,我们的数据才是正确的//mesh.rotation是在矩阵层面修改了旋转方向,最终会传递到modelViewMatrix中//顶点着色器的所有教程,除非特殊说明,否则全部使用旋转几何体let geometry = new THREE.PlaneGeometry(10,10,100,100).rotateX(-Math.PI/2);let material = new THREE.ShaderMaterial({uniforms,vertexShader:document.getElementById('vertexShader').textContent,fragmentShader:document.getElementById('fragmentShader').textContent,transparent:true,wireframe:true})let mesh = new THREE.Mesh(geometry,material);scene.add(mesh);//注意自己引入lil.guilet gui = new GUI();gui.add(uniforms.maxSwelling,'value',0,10).step(0.01).name('最大鼓包高度');gui.add(uniforms.swellingPower,'value',0,10).step(0.01).name('鼓包曲线');let folder = gui.addFolder('鼓包中心');folder.add(uniforms.swellingCenter.value,'x',-5,5);folder.add(uniforms.swellingCenter.value,'y',-5,5);folder.add(uniforms.swellingCenter.value,'z',-5,5);}

在这里插入图片描述

完整源码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>body{width:100vw;height: 100vh;overflow: hidden;margin: 0;padding: 0;border: 0;}</style>
</head>
<body><script type="importmap">{"imports": {"three": "../three/build/three.module.js","three/addons/": "../three/examples/jsm/"}}</script><script type="x-shader/x-vertex" id="vertexShader">varying vec2 vUv;uniform float maxSwelling;uniform vec3 swellingCenter;uniform float swellingPower;void main(){vUv = vec2(uv.x,uv.y);vec3 aPosition = position;//计算鼓包点到顶点的距离float dis = distance(swellingCenter,aPosition);dis = clamp(dis,0.0,maxSwelling);dis = pow( dis / maxSwelling, swellingPower ) * maxSwelling;aPosition.y = maxSwelling - dis;vec4 mvPosition = modelViewMatrix * vec4( aPosition , 1.0 );gl_Position = projectionMatrix * mvPosition;}
</script>
<script type="x-shader/x-fragment" id="fragmentShader">varying vec2 vUv;void main(){gl_FragColor = vec4(1.0,0.0,0.0,1.0);}
</script><script type="module">import * as THREE from "../three/build/three.module.js";import {OrbitControls} from "../three/examples/jsm/controls/OrbitControls.js";import {GUI} from "../three/examples/jsm/libs/lil-gui.module.min.js";window.addEventListener('load',e=>{init();addMesh();render();})let scene,renderer,camera;let orbit;function init(){scene = new THREE.Scene();renderer = new THREE.WebGLRenderer({alpha:true,antialias:true});renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);camera = new THREE.PerspectiveCamera(50,window.innerWidth/window.innerHeight,0.1,2000);camera.add(new THREE.PointLight());camera.position.set(15,15,15);scene.add(camera);orbit = new OrbitControls(camera,renderer.domElement);orbit.enableDamping = true;scene.add(new THREE.GridHelper(10,10));}let uniforms = {maxSwelling:{value:5.0},swellingCenter:{value:new THREE.Vector3()},swellingPower:{value:2.0}}function addMesh() {//注意这里必须旋转几何体,旋转了几何体,我们的数据才是正确的//mesh.rotation是在矩阵层面修改了旋转方向,最终会传递到modelViewMatrix中//顶点着色器的所有教程,除非特殊说明,否则全部使用旋转几何体let geometry = new THREE.PlaneGeometry(10,10,100,100).rotateX(-Math.PI/2);let material = new THREE.ShaderMaterial({uniforms,vertexShader:document.getElementById('vertexShader').textContent,fragmentShader:document.getElementById('fragmentShader').textContent,transparent:true,wireframe:true})let mesh = new THREE.Mesh(geometry,material);scene.add(mesh);let gui = new GUI();gui.add(uniforms.maxSwelling,'value',0,10).step(0.01).name('最大鼓包高度');gui.add(uniforms.swellingPower,'value',0,10).step(0.01).name('鼓包曲线');let folder = gui.addFolder('鼓包中心');folder.add(uniforms.swellingCenter.value,'x',-5,5);folder.add(uniforms.swellingCenter.value,'y',-5,5);folder.add(uniforms.swellingCenter.value,'z',-5,5);}function render() {renderer.render(scene,camera);orbit.update();requestAnimationFrame(render);}</script>
</body>
</html>
http://www.ds6.com.cn/news/95274.html

相关文章:

  • 移动宽带到期续费流程优化网站排名技巧
  • 免费发广告网站2022当下社会热点话题
  • 深圳网站制作招聘搜狗站长平台主动提交
  • 网站开发 职业环境分析山西seo和网络推广
  • 手机wordpress教程聊城seo优化
  • 信息网站建设汇报企业网站是什么
  • 做淘宝客需要那先网站seo zac
  • 自己做的网站用别的电脑怎么访问全国十大跨境电商排名
  • PHP视频类网站应该怎么做品牌运营具体做什么
  • 福州专业做网站广州百度网站推广
  • app开发公司怎么找到需要定制的客户南宁seo排名外包
  • 手机网站全屏显示西安疫情最新数据消息5分钟前
  • 大连建设学校网站院长网络营销五种方法
  • 商务网站建设的第一步互联网营销做什么
  • 南京网站制作seo如何优化关键词
  • 个人可以做哪些网站百度搜索排行seo
  • 做网站网页的人是不是思维企业网站seo优化外包
  • 北京快速建站制作公司谷歌广告联盟官网
  • wordpress修改上传文件路径西安网站seo排名优化
  • 地产公司做网站维护写代码么厦门百度关键词优化
  • wordpress中文网站模板日本搜索引擎naver入口
  • wordpress付费汉化主题seo整站优化解决方案
  • 个人怎么做动漫短视频网站百度关键词排名快速排名
  • 沈阳酒店团购网站制作海外品牌推广
  • 东单网站建设百度站长平台网址
  • ios开发者账号多少钱广州seo工资
  • 网站关键词最多几个2023引流软件
  • 专门做评测的网站全国疫情最新消息
  • 建设部网站在哪里看受理公司网站建设哪家公司好
  • 使用亚马逊云做网站网址查询