Unity3D Shader——水的折射
2017-11-27 11:36
375 查看
这里依然用的是vertex 和fragment shader来解决水的反射的问题。
首先,准备两个平面,一个平面作为底图,一个平面模拟水的波动。这里要用到抓取底图的通道 GrabPass{}。然后把抓取的通道图放到水面的那张图上。另外一个难点就是要模拟水的波动,水的波动的原理如下图:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
如果想最后的贴图是随着法线变化,那么就要用到偏导数,计算每个顶点的动态法线。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
以上还不算完美,可以加上漫反射,让水的颜色随着波纹变化。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
最终的效果:
首先,准备两个平面,一个平面作为底图,一个平面模拟水的波动。这里要用到抓取底图的通道 GrabPass{}。然后把抓取的通道图放到水面的那张图上。另外一个难点就是要模拟水的波动,水的波动的原理如下图:
其中顶点函数代码和片段函数代码如下: v2f vert(appdata v){ float w=2*3.1415926/_L; float f=_S*w; v.vertex.y+=_A*sin(v.vertex.xz*w+_Time.x*f); v2f o; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.uv=TRANSFORM_TEX(v.uv,_MainTex); o.proj=ComputeGrabScreenPos(o.pos); return o; } float4 frag(v2f IN):SV_Target{ IN.proj.xy+=0.01*sin(IN.proj.xy*3.14*10+_Time.y*2); float4 col=tex2Dproj(_GrabTexture,IN.proj)*0.5; return col; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
如果想最后的贴图是随着法线变化,那么就要用到偏导数,计算每个顶点的动态法线。
v2f vert(appdata v){ float w=2*3.1415926/_L; float f=_S*w; v.vertex.y+=_A*sin(-length(v.vertex.xz)*w+_Time.x*f); float dx=_A*v.vertex.x*w*cos(-length(v.vertex.xz)*w+_Time.x*f); float dz=_A*v.vertex.z*w*cos(-length(v.vertex.xz)*w+_Time.x*f); float3 B=normalize(float3(1,dx,0)); float3 T=normalize(float3(0,dz,1)); v2f o; o.N=cross(B,T); o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.uv=TRANSFORM_TEX(v.uv,_MainTex); o.proj=ComputeGrabScreenPos(o.pos); return o; } float4 frag(v2f IN):SV_Target{ float d=dot(IN.N,float3(0,1,0)); IN.proj.xy+=d*0.1; //IN.proj.xy+=0.01*sin(IN.proj.xy*3.14*10+_Time.y*2); float4 col=tex2Dproj(_GrabTexture,IN.proj)*0.5; return col; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
以上还不算完美,可以加上漫反射,让水的颜色随着波纹变化。
v2f vert(appdata v){ float w=2*3.1415926/_L; float f=_S*w; v.vertex.y+=_A*sin(-length(v.vertex.xz)*w+_Time.x*f); float dx=_A*v.vertex.x*w*cos(-length(v.vertex.xz)*w+_Time.x*f); float dz=_A*v.vertex.z*w*cos(-length(v.vertex.xz)*w+_Time.x*f); float3 B=normalize(float3(1,dx,0)); float3 T=normalize(float3(0,dz,1)); v2f o; o.N=cross(B,T); o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.uv=TRANSFORM_TEX(v.uv,_MainTex); o.proj=ComputeGrabScreenPos(o.pos); return o; } float4 frag(v2f IN):SV_Target{ float3 ncol=UnpackNormal(tex2D(_MainTex,IN.uv+_Time.x))*0.3; IN.N=IN.N+ncol; float d=dot(IN.N,float3(0,1,0)); float diff=max(0,dot(IN.N,float3(1,0,0))); //漫反射 IN.proj.xy+=d*0.1; //IN.proj.xy+=0.01*sin(IN.proj.xy*3.14*10+_Time.y*2); float4 col=tex2Dproj(_GrabTexture,IN.proj)*(0.3+diff); return col; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
最终的效果:
相关文章推荐
- Unity3D shader——水的折射与反射
- Unity3D Shader(17)——水的折射
- Unity3D shader(18)——水的折射与反射
- 详解Unity3D Shader之Shader Lab框架
- Unity3D shader脚本
- 猫都能学会的Unity3D Shader入门指南(二)
- 【Unity3D自学记录】进击的Shader
- Unity3d中Shader的基本属性以及定义
- Unity3D内置Shader私房课(四)Skybox天空盒(立方体版)
- Unity3D Shader入门指南(一)
- Unity3D Shader编程】之一 夏威夷篇:游戏场景的创建 & 第一个Shader的书写
- Unity3D Shader官方教程翻译(二)
- Unity3D Shader官方教程翻译(十九)----Shader语法,编写表面着色器
- unity3d shader缔造金属各向异性效果
- 猫都能学会的Unity3D Shader入门指南(一)
- 【浅墨Unity3D Shader编程】之四 热带雨林篇: 剔除、深度测试、Alpha测试以及基本雾效合辑
- UNITY3D shader代码例子<一> 法线颜色
- Unity3d BTDF实时折射模拟有粗糙度的半透明物体
- 猫都能学会的Unity3D Shader入门指南(二)
- Unity3D Shader官方教程翻译(八)----Shader语法:Pass的纹理处理