- Home /
How to create water like in Monument Valley ?
I have modelled a 3D mesh with irregular polygons in Maya and imported it into Unity. How do I create the wavey motion on the 3D mesh of the water ? A possible reference to it is as picture below.
Static pictures are not the easiest media to describe motion ;) However, I think you're just describing the sinusoidal vertex displacement on the y axis? This can be done through mesh.vertices or in the shader assigned to the material.
I read about the sinusoidal vertex displacement posting the question, however I'm not sure how to manipulate the vertices of the mesh in a way that it looks like the reference picture. To make more sense of how the movement works, check this link out. Reference Video It happens at time 29$$anonymous$$s 49secs.
Answer by robertbu · Oct 31, 2014 at 05:57 AM
Some thoughts watching the video:
Building the mesh so that every triangle has a unique set of vertices (no triangle shares vertices), and assigning the same normal to all three of the vertices on each triangle will give you the blocky look. When you construct the mesh, you will have six vertices per quad.
As mentioned above you can use sine calculations to undulate the waves. Here is one answer that is applied to a traditional mesh (i.e. shared vertices) that you might be able to use as a starting point:
http://answers.unity3d.com/questions/443031/sinus-for-rolling-waves.html
The floating objects don't interact with the mesh. The sense of waves and spray can be done by a particle system and some sort of dynamic decal.
Thanks for the reply, @robertbu. The mesh I'm using has exactly what you are suggesting, i.e, no shared vertices and 6 vertices per quad. I managed to create the exact motion in $$anonymous$$aya, that I require to be created in Unity. You can take a look at it HERE.
I tried using the Perlin Noise script that you used in your answer on the page you linked. It moves the entire mesh as a part of a single wave, ins$$anonymous$$d of creating smaller waves inside it. So, it looks like a waving cloth in the wind ins$$anonymous$$d of waves on a water surface. This is what it looks like in Unity - LIN$$anonymous$$.
Just so that you know, the mesh I'm using is quite irregular but each face is a triangle. This was done to bring a more organic feel to the surface of the sea. In the Import mesh options, I also set the Normals to Calculate, and Smoothing Angle to 0.
Here is a bit of code to try. I was just getting started expecting to have to play a while to get something that looked good, but my first try with only $$anonymous$$or setting changes looks pretty good to my untrained eye. Replace your 'wave' script with the following:
#pragma strict
var waveSource1 : Vector3 = Vector3(2.0, 0.0, 2.0);
var freq1 : float = 0.1;
var amp1 : float = 0.01;
var waveLength1 : float = 0.05;
private var mesh : $$anonymous$$esh;
private var vertices : Vector3[];
function Start () {
var mf = GetComponent($$anonymous$$eshFilter);
if (mf == null) {
Debug.Log("No mesh filter");
return;
}
mesh = mf.mesh;
vertices = mesh.vertices;
}
function Update () {
CalcWave();
}
function CalcWave() {
for (var i = 0; i < vertices.Length; i++) {
var v = vertices[i];
v.y = 0.0f;
var dist = Vector3.Distance(v, waveSource1);
dist = (dist % waveLength1) / waveLength1;
v.y = amp1 * $$anonymous$$athf.Sin(Time.time * $$anonymous$$athf.PI * 2.0f * freq1 + ($$anonymous$$athf.PI * 2.0 * dist));
vertices[i] = v;
}
mesh.vertices = vertices;
}
Note the original code I pointed you to also created a nice wave pattern. As a guess (I did not debug it), your issue in applying the code as-is was the scale of your Ocean mesh. The local scale of your Ocean is only 0.6 x 0.6.
Some screenshots of a quick test scene using the above shader!
Although it is a kind of a cheat, that works just fine ! If I find the reason why the previous shader wasn't supported on Android, I'll post it here. The blocky wave motion and how the shading works is exactly all that I needed.Thanks a lot @robertbu and @Scribe for all your suggestions and ideas and codes that you shared.
I know this has been 'answered' but incase it is useful here's a second shader script! I am very newbie at shader coding so this is good practice for me! :D
Shader "Custom/NormalLighting" {
Properties {
_$$anonymous$$ainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
}
SubShader {
Pass {
CGPROGRA$$anonymous$$
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
uniform sampler2D _$$anonymous$$ainTex;
struct appdata {
float4 vertex : POSITION;
float3 normal : NOR$$anonymous$$AL;
fixed4 color : COLOR;
};
struct v2f {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
float2 uv : TEXCOORD0;
};
v2f vert (appdata v) {
v2f o;
o.pos = mul( UNITY_$$anonymous$$ATRIX_$$anonymous$$VP, v.vertex );
float3 worldNormal = normalize(mul(_Object2World, float4(v.normal, 0.0)).xyz);
float3 b = worldNormal;
o.uv = float2(0.5+(b.x/2), 0.5+(b.z/2));
return o;
}
fixed4 frag (v2f i) : COLOR0 {
return tex2D (_$$anonymous$$ainTex, i.uv);
}
ENDCG
}
}
FallBack "Diffuse"
}
Answer by Almostpic · Nov 13, 2014 at 02:40 PM
Great code ! I translated it in C# for those who are interested :
using UnityEngine;
using System.Collections;
public class waves : MonoBehaviour {
Vector3 waveSource1 = new Vector3 (2.0f, 0.0f, 2.0f);
public float freq1 = 0.1f;
public float amp1 = 0.01f;
public float waveLength1 = 0.05f;
Mesh mesh;
Vector3[] vertices;
// Use this for initialization
void Start () {
MeshFilter mf = GetComponent<MeshFilter>();
if(mf == null)
{
Debug.Log("No mesh filter");
return;
}
mesh = mf.mesh;
vertices = mesh.vertices;
}
// Update is called once per frame
void Update () {
CalcWave();
}
void CalcWave()
{
for(int i = 0; i < vertices.Length; i++)
{
Vector3 v = vertices[i];
v.y = 0.0f;
float dist = Vector3.Distance(v, waveSource1);
dist = (dist % waveLength1) / waveLength1;
v.y = amp1 * Mathf.Sin(Time.time * Mathf.PI * 2.0f * freq1
+ (Mathf.PI * 2.0f * dist));
vertices[i] = v;
}
mesh.vertices = vertices;
}
}
Your answer
Follow this Question
Related Questions
Create a water drop simulation 1 Answer
blurred out images? 1 Answer
Water of cubes? 2 Answers
Water for Android OS (Tegra Tango) 0 Answers
Google Earth, Sketchup, Global Mapper - best way to generate terrain 1 Answer