public override void Load() { if (Fetched) { return; } var images = DoFetchImages(FileNames); _fft = Fourier.FFT2(Images[0], false); ViewColumns = 9; ViewRows = 9; Images = images; Rearrange(0, 0, 300, 150, 9); }
private void DoApply(UnmanagedImage image, UnmanagedImage output) { var fimg = Fourier.FFT2(image); if (Width != fimg.Width || Height != fimg.Height) { throw new DimensionMismatchException(); } fimg.C0.MultiplyWith(C0); fimg.C1.MultiplyWith(C1); fimg.C2.MultiplyWith(C2); output.Draw(fimg.InverseFFT2(false)); }
void GenerateBumpmaps() { if (!normalDone) { for (int idx = 0; idx < 2; idx++) { for (int y = 0; y < n_height; y++) { for (int x = 0; x < n_width; x++) { float yc = y < n_height / 2 ? y : -n_height + y; float xc = x < n_width / 2 ? x : -n_width + x; Vector2 vec_k = new Vector2(2.0f * Mathf.PI * xc / (size.x / normal_scale), 2.0f * Mathf.PI * yc / (size.z / normal_scale)); float iwkt = idx == 0 ? 0.0f : Mathf.PI / 2; ComplexF coeffA = new ComplexF(Mathf.Cos(iwkt), Mathf.Sin(iwkt)); ComplexF coeffB = coeffA.GetConjugate(); int ny = y > 0 ? n_height - y : 0; int nx = x > 0 ? n_width - x : 0; n_x[n_width * y + x] = (n0[n_width * y + x] * coeffA + n0[n_width * ny + nx].GetConjugate() * coeffB) * new ComplexF(0.0f, -vec_k.x); n_y[n_width * y + x] = (n0[n_width * y + x] * coeffA + n0[n_width * ny + nx].GetConjugate() * coeffB) * new ComplexF(0.0f, -vec_k.y); } } Fourier.FFT2(n_x, n_width, n_height, FourierDirection.Backward); Fourier.FFT2(n_y, n_width, n_height, FourierDirection.Backward); for (int i = 0; i < n_width * n_height; i++) { Vector3 bump = new Vector3(n_x[i].Re * Mathf.Abs(n_x[i].Re), n_y[i].Re * Mathf.Abs(n_y[i].Re), n_width * n_height / scale / normal_scale * normalStrength).normalized * 0.5f; pixelData[i] = new Color(bump.x + 0.5f, bump.y + 0.5f, bump.z + 0.8f); // pixelData[i] = Color (0.5, 0.5, 1.0); } if (idx == 0) { textureA.SetPixels(pixelData, 0); textureA.Apply(); } else { textureB.SetPixels(pixelData, 0); textureB.Apply(); } } normalDone = true; } }
private void miBackwardFFT_Click(object sender, System.EventArgs e) { if (this.ActiveCImage == null) { return; } CImage cimage = this.ActiveCImage; float scale = 1f / (float)Math.Sqrt(cimage.Width * cimage.Height); ComplexF[] data = cimage.Data; Fourier.FFT2(data, cimage.Width, cimage.Height, FourierDirection.Backward); int offset = 0; for (int y = 0; y < cimage.Height; y++) { for (int x = 0; x < cimage.Width; x++) { if (((x + y) & 0x1) != 0) { data[offset] *= -1; } offset++; } } cimage.FrequencySpace = false; for (int i = 0; i < data.Length; i++) { data[i] *= scale; } this.ActiveCImage = cimage; }
void Update() { //If player null, search for player by Player tag if (player == null) { player = GameObject.FindGameObjectWithTag("Player").GetComponent <Transform>(); } //Get sun reflection dir from sun object if (sun != null) { SunDir = sun.transform.forward; material.SetVector("_SunDir", SunDir); } if (this.renderReflection) { RenderObject(); } if (followMainCamera) { Vector3 centerOffset; //centerOffset.x = Mathf.Floor (player.position.x / size.x) * size.x; //centerOffset.z = Mathf.Floor (player.position.z / size.z) * size.z; centerOffset.y = transform.position.y; //centerOffset.x = (((int)player.position.x + 64) & ~127); //centerOffset.z = (((int)player.position.z + 64) & ~127); //Optimized ocean tiles movement centerOffset.x = Mathf.Floor((player.position.x + size.x * 0.5f) * sizeInv.x) * size.x; centerOffset.z = Mathf.Floor((player.position.z + size.z * 0.5f) * sizeInv.y) * size.z; if (transform.position != centerOffset) { transform.position = centerOffset; } } float hhalf = height / 2f; float whalf = width / 2f; float time = Time.time; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int idx = width * y + x; float yc = y < hhalf ? y : -height + y; float xc = x < whalf ? x : -width + x; Vector2 vec_k = new Vector2(2.0f * Mathf.PI * xc / size.x, 2.0f * Mathf.PI * yc / size.z); float sqrtMagnitude = (float)System.Math.Sqrt((vec_k.x * vec_k.x) + (vec_k.y * vec_k.y)); float iwkt = (float)System.Math.Sqrt(9.81f * sqrtMagnitude) * time * speed; ComplexF coeffA = new ComplexF((float)System.Math.Cos(iwkt), (float)System.Math.Sin(iwkt)); ComplexF coeffB; coeffB.Re = coeffA.Re; coeffB.Im = -coeffA.Im; int ny = y > 0 ? height - y : 0; int nx = x > 0 ? width - x : 0; data [idx] = h0 [idx] * coeffA + h0[width * ny + nx].GetConjugate() * coeffB; t_x [idx] = data [idx] * new ComplexF(0.0f, vec_k.x) - data [idx] * vec_k.y; // Choppy wave calculations if (x + y > 0) { data [idx] += data [idx] * vec_k.x / sqrtMagnitude; } } } Fourier.FFT2(data, width, height, FourierDirection.Backward); Fourier.FFT2(t_x, width, height, FourierDirection.Backward); // Get base values for vertices and uv coordinates. if (baseHeight == null) { baseHeight = baseMesh.vertices; vertices = new Vector3[baseHeight.Length]; normals = new Vector3[baseHeight.Length]; tangents = new Vector4[baseHeight.Length]; } int wh = width * height; float scaleA = choppy_scale / wh; float scaleB = scale / wh; float scaleBinv = 1.0f / scaleB; for (int i = 0; i < wh; i++) { int iw = i + i / width; vertices [iw] = baseHeight [iw]; vertices [iw].x += data [i].Im * scaleA; vertices [iw].y = data [i].Re * scaleB; normals [iw] = Vector3.Normalize(new Vector3(t_x [i].Re, scaleBinv, t_x [i].Im)); if (((i + 1) % width) == 0) { int iwi = iw + 1; int iwidth = i + 1 - width; vertices [iwi] = baseHeight [iwi]; vertices [iwi].x += data [iwidth].Im * scaleA; vertices [iwi].y = data [iwidth].Re * scaleB; normals [iwi] = Vector3.Normalize(new Vector3(t_x [iwidth].Re, scaleBinv, t_x [iwidth].Im)); } } int offset = g_width * (g_height - 1); for (int i = 0; i < g_width; i++) { int io = i + offset; int mod = i % width; vertices [io] = baseHeight [io]; vertices [io].x += data [mod].Im * scaleA; vertices [io].y = data [mod].Re * scaleB; normals [io] = Vector3.Normalize(new Vector3(t_x [mod].Re, scaleBinv, t_x [mod].Im)); } int gwgh = g_width * g_height - 1; for (int i = 0; i < gwgh; i++) { //Need to preserve w in refraction/reflection mode if (!reflectionRefractionEnabled) { if (((i + 1) % g_width) == 0) { tangents [i] = Vector3.Normalize((vertices [i - width + 1] + new Vector3(size.x, 0.0f, 0.0f) - vertices [i])); } else { tangents [i] = Vector3.Normalize((vertices [i + 1] - vertices [i])); } tangents [i].w = 1.0f; } else { Vector3 tmp; // = Vector3.zero; if (((i + 1) % g_width) == 0) { tmp = Vector3.Normalize(vertices[i - width + 1] + new Vector3(size.x, 0.0f, 0.0f) - vertices [i]); } else { tmp = Vector3.Normalize(vertices [i + 1] - vertices [i]); } tangents [i] = new Vector4(tmp.x, tmp.y, tmp.z, tangents [i].w); } } //Vector3 playerRelPos = player.position - transform.position; //In reflection mode, use tangent w for foam strength if (reflectionRefractionEnabled) { for (int y = 0; y < g_height; y++) { for (int x = 0; x < g_width; x++) { int item = x + g_width * y; if (x + 1 >= g_width) { tangents [item].w = tangents [g_width * y].w; continue; } if (y + 1 >= g_height) { tangents [item].w = tangents [x].w; continue; } float right = vertices[(x + 1) + g_width * y].x - vertices[item].x; float foam = right / (size.x / g_width); if (foam < 0.0f) { tangents [item].w = 1f; } else if (foam < 0.5f) { tangents [item].w += 3.0f * Time.deltaTime; } else { tangents [item].w -= 0.4f * Time.deltaTime; } if (player != null) { Vector3 player2Vertex = (player.position - vertices[item] - transform.position); // foam around boat if (player2Vertex.x >= size.x) { player2Vertex.x -= size.x; } if (player2Vertex.x <= -size.x) { player2Vertex.x += size.x; } if (player2Vertex.z >= size.z) { player2Vertex.z -= size.z; } if (player2Vertex.z <= -size.z) { player2Vertex.z += size.z; } player2Vertex.y = 0; if (player2Vertex.sqrMagnitude < wakeDistance * wakeDistance) { tangents[item].w += 3.0f * Time.deltaTime; } } tangents [item].w = Mathf.Clamp(tangents[item].w, 0.0f, 2.0f); } } } tangents [gwgh] = Vector4.Normalize(vertices [gwgh] + new Vector3(size.x, 0.0f, 0.0f) - vertices [1]); for (int L0D = 0; L0D < max_LOD; L0D++) { int den = (int)System.Math.Pow(2f, L0D); int itemcount = (int)((height / den + 1) * (width / den + 1)); Vector4[] tangentsLOD = new Vector4[itemcount]; Vector3[] verticesLOD = new Vector3[itemcount]; Vector3[] normalsLOD = new Vector3[itemcount]; int idx = 0; for (int y = 0; y < g_height; y += den) { for (int x = 0; x < g_width; x += den) { int idx2 = g_width * y + x; verticesLOD [idx] = vertices [idx2]; tangentsLOD [idx] = tangents [idx2]; normalsLOD [idx++] = normals [idx2]; } } for (int k = 0; k < tiles_LOD[L0D].Count; k++) { Mesh meshLOD = tiles_LOD [L0D][k]; meshLOD.vertices = verticesLOD; meshLOD.normals = normalsLOD; meshLOD.tangents = tangentsLOD; } } }
public DeblurFilter(UnmanagedImage reference, UnmanagedImage blurred) : this(Fourier.FFT2(reference), Fourier.FFT2(blurred)) { }
// Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.P)) { Application.CaptureScreenshot("Screenshot.png"); } for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int idx = width * y + x; float yc = y < height / 2 ? y : -height + y; float xc = x < width / 2 ? x : -width + x; Vector2 vec_k = new Vector2(2.0f * Mathf.PI * xc / size.x, 2.0f * Mathf.PI * yc / size.z); float iwkt = disp(vec_k) * Time.time; ComplexF coeffA = new ComplexF(Mathf.Cos(iwkt), Mathf.Sin(iwkt)); ComplexF coeffB = coeffA.GetConjugate(); int ny = y > 0 ? height - y : 0; int nx = x > 0 ? width - x : 0; data[idx] = h0[idx] * coeffA + h0[width * ny + nx].GetConjugate() * coeffB; t_x[idx] = data[idx] * new ComplexF(0.0f, vec_k.x) - data[idx] * vec_k.y; // Choppy wave calcuations if (x + y > 0) { data[idx] += data[idx] * vec_k.x / vec_k.magnitude; } } } material_ocean.SetFloat("_BlendA", Mathf.Cos(Time.time) * 0.1f); material_ocean.SetFloat("_BlendB", Mathf.Sin(Time.time) * 0.5f); Fourier.FFT2(data, width, height, FourierDirection.Backward); Fourier.FFT2(t_x, width, height, FourierDirection.Backward); // Get base values for vertices and uv coordinates. if (baseHeight == null) { Mesh mesh = baseMesh; baseHeight = mesh.vertices; baseUV = mesh.uv; int itemCount = baseHeight.Length; uvs = new Vector2[itemCount]; vertices = new Vector3[itemCount]; normals = new Vector3[itemCount]; tangents = new Vector4[itemCount]; } //Vector3 vertex; Vector3 uv; //Vector3 normal; float n_scale = size.x / width / scale; float scaleA = choppy_scale / (width * height); float scaleB = scale / (width * height); float scaleBinv = 1.0f / scaleB; for (int i = 0; i < width * height; i++) { int iw = i + i / width; vertices[iw] = baseHeight[iw]; vertices[iw].x += data[i].Im * scaleA; vertices[iw].y = data[i].Re * scaleB; normals[iw] = new Vector3(t_x[i].Re, scaleBinv, t_x[i].Im).normalized; uv = baseUV[iw]; uv.x = uv.x + Time.time * uv_speed; uvs[iw] = uv; if (!((i + 1) % width > 0)) { vertices[iw + 1] = baseHeight[iw + 1]; vertices[iw + 1].x += data[i + 1 - width].Im * scaleA; vertices[iw + 1].y = data[i + 1 - width].Re * scaleB; normals[iw + 1] = new Vector3(t_x[i + 1 - width].Re, scaleBinv, t_x[i + 1 - width].Im).normalized; uv = baseUV[iw + 1]; uv.x = uv.x + Time.time * uv_speed; uvs[iw + 1] = uv; } } int offset = g_width * (g_height - 1); for (int i = 0; i < g_width; i++) { vertices[i + offset] = baseHeight[i + offset]; vertices[i + offset].x += data[i % width].Im * scaleA; vertices[i + offset].y = data[i % width].Re * scaleB; normals[i + offset] = new Vector3(t_x[i % width].Re, scaleBinv, t_x[i % width].Im).normalized; uv = baseUV[i + offset]; uv.x = uv.x - Time.time * uv_speed; uvs[i + offset] = uv; } for (int i = 0; i < g_width * g_height - 1; i++) { //Need to preserve w in refraction/reflection mode if (!reflectionRefractionEnabled) { if (((i + 1) % g_width) == 0) { tangents[i] = (vertices[i - width + 1] + new Vector3(size.x, 0.0f, 0.0f) - vertices[i]).normalized; } else { tangents[i] = (vertices[i + 1] - vertices[i]).normalized; } tangents[i].w = 1.0f; } else { Vector3 tmp = Vector3.zero; if (((i + 1) % g_width) == 0) { tmp = (vertices[i - width + 1] + new Vector3(size.x, 0.0f, 0.0f) - vertices[i]).normalized; } else { tmp = (vertices[i + 1] - vertices[i]).normalized; } tangents[i] = new Vector4(tmp.x, tmp.y, tmp.z, tangents[i].w); } } //In reflection mode, use tangent w for foam strength if (reflectionRefractionEnabled) { for (int y = 0; y < g_height; y++) { for (int x = 0; x < g_width; x++) { if (x + 1 >= g_width) { tangents[x + g_width * y].w = tangents[g_width * y].w; continue; } if (y + 1 >= g_height) { tangents[x + g_width * y].w = tangents[x].w; continue; } Vector3 right = vertices[(x + 1) + g_width * y] - vertices[x + g_width * y]; Vector3 back = vertices[x + g_width * y] - vertices[x + g_width * (y + 1)]; float foam = right.x / (size.x / g_width); if (foam < 0.0f) { tangents[x + g_width * y].w = 1; } else if (foam < 0.5f) { tangents[x + g_width * y].w += 2 * Time.deltaTime; } else { tangents[x + g_width * y].w -= 0.5f * Time.deltaTime; } tangents[x + g_width * y].w = Mathf.Clamp(tangents[x + g_width * y].w / foamTime, 0.0f, 2.0f); } } } tangents[g_width * g_height - 1] = (vertices[g_width * g_height - 1] + new Vector3(size.x, 0.0f, 0.0f) - vertices[1]).normalized; //~ LOD=0; for (int LOD = 0; LOD < max_LOD; LOD++) { int den = (int)Mathf.Pow(2, LOD); int itemcount = (height / den + 1) * (width / den + 1); Vector4[] tangentsLOD = new Vector4[itemcount]; Vector3[] verticesLOD = new Vector3[itemcount]; Vector3[] normalsLOD = new Vector3[itemcount]; Vector2[] uvLOD = new Vector2[(height / (int)Mathf.Pow(2, LOD) + 1) * (width / (int)Mathf.Pow(2, LOD) + 1)]; int idx = 0; for (int y = 0; y < g_height; y += den) { for (int x = 0; x < g_width; x += den) { int idx2 = g_width * y + x; verticesLOD[idx] = vertices[idx2]; uvLOD[idx] = uvs[g_width * y + x]; tangentsLOD[idx] = tangents[idx2]; normalsLOD[idx++] = normals[idx2]; } } for (int k = 0; k < tiles_LOD[LOD].Count; k++) { Mesh meshLOD = tiles_LOD[LOD][k]; meshLOD.vertices = verticesLOD; meshLOD.normals = normalsLOD; meshLOD.uv = uvLOD; meshLOD.tangents = tangentsLOD; } } //oceansize=width*(max_LOD*2+1); float width_LOD2 = 175 * s; //transform.position.x=mycam.transform.localPosition.x; float tmpx = Mathf.RoundToInt(mycam.transform.position.x / width_LOD2); float tmpz = Mathf.RoundToInt(mycam.transform.position.z / width_LOD2); tmpx = tmpx * width_LOD2 - (width_LOD2 / 2); tmpz = tmpz * width_LOD2 - (width_LOD2 / 2); //tmpx-=Mathf.RoundToInt(width_LOD2); //tmpz-=Mathf.RoundToInt(width_LOD2); //~ transform.position.x=tmpx; //~ transform.position.z=tmpz; transform.position = new Vector3(tmpx, transform.position.y, tmpz); //transform.position.z=mycam.transform.localPosition.z*1000; }
public iTemplate(Bitmap myImage) { //BitmapFilter.GrayScale(myImage); BitmapFilter.FixHistogram(ref myImage); // myImage.Save("FixedHistogram.bmp", System.Drawing.Imaging.ImageFormat.Bmp); BitmapFilter.Binarize(ref myImage, 110); // myImage.Save("Binarized.bmp", System.Drawing.Imaging.ImageFormat.Bmp); //BitmapFilter.GaussianBlur(myImage, 1); /******************************************************/ CImage cimage = new CImage(myImage); float scale = 1f / (float)Math.Sqrt(cimage.Width * cimage.Height); ComplexF[] data = cimage.Data; int offset = 0; for (int y = 0; y < cimage.Height; y++) { for (int x = 0; x < cimage.Width; x++) { if (((x + y) & 0x1) != 0) { data[offset] *= -1; } offset++; } } Fourier.FFT2(data, cimage.Width, cimage.Height, FourierDirection.Forward); cimage.FrequencySpace = true; for (int i = 0; i < data.Length; i++) { data[i] *= scale; } myImage = cimage.ToBitmap(); // myImage.Save("FFT.bmp", System.Drawing.Imaging.ImageFormat.Bmp); //pictureBoxFiltred.Size = new System.Drawing.Size(myImage.Width, myImage.Height); /******************************************************/ Bitmap zerImage = new Bitmap(zerSize, zerSize); int ow, oh; ow = myImage.Width / 2 - zerSize / 2; oh = myImage.Height / 2 - zerSize / 2; for (int y = 0; y < zerSize; y++) { for (int x = 0; x < zerSize; x++) { zerImage.SetPixel(x, y, myImage.GetPixel(x + ow, y + oh)); } } ZernikeDesc zernikeDesc = new ZernikeDesc(zerImage); zerCoefficients = zernikeDesc.Process(); }
/// <summary> /// Update is called once per frame. /// </summary> private void Update() { if (!simulationEnabled) { return; } // Calculate mesh vertices, uv and tangents. float halfWidth = tilePolygonWidth / 2.0f; float halfHeight = tilePolygonHeight / 2.0f; float time = Time.time; for (int y = 0; y < tilePolygonHeight; ++y) { for (int x = 0; x < tilePolygonWidth; ++x) { int idx = tilePolygonWidth * y + x; float yCopy = y < halfHeight ? y : y - tilePolygonHeight; float xCopy = x < halfWidth ? x : x - tilePolygonWidth; Vector2 vecK = new Vector2(2.0f * Mathf.PI * xCopy / oceanTileSize.x, 2.0f * Mathf.PI * yCopy / oceanTileSize.z); float sqrtMagnitude = (float)Math.Sqrt(Mathf.Pow(vecK.x, 2.0f) + Mathf.Pow(vecK.y, 2.0f)); float offset = Mathf.Sqrt(GRAVITY_ACCELERATION * sqrtMagnitude) * time * waveSpeed; ComplexF complexFA = new ComplexF(Mathf.Cos(offset), Mathf.Sin(offset)); ComplexF complexFB; complexFB.Re = complexFA.Re; complexFB.Im = -complexFA.Im; int nY = y > 0 ? tilePolygonHeight - y : 0; int nX = x > 0 ? tilePolygonWidth - x : 0; waterHeightData[idx] = vertexSpectra[idx] * complexFA + vertexSpectra[tilePolygonWidth * nY + nX].GetConjugate() * complexFB; tangentX[idx] = waterHeightData[idx] * new ComplexF(0.0f, vecK.x) - waterHeightData[idx] * vecK.y; // Choppy wave calculation. if (x + y > 0) { waterHeightData[idx] += waterHeightData[idx] * vecK.x / sqrtMagnitude; } } } Fourier.FFT2(waterHeightData, tilePolygonWidth, tilePolygonHeight, FourierDirection.Backward); Fourier.FFT2(tangentX, tilePolygonWidth, tilePolygonHeight, FourierDirection.Backward); // Get base values for vertices and uv coordinates. if (baseHeights == null) { baseHeights = baseMesh.vertices; vertices = new Vector3[baseHeights.Length]; normals = new Vector3[baseHeights.Length]; tangents = new Vector4[baseHeights.Length]; } int area = tilePolygonWidth * tilePolygonHeight; float scaleX = choppyScale / area; float scaleY = waveScaleRealTime / area; float scaleYReciprocal = MathUtility.GetReciprocal(scaleY); for (int i = 0; i < area; ++i) { int index = i + i / tilePolygonWidth; vertices[index] = baseHeights[index]; vertices[index].x += waterHeightData[i].Im * scaleX; vertices[index].y = waterHeightData[i].Re * scaleY; normals[index] = Vector3.Normalize(new Vector3(tangentX[i].Re, scaleYReciprocal, tangentX[i].Im)); if ((i + 1) % tilePolygonWidth == 0) { int indexPlus = index + 1; int iWidth = i + 1 - tilePolygonWidth; vertices[indexPlus] = baseHeights[indexPlus]; vertices[indexPlus].x += waterHeightData[iWidth].Im * scaleX; vertices[indexPlus].y = waterHeightData[iWidth].Re * scaleY; normals[indexPlus] = Vector3.Normalize(new Vector3(tangentX[iWidth].Re, scaleYReciprocal, tangentX[iWidth].Im)); } } int indexOffset = geometryWidth * (geometryHeight - 1); for (int i = 0; i < geometryWidth; ++i) { int index = i + indexOffset; int mod = i % tilePolygonWidth; vertices[index] = baseHeights[index]; vertices[index].x += waterHeightData[mod].Im * scaleX; vertices[index].y = waterHeightData[mod].Re * scaleY; normals[index] = Vector3.Normalize(new Vector3(tangentX[mod].Re, scaleYReciprocal, tangentX[mod].Im)); } int geometryArea = geometryWidth * geometryHeight - 1; for (int i = 0; i < geometryArea; ++i) { Vector3 tmp; if ((i + 1) % geometryWidth == 0) { tmp = Vector3.Normalize(vertices[i - tilePolygonWidth + 1] + new Vector3(oceanTileSize.x, 0.0f, 0.0f) - vertices[i]); } else { tmp = Vector3.Normalize(vertices[i + 1] - vertices[i]); } tangents[i] = new Vector4(tmp.x, tmp.y, tmp.z, tangents[i].w); } for (int y = 0; y < geometryHeight; ++y) { for (int x = 0; x < geometryWidth; ++x) { int index = x + geometryWidth * y; if (x + 1 >= geometryWidth) { tangents[index].w = tangents[geometryWidth * y].w; continue; } if (y + 1 >= geometryHeight) { tangents[index].w = tangents[x].w; continue; } float right = vertices[x + 1 + geometryWidth * y].x - vertices[index].x; float foam = right / (oceanTileSize.x / geometryWidth); if (foam < 0.0f) { tangents[index].w = 1.0f; } else if (foam < 0.5f) { tangents[index].w += 3.0f * Time.deltaTime; } else { tangents[index].w -= 0.4f * Time.deltaTime; } tangents[index].w = Mathf.Clamp(tangents[index].w, 0.0f, 2.0f); } } tangents[geometryArea] = Vector4.Normalize(vertices[geometryArea] + new Vector3(oceanTileSize.x, 0.0f, 0.0f) - vertices[1]); for (int level = 0; level < MAX_LOD; ++level) { int pow = (int)Math.Pow(2.0f, level); int length = (int)((tilePolygonHeight / pow + 1) * (tilePolygonWidth / pow + 1)); Vector4[] tangentsLOD = new Vector4[length]; Vector3[] verticesLOD = new Vector3[length]; Vector3[] normalsLOD = new Vector3[length]; int index = 0; for (int y = 0; y < geometryHeight; y += pow) { for (int x = 0; x < geometryWidth; x += pow) { int indexTemp = geometryWidth * y + x; verticesLOD[index] = vertices[indexTemp]; tangentsLOD[index] = tangents[indexTemp]; normalsLOD[index++] = normals[indexTemp]; } } for (int i = 0, count = tilesLOD[level].Count; i < count; ++i) { Mesh meshLOD = tilesLOD[level][i]; meshLOD.vertices = verticesLOD; meshLOD.normals = normalsLOD; meshLOD.tangents = tangentsLOD; } } if (reflectionEnabled) { RenderReflectionAndRefraction(); } }