交互草地shader的制作
TA图形学渲染引擎Shader材质球 4970 2
实名

通过了实名认证的内容创造者

发布于 2021-10-10 16:34:37

您需要 登录 才可以下载或查看,没有账号?注册

x
草地与物体的交互:
一、模型部分(Blender三维软件)
1.对平面进行分段处理。分为六段,方便对顶点着色。
图片1.png
2.顶点着色
a.在编辑模式下选中点
图片2.png


b.选中点后在顶点绘制模式,通过Shift+k进行着色。让R的值每段增加0.15,递增六段之后为1。通过R通道,来影响模型的顶点颜色从而,控制顶点受效果的影响程度。(后面做shader时会解释)


c.经过六段着色后得到的效果。


3.让模型有一些弯曲。


4. 导出fbx格式模型到unity中。
二、材质部分
1.创建Shader Graph文件和创建材质。
右键项目面板空白地方,创建PBR Graph。


右键项目面板空白地方,创建材质,


更换材质的shader为上面创建的shader





2.UV移动部分
(1)提取世界坐标下的x、z轴,作为UV。并通过Vertex1的数值进行控制大小。


a.通过Split对世界坐标的R、B(x、z)进行分离,再通过Combine合并为一个二维的数值(RG)。
b.通过定义的Winduv与RG数值相乘来控制UV的大小。
(2)通过Time节点的变化函数来控制方向的偏移。


a.通过定义的noiseSpeed来控制Time节点sin函数变化的速度。
(3)通过UV与偏移量相加使得UV朝着偏移的方向移动。


(4)通过在顶点着色器中进行采样一张Noise贴图,来改变偏移的变化值,得到一个滚动的UV,同时模拟出一阵风吹过时的情况。


a.因为进行采样的Noise是一张RGB通道都是不同噪点的黑白贴图的合成图。所以将它的R通道用来控制UV的运动强度,B通道来控制颜色的明暗。
b.Noise贴图:
RGB通道合成:


G通道黑白分布密集适合来控制运动变化,不确定性高:


B通道黑白分布很广且差别不大,适合用来做细微的明暗变化:


(5)对R通道进行处理:减掉0.5再乘以2得到一个双向的运动方式。


注:
a.因为R通道的值的范围是0到1,因此减掉0.5再乘以2,范围就变成了-1到1。就得到了一个负值,为反方向运动。
b.因为有反方向运动,就使得运动方式变成来回摆动。
c.定义一个Vertex1的值来控制风强的大小。
(6)通过Vertex Color节点得到物体顶点着色,再通过split分离出物体顶点的R通道。(之模型部分的顶点着色对R通道做的准备),通过分离出来的通道与上一点(5)得到的UV偏移运动相乘。会使模型的底部不动。


注:
a. 因为对模型R通道做的顶点着色范围是0-1之间的渐变向上的值,越往上越趋近于1。当值为0时会被剔除,不受影响。也就是说,越往上受到偏移运动的影响越大。
(7)当把得到的值加上世界空间坐标的值后会变成一个世界空间坐标的值,这时通过Transform节点将world世界空间转换为Object模型空间的值,才能将数值传递到模型上。


注:
通过连接后,将windpow的值调大,会发现模型的拉伸随着高度的变化会被拉伸的很长。
(8)因此为了解决拉伸的问题,再次将得到的值进行拆分。进行计算。
(9)通过split将得到的值的R和B通道拆分出来,进行绝对值处理得到一个正值。这个正值是模型左右摇摆的多少。一个是R通道的一个是B通道的值。再将它们加起来,就得到了模型摇摆一次总共值。


注:因为之前得到的值在-1到1之间,所以会有负值。Absolute是取数值的绝对值,才能将左右摇摆的值相加起来。
(10)将模型左右摇摆的值放到Vertex3中,加上世界空间的坐标。就有了Y值。


注:因为最开始就将物体的世界空间坐标的Y值给剔除掉了。所以现在要加回来。
(11)将得到的世界空间的坐标的y轴的值,也就是现在模型y轴的高度。来减掉一个,随时变化的,左右摇摆总值的一半的数值,使得原来的y轴高度随左右摆动幅度而降低。


注:
a.乘以0.5是因为被减的值不能太大。太大了会使得模型高度变得很奇怪。
b.y轴高度随左右摆动幅度而降低的原理:当左右摆动的幅度越大时,被减的数值也就越大,降低的高度也就越低。


c.从图中可以看到,当Y轴高度不变时,模型向左右摆动的θ角度变大时,L1明显比L0长很多。为了使这个拉伸变得正常。将Y轴的高度减去一个左右摆动总值的1/2的高度值h,就会得到一个随着θ角度变大,高度越低的变化弧线。


d.从图中可以看到处理后的拉伸感没有那么奇怪。
没有进行高度处理时:


进行高度处理后:


三、颜色部分
注:为了使UV移动部分看的更加明显,就先连接好了颜色部分的节点。
1.将shader的渲染改为双面渲染。因为导入的模型时一个平面,背面可能没有效果。


2.采样一个2D贴图放到片段着色器中运行。


a.采样的贴图中的R通道是一张黑白贴图,通过连接Alpha端口,进行计算,再通过AlphaClipThreshold进行裁剪,对黑色的部位进行剔除。
b.因为这里的R通道的是一个黑白的贴图,只有0和1的数值。因此给予AlphaClipThreshold的值为0.5。意思是当物体表面的颜色小于0.5时将0-0.5的值的剔除,反之保留。就会得到下图右边的效果。
R通道:


c.G通道是一张由下至上渐变的黑白贴图:


d.通过这张渐变贴图作为Lerp节点的混合方式来对模型进行上色。Lerp上的A端口改变黑色的颜色,B端口改变白色的颜色。
e.Add所加的颜色为“UV移动部分的(4)中Noise贴图中的B通道”
四、交互部分
1.获取玩家的坐标。
(1)通过定义一个vertex的值。注意名字要全部保持一致。Reference的名字前要加_(底杠),为了通过脚本将玩家的位置传递到shader graph中,进行计算。


(2)将脚本挂载在玩家上,获取玩家坐标。


2.定义模型的原点坐标,并转为世界空间坐标。并且将它的x、z轴坐标分离出来再合并。


a.将模型原点定义为(0,0,0)的原理:
由于在世界空间坐标下,Noise贴图的映射是不均匀的,会使得模型上的每一个顶点,与Noise贴图进行计算时都不一样,就会导致模型草的顶点偏移会有点部位偏移的很大,有的很小。因此当把模型上的顶点都规定在原点(0,0,0)上,Noise贴图就只会读取一个坐标点(像素点)进行计算。使得每一个点都均匀受力。


Noise贴图:



3.通过Distance节点计算玩家与草之间的距离,玩家与草的坐标进行拆分在合并,剔除Y轴上的值。


4.通过Clamp节点来约束影响的距离范围。通过定义一个Vertex1的值来约束距离的最大值Max,从而控制影响的范围。


5.通过最大值减去一个值,再让相减得到的值除以这个最大值。得到一个衰减的范围。


注:a.最大值减去一个值,这个值肯定比最大值小。


b.这个相减得到的值,除以一个比它大的值,会是一个小于1的小数。也就是衰减的范围。意思是越在中心影响就越大。


6.获取玩家到草的方向向量。
通过草的坐标减去玩家的坐标,得到玩家到草的向量。也就是玩家作用到草的一个方向,草倒的方向。


7.让方向作用到草上。将世界空间转为模型空间。并定义一个Vertex1的值控制方向的强度。


8.通过R通道控制草被压倒时的顶点位移范围。控制草的根部不动。


9.将得到数值相乘得到包含这些效果的值。在某个方向的作用上草倒的效果的数值。


10.对草倒的时候拉伸的处理。


a.通过之前风吹动草的运动的世界空间坐标的值减去玩家作用在草上的值。当玩家作用的值为0时,只有风吹的草的效果。而当玩家作用在草上时,这个差值就是这两个力同时作用的效果。
b.通过对相减得到的值,提取它的y轴高度来减去玩家作用于草时偏移的距离的1/2,使得草的高度随压倒的偏移增大而变低。
11.最终将分开计算的轴,合并在一起。在把他们从世界空间转为模型空间传递给模型的顶点。
如果看不清楚,可以下载这里的文档:草地与物体的交互,提取码:vzoj




图片9.png

本帖被以下画板推荐:

还没有设置签名!您可以在此展示你的链接,或者个人主页!
使用道具 <
オーロラ  发表于 2021-11-2 09:47:46  
2#
感觉挺详细的啊
回复 收起回复
使用道具
3D小白白  发表于 2022-8-3 10:49:53  
3#
感谢大佬分享
回复 收起回复
使用道具
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表