在我学习入门精要的时候,经常遇到不解释api,甚至是关键代码的实现原理。

11.3.1流动的河流中的offset.x的sin函数查了一下好像大家也都是书上原话直接复制,现在好不容易想明白了希望能帮到和我一样一脸懵逼的人。

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 11/Water" {
Properties {
_MainTex ("Main Tex", 2D) = "white" {}
_Color ("Color Tint", Color) = (1, 1, 1, 1)
_Magnitude ("Distortion Magnitude", Float) = 1
_Frequency ("Distortion Frequency", Float) = 1
_InvWaveLength ("Distortion Inverse Wave Length", Float) = 10
_Speed ("Speed", Float) = 0.5
}
SubShader {
// Need to disable batching because of the vertex animation
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "DisableBatching"="True"} Pass {
Tags { "LightMode"="ForwardBase" } ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Cull Off CGPROGRAM
#pragma vertex vert
#pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
float _Magnitude;
float _Frequency;
float _InvWaveLength;
float _Speed; struct a2v {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
}; struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
}; v2f vert(a2v v) {
v2f o; float4 offset;
offset.yzw = float3(0.0, 0.0, 0.0);
//最重要却没讲清楚的一句
offset.x = sin(_Frequency * _Time.y + v.vertex.x * _InvWaveLength + v.vertex.y * _InvWaveLength + v.vertex.z * _InvWaveLength) * _Magnitude;
o.pos = UnityObjectToClipPos(v.vertex + offset);
//这里只对uv偏移,对模型顶点没有影响
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.uv += float2(0.0, _Time.y * _Speed); return o;
} fixed4 frag(v2f i) : SV_Target {
fixed4 c = tex2D(_MainTex, i.uv);
c.rgb *= _Color.rgb; return c;
} ENDCG
}
}
FallBack "Transparent/VertexLit"
}

这个offset.x是个啥?而且其中的v.vertex的xyz分量都乘了波长更让人摸不着头脑,我们先看一个标准版本。

下面这个版本能够实现一个标准的行波河流

offset.x = _Magnitude * sin(_Frequency * _Time.y + v.vertex.z * _InvWaveLength);

效果(上下边缘对称)

然后逐一解释

这个首先是坐标,我们需要知道模型空间下左右(横轴)是z,而上下是x。

然后再用行波的表达式

y = Asin(kx - ωt + φ)+ b

可以知道x对应v.vertex.z;_Time.y对应t

并且周期是2π/ω,波长是2π/k。

那么我们就能知道书上原话“利用_Frequency属性和内置的_Time变量来控制正弦函数的频率,....乘以_InvWaveLength来控制波长”是啥意思了

_Magnitude 控制波动幅度大家学过三角函数肯定都知道。

然后再来看书上为什么是

offset.x = sin(_Frequency * _Time.y + v.vertex.x * _InvWaveLength + v.vertex.y * _InvWaveLength + v.vertex.z * _InvWaveLength) * _Magnitude;

这里多出来的是

v.vertex.y * _InvWaveLength + v.vertex.x * _InvWaveLengt

实际上y没有意义----因为我们这个河流的顶点的y在模型空间上都是0

所以考虑x就是在纵方向上形成偏移,竖直方向来看,同一z轴的x往下不断变化,也就是同一z上的不同x的初项不同,从上往下的波初项不同,形成偏移

放在图片上面就是上下边缘的波形相同,但是时刻不同。

这里可能有人想的比较复杂,觉得顶点坐标已经偏移了之后计算会变化,但其实v.vertex一直都是原本的顶点坐标,只是pos来负责计算之后输出到SV_POSITION之中。



希望能帮到大家

最新文章

  1. Inno setup定制安装界面
  2. spring的自动装配基础
  3. OpenCV Linux 安装 Make出错
  4. TTL电平和CMOS电平总结
  5. 2011斯坦福大学iOS应用开发教程学习笔记(第一课)MVC.and.Introduction.to.Objective-C
  6. 云主机上搭建squid3代理服务器
  7. Spark Streaming 数据接收过程
  8. 我的第一个python web开发框架(14)——后台管理系统登录功能
  9. DOM节点类型
  10. Cocos Creator cc.Button (脚本事件内容)
  11. jquery遇到的问题
  12. msvcp140.dll丢失解决方案
  13. mongoDB的配置和使用
  14. 学习笔记45—Linux压缩集
  15. powerdesigner 实体关系模型CDM与物理数据模型PDM互转
  16. [python] pyCharm 右击出现run unittest 解决办法
  17. pta6-17(另类堆栈)
  18. 1098 Insertion or Heap Sort
  19. 【51Nod1258】序列求和V4(FFT)
  20. linux环境下的GUN make学习笔记(一)

热门文章

  1. JVM收藏的文章
  2. pycharm关闭pytest
  3. html特殊字符(css3 content)
  4. transient关键字有何作用
  5. nginx域名转发
  6. 分布式缓存NCache使用
  7. 攻防世界之Web_php_include
  8. windev中自定义选定列的使用和注意事项
  9. 【windows 操作系统】异步
  10. 2、CPU是怎么实现运算的 ?