您的位置:首页 > 其它

Genesis-3D 入门教程—28.自定制水

2013-12-06 10:57 309 查看



该文章转载自Genesis-3D官网,


更多教程请访问Genesis-3D官网:http://www.genesis-3d.com.cn

自定制水

这是一个自定制水的实例,本实例通过定制shader和脚本,展现出一个自定义的水面,帮助用户熟悉在Genesis-3D中定制水效的流程,并且了解shader的编写与使用和在脚本中使用RenderTexture,设置shader参数等渲染相关的技巧。

1. 创建一个面片,把工程资源中提供的waterplane拖入场景:





2. 创建一个材质文件,将其命名为water:



3. 创建一个文本文件命名为FX_Water.shader



在shader里用户可以自定义水面效果,在本实例中实现的大致思路如下,以供参考,完整代码请参阅工程资源内的FX_Water.shader。

01
//在顶点渲染器中控制顶点的移动
02
float3
offsets = GerstnerOffset4(worldpos.xz,Steepness,Amplitude,Frequency,Speed,DirectionAB,DirectionCD);
03
float3
nrml = GerstnerNormal4(worldpos.xz + offsets.xz,Amplitude,Frequency,Speed,DirectionAB,DirectionCD);
04
05
//计算UV
06
float4
projTex = p.input_ClipSpacePos;
07
projTex.xy
/= projTex.w;
08
projTex.x
= 0.5 * projTex.x + 0.5;
09
projTex.y
= -0.5 * projTex.y + 0.5;
10
projTex.xy
+= g_ScreenSize.zw;
11
12
float4
reflectCoord = p.input_ClipSpacePos;
13
reflectCoord.xy
/= reflectCoord.w;
14
reflectCoord.x
*= -1.0f;
15
reflectCoord.x
= 0.5 * reflectCoord.x + 0.5;
16
reflectCoord.y
= -0.5 * reflectCoord.y + 0.5;
17
reflectCoord.xy
+= g_ScreenSize.zw;
18
19
//采样反射与折射
20
float4
reflectCol = tex2D(_reflectionMap,reflectCoord.xy+perturbVec);
21
loat4
refractCol = tex2D(_refractionMap,projTex.xy-perturbVec);
22
23
//混合像素颜色
24
refractCol
*= 1 + depth.y * CausticPower;
25
refractCol
= lerp(WaterColor,refractCol,depth.x);
26
float
refractWt
= saturate(RefractBias + pow(max(dot(viewdir,normalW),0.0f),RefractPower));
27
float4
lerp_color = lerp(reflectCol,refractCol,refractWt);
28
29
float4
spec = t * WaterSpecColor;
30
float4
diffuse = (lerp_color * g_LightDiffuse[0] * WaterDiffuseColor);
31
o.Diffuse
= diffuse + spec;
4. 设置waterplane的材质为water,设置water的shader为FX_Water.shader:



5. 创建一个脚本文件,命名为WaterRender.cs



在脚本文件中用户可以自由创建相机,绘制RT,设置shader参数用以完善效果,制作更加真实高级的水面效果 在本实例中实现的大致思路如下,以供参考,完整代码请参阅工程资源内的WaterRender.cs

01
//设定反射矩阵
02
private
Matrix44
Reflect(Vector4 plane)
03
{
04
Matrix44
matout =
new
Matrix44();
05
matout[0,
0] = -2.0f * plane.X * plane.X + 1.0f;
06
matout[0,
1] = -2.0f * plane.X * plane.Y;
07
matout[0,
2] = -2.0f * plane.X * plane.Z;
08
matout[0,
3] = -2.0f * plane.X * plane.W;
09
10
matout[1,
0] = -2.0f * plane.Y * plane.X;
11
matout[1,
1] = -2.0f * plane.Y * plane.Y + 1.0f;
12
matout[1,
2] = -2.0f * plane.Y * plane.Z;
13
matout[1,
3] = -2.0f * plane.Y * plane.W;
14
15
matout[2,
0] = -2.0f * plane.Z * plane.X;
16
matout[2,
1] = -2.0f * plane.Z * plane.Y;
17
matout[2,
2] = -2.0f * plane.Z * plane.Z + 1.0f;
18
matout[2,
3] = -2.0f * plane.Z * plane.W;
19
matout[3,
0] = 0.0f; matout[3,1] = 0.0f; matout[3,2] = 0.0f; matout[3,3] = 1.0f;
20
return
matout;
21
}
22
23
24
//创建折射相机与RT
25
private
void
CreateReflect()
26
{
27
int
width
= GraphicSystem.GetWidth();
28
int
height
= GraphicSystem.GetHeight();
29
Vector4
color =
new
Vector4(0.25f,0.25f,0.25f,1.0f);
30
31
32
reflectRtt
=
new
RenderToTexture();
33
reflectRtt.Setup(width
/ 2,height / 2,PixelFormat.X8R8G8B8,ClearFlag.ClearAll,
ref
color,
true
);
34
35
36
37
reflectCam
=
new
Camera();
38
reflectCam.SetupPerspectiveFovRH(0.75f,
width / height,1.0f,10000.0f);
39
reflectCam.SetRenderTarget(reflectRtt);
40
reflectCam.SetLightLitTexture(lightlit);
41
reflectCam.RenderDepth
=
false
;
42
reflectCam.RenderNormal
=
true
;
43
reflectCam.RenderCustomised
=
true
;
44
reflectCam.CullMask
= RenderLayer.eRLDefault;
45
reflectCam.UseBeforeDrawEvent
=
false
;
46
reflectCam.RenderShadowMap
=
false
;
47
}
48
49
private
void
CreateRefract()
50
{
51
int
width
= GraphicSystem.GetWidth();
52
int
height
= GraphicSystem.GetHeight();
53
Vector4
color =
new
Vector4(0.25f,0.25f,0.25f,1.0f);
54
refractRtt
=
new
RenderToTexture();
55
refractRtt.Setup(width
/ 2,height / 2,PixelFormat.A16B16G16R16F,ClearFlag.ClearAll,
ref
color,
true
);
56
57
refractCam
=
new
Camera();
58
refractCam.SetupPerspectiveFovRH(0.75f,
width / height,1.0f,10000.0f);
59
refractCam.SetRenderTarget(refractRtt);
60
refractCam.SetLightLitTexture(lightlit);
61
refractCam.RenderDepth
=
false
;
62
refractCam.RenderNormal
=
true
;
63
refractCam.RenderCustomised
=
true
;
64
refractCam.CullMask
= RenderLayer.eRLDefault;
65
refractCam.UseBeforeDrawEvent
=
false
;
66
refractCam.RenderShadowMap
=
false
;
67
}
68
69
70
71
//设置其他材质参数
72
meshRenderCom.SetTexture(0,
"_waveMap"
,
"asset:Media/Waterbump.dds"
,
0);
73
meshRenderCom.SetTexture(0,
"_fresnelMap"
,
"asset:Media/WaterFresnel.dds"
,
0);
74
meshRenderCom.SetTexture(0,
"_reflectionMap"
,
reflectRtt);
75
meshRenderCom.SetTexture(0,
"_refractionMap"
,
refractRtt);
76
77
//渲染反射与折射相机
78
public
override
void
OnWillRenderObject(RenderComponent
sender)
79
{
80
Owner.LayerID
= 4;
81
if
(reflectCam
==
null
)
82
{
83
 
lightlit
=
new
RenderToTexture();
84
 
Vector4
lightlitColor = Vector4.One;
85
 
lightlit.Setup(1,
1,PixelFormat.X8R8G8B8,ClearFlag.ClearAll,
ref
lightlitColor,
false
);
86
87
 
CreateReflect();
88
 
CreateRefract();
89
 
SetupMat();
90
}
91
 
92
UpdateRefract();
93
UpdateReflect();
94
//---------------------uv
offest-----------------------//
95
UpdataMat();
96
97
GraphicSystem.RenderCamera(reflectCam);
98
GraphicSystem.RenderCamera(refractCam);
99
}
6. 将脚本挂接在waterplane上:



7. 导入实例资源内提供的wave0.dds、wave1.dds、Waterbump.dds、WaterFresnel.dds 将wave1和wave2设置给材质中的_waveMap1和_waveMap2两个参数,两外张图是脚本中设置的材质资源。



8. 调整shader反射的参数,定制出属于自己的水面效果:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: