/// <summary> /// Given a position in world-space, returns the wave height and normal /// </summary> /// <param name="position">Sample position in world-space</param> /// <param name="waterObject">Water object component, used to get the water material and level (height)</param> /// <param name="rollStrength">Multiplier for the the normal strength</param> /// <param name="dynamicMaterial">If true, the material's wave parameters will be re-fetched with every function call</param> /// <param name="normal">Output upwards normal vector, perpendicular to the wave</param> /// <returns>Wave height, in world-space.</returns> public static float SampleWaves(UnityEngine.Vector3 position, WaterObject waterObject, float rollStrength, bool dynamicMaterial, out UnityEngine.Vector3 normal) { return(SampleWaves(position, waterObject.material, waterObject.transform.position.y, rollStrength, dynamicMaterial, out normal)); }
/// <summary> /// Given a position in world-space, returns the wave height and normal /// </summary> /// <param name="position">Sample position in world-space</param> /// <param name="waterMat">Material using StylizedWater2 shader</param> /// <param name="waterLevel">Height of the reference water plane.</param> /// <param name="rollStrength">Multiplier for the the normal strength</param> /// <param name="dynamicMaterial">If true, the material's wave parameters will be re-fetched with every function call</param> /// <param name="normal">Output upwards normal vector, perpendicular to the wave</param> /// <returns>Wave height, in world-space.</returns> public static float SampleWaves(UnityEngine.Vector3 position, Material waterMat, float waterLevel, float rollStrength, bool dynamicMaterial, out UnityEngine.Vector3 normal) { Profiler.BeginSample("Buoyancy sampling"); if (!waterMat) { normal = UnityEngine.Vector3.up; return(waterLevel); } //Fetch the material's wave parameters, so the exact calculations can be mirrored if (lastMaterial == null || lastMaterial.Equals(waterMat) == false) { GetMaterialParameters(waterMat); lastMaterial = waterMat; } if (dynamicMaterial || !Application.isPlaying) { GetMaterialParameters(waterMat); } Vector4 freq = new Vector4(1.3f, 1.35f, 1.25f, 1.25f) * (1 - waveParameters.distance) * 3f; direction1 = MultiplyVec4(dir1, waveParameters.direction); direction2 = MultiplyVec4(dir2, waveParameters.direction); Vector3 offsets = Vector3.zero; frequency = freq; realSpeed.x *= waveParameters.animationParams.x; realSpeed.y *= waveParameters.animationParams.y; realSpeed.z *= waveParameters.animationParams.x; realSpeed.w *= waveParameters.animationParams.y; for (int i = 0; i <= waveParameters.count; i++) { float t = 1f + ((float)i / (float)waveParameters.count); frequency *= t; AB.x = steepness.x * waveParameters.steepness * direction1.x * amp.x; AB.y = steepness.x * waveParameters.steepness * direction1.y * amp.x; AB.z = steepness.x * waveParameters.steepness * direction1.z * amp.y; AB.w = steepness.x * waveParameters.steepness * direction1.w * amp.y; CD.x = steepness.z * waveParameters.steepness * direction2.x * amp.z; CD.y = steepness.z * waveParameters.steepness * direction2.y * amp.z; CD.z = steepness.w * waveParameters.steepness * direction2.z * amp.w; CD.w = steepness.w * waveParameters.steepness * direction2.w * amp.w; planarPosition.x = position.x; planarPosition.y = position.z; #if MATHEMATICS dotABCD.x = Dot2(direction1.xy, planarPosition) * frequency.x; dotABCD.y = Dot2(direction1.zw, planarPosition) * frequency.y; dotABCD.z = Dot2(direction2.xy, planarPosition) * frequency.z; dotABCD.w = Dot2(direction2.zw, planarPosition) * frequency.w; #else dotABCD.x = Dot2(new Vector2(direction1.x, direction1.y), planarPosition) * frequency.x; dotABCD.y = Dot2(new Vector2(direction1.z, direction1.w), planarPosition) * frequency.y; dotABCD.z = Dot2(new Vector2(direction2.x, direction2.y), planarPosition) * frequency.z; dotABCD.w = Dot2(new Vector2(direction2.z, direction2.w), planarPosition) * frequency.w; #endif TIME = (_TimeParameters * waveParameters.animationParams.z * waveParameters.speed * speed); sine.x = Sine(dotABCD.x + TIME.x); sine.y = Sine(dotABCD.y + TIME.y); sine.z = Sine(dotABCD.z + TIME.z); sine.w = Sine(dotABCD.w + TIME.w); cosine.x = Cosine(dotABCD.x + TIME.x); cosine.y = Cosine(dotABCD.y + TIME.y); cosine.z = Cosine(dotABCD.z + TIME.z); cosine.w = Cosine(dotABCD.w + TIME.w); offsets.x += Dot4(cosine, new Vector4(AB.x, AB.z, CD.x, CD.z)); offsets.y += Dot4(sine, amp); offsets.z += Dot4(cosine, new Vector4(AB.y, AB.w, CD.y, CD.w)); } rollStrength *= Mathf.Lerp(0.001f, 0.1f, waveParameters.steepness); normal = new Vector3(-offsets.x * rollStrength * waveParameters.height, 2f, -offsets.z * rollStrength * waveParameters.height); #if MATHEMATICS normal = normalize(normal); #else normal = normal.normalized; #endif //Average height offsets.y /= waveParameters.count; Profiler.EndSample(); return((offsets.y * waveParameters.height) + waterLevel); }
public static float SampleWaves(Vector3 position, Material waterMat, float waterLevel, float rollStrength, out UnityEngine.Vector3 normal) { return(SampleWaves(position, waterMat, waterLevel, rollStrength, false, out normal)); }