Release a Compute Buffer.
/*****/ private void CreateDistanceField() { var size = 128; var pdbName = "MA_matrix_G1"; string path = "Assets/Resources/3D Textures/" + pdbName + ".asset"; Texture3D tmp = (Texture3D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture3D)); if (tmp) { _volumeTexture = tmp; } else { RenderTexture _distanceFieldRT; _distanceFieldRT = new RenderTexture(size, size, 0, RenderTextureFormat.R8); _distanceFieldRT.volumeDepth = size; _distanceFieldRT.isVolume = true; _distanceFieldRT.isPowerOfTwo = true; _distanceFieldRT.enableRandomWrite = true; _distanceFieldRT.filterMode = FilterMode.Trilinear; _distanceFieldRT.name = pdbName; _distanceFieldRT.hideFlags = HideFlags.HideAndDontSave; _distanceFieldRT.generateMips = true; _distanceFieldRT.useMipMap = true; _distanceFieldRT.Create(); var atomSpheres = PdbLoader.LoadAtomSpheres(pdbName); var atomSphereGPUBuffer = new ComputeBuffer(atomSpheres.Count, sizeof(float) * 4, ComputeBufferType.Default); atomSphereGPUBuffer.SetData(atomSpheres.ToArray()); Graphics.SetRenderTarget(_distanceFieldRT); GL.Clear(true, true, new Color(0, 0, 0)); var createDistanceFieldCS = Resources.Load("Compute Shaders/CreateDistanceField") as ComputeShader; createDistanceFieldCS.SetInt("_GridSize", size); createDistanceFieldCS.SetInt("_NumAtoms", atomSpheres.Count); createDistanceFieldCS.SetBuffer(0, "_SpherePositions", atomSphereGPUBuffer); createDistanceFieldCS.SetTexture(0, "_VolumeTexture", _distanceFieldRT); createDistanceFieldCS.Dispatch(0, Mathf.CeilToInt(size / 10.0f), Mathf.CeilToInt(size / 10.0f), Mathf.CeilToInt(size / 10.0f)); atomSphereGPUBuffer.Release(); //**** var flatSize = size * size * size; var voxelGPUBuffer = new ComputeBuffer(flatSize, sizeof(float)); var readVoxelsCS = Resources.Load("Compute Shaders/ReadVoxels") as ComputeShader; readVoxelsCS.SetInt("_VolumeSize", size); readVoxelsCS.SetBuffer(0, "_VoxelBuffer", voxelGPUBuffer); readVoxelsCS.SetTexture(0, "_VolumeTexture", _distanceFieldRT); readVoxelsCS.Dispatch(0, size, size, size); var voxelCPUBuffer = new float[flatSize]; voxelGPUBuffer.GetData(voxelCPUBuffer); var volumeColors = new Color[flatSize]; for (int i = 0; i < flatSize; i++) { volumeColors[i] = new Color(0, 0, 0, voxelCPUBuffer[i]); } var texture3D = new Texture3D(size, size, size, TextureFormat.Alpha8, true); texture3D.SetPixels(volumeColors); texture3D.wrapMode = TextureWrapMode.Clamp; texture3D.anisoLevel = 0; texture3D.Apply(); AssetDatabase.CreateAsset(texture3D, path); AssetDatabase.SaveAssets(); // Print the path of the created asset Debug.Log(AssetDatabase.GetAssetPath(texture3D)); voxelGPUBuffer.Release(); _distanceFieldRT.Release(); DestroyImmediate(_distanceFieldRT); _volumeTexture = texture3D; } }
void Start() { ComputeBuffer buffer = new ComputeBuffer (4 * 4 * 2 * 2, sizeof(int)); int kernel = shader.FindKernel ("CSMain2"); shader.SetBuffer (kernel, "buffer2", buffer); shader.Dispatch (kernel, 2, 2, 1); int[] data = new int[4 * 4 * 2 * 2]; buffer.GetData (data); for(int i = 0; i < 8; i++) { string line = ""; for(int j = 0; j < 8; j++) { line += " " + data[j+i*8]; } Debug.Log (line); } buffer.Release (); }
static public int Release(IntPtr l) { try { #if DEBUG var method = System.Reflection.MethodBase.GetCurrentMethod(); string methodName = GetMethodName(method); #if UNITY_5_5_OR_NEWER UnityEngine.Profiling.Profiler.BeginSample(methodName); #else Profiler.BeginSample(methodName); #endif #endif UnityEngine.ComputeBuffer self = (UnityEngine.ComputeBuffer)checkSelf(l); self.Release(); pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } #if DEBUG finally { #if UNITY_5_5_OR_NEWER UnityEngine.Profiling.Profiler.EndSample(); #else Profiler.EndSample(); #endif } #endif }
/// <summary> /// Uses the GPU to generate a RenderTexture where the pixels in the texture represent noise. /// Set the octaves variable before calling this to a desired value. /// </summary> /// <returns>RenderTexture</returns> /// <param name="width"> Width of the texture to generate. </param> /// <param name="height"> Height of the texture to generate. </param> /// <param name="noiseOffsetX"> X Coordinate of the offset for the noise on the texture. </param> /// <param name="noiseOffsetY"> Y Coordinate of the offset for the noise on the texture. </param> /// <param name="noiseScale"> Value to scale the noise coordinates by. </param> /// <param name="normalize"> Whether or not to remap the noise from (-1, 1) to (0, 1). </param> public static UnityEngine.RenderTexture GetNoiseRenderTexture(int width, int height, float noiseOffsetX = 0, float noiseOffsetY = 0, float noiseScale = 0.01f, bool normalize = true) { UnityEngine.RenderTexture retTex = new UnityEngine.RenderTexture(width, height, 0); retTex.enableRandomWrite = true; retTex.Create(); UnityEngine.ComputeShader shader = UnityEngine.Resources.Load(shaderPath) as UnityEngine.ComputeShader; if (shader == null) { UnityEngine.Debug.LogError(noShaderMsg); return(null); } int[] resInts = { width, height }; int kernel = shader.FindKernel("ComputeNoise"); shader.SetTexture(kernel, "Result", retTex); SetShaderVars(shader, new UnityEngine.Vector2(noiseOffsetX, noiseOffsetY), normalize, noiseScale); shader.SetInts("reses", resInts); UnityEngine.ComputeBuffer permBuffer = new UnityEngine.ComputeBuffer(perm.Length, 4); permBuffer.SetData(perm); shader.SetBuffer(kernel, "perm", permBuffer); shader.Dispatch(kernel, width / 14, height / 15, 1); permBuffer.Release(); return(retTex); }
static public int Release(IntPtr l) { try{ UnityEngine.ComputeBuffer self = (UnityEngine.ComputeBuffer)checkSelf(l); self.Release(); return(0); } catch (Exception e) { LuaDLL.luaL_error(l, e.ToString()); return(0); } }
public static List<Vector4> GetClusters(List<Vector4> atoms, int numCentroids) { if (ComputeShaderManager.Instance.KMeansCS == null) throw new Exception("KMeans compute shader not assigned"); if (numCentroids <= 0) throw new Exception("Num centroids too low"); var centroids = new List<Vector4>(); var centroidStep = Mathf.CeilToInt(atoms.Count / (float)numCentroids); for (int i = 0; i < numCentroids; i++) { if (i*centroidStep < atoms.Count) { centroids.Add(atoms[i * centroidStep]); } else { centroids.Add(atoms[UnityEngine.Random.Range(0, atoms.Count)]); } } var centroidBuffer = new ComputeBuffer(numCentroids, 4 * sizeof(float)); centroidBuffer.SetData(centroids.ToArray()); var pointBuffer = new ComputeBuffer(atoms.Count, 4 * sizeof(float)); pointBuffer.SetData(atoms.ToArray()); var membershipBuffer = new ComputeBuffer(atoms.Count, sizeof(int)); ComputeShaderManager.Instance.KMeansCS.SetInt("_NumPoints", atoms.Count); ComputeShaderManager.Instance.KMeansCS.SetInt("_NumCentroids", numCentroids); for (int i = 0; i < 5; i++) { ComputeShaderManager.Instance.KMeansCS.SetBuffer(0, "_PointBuffer", pointBuffer); ComputeShaderManager.Instance.KMeansCS.SetBuffer(0, "_CentroidBuffer", centroidBuffer); ComputeShaderManager.Instance.KMeansCS.SetBuffer(0, "_MembershipBuffer", membershipBuffer); ComputeShaderManager.Instance.KMeansCS.Dispatch(0, Mathf.CeilToInt(atoms.Count / 1), 1, 1); ComputeShaderManager.Instance.KMeansCS.SetBuffer(1, "_PointBuffer", pointBuffer); ComputeShaderManager.Instance.KMeansCS.SetBuffer(1, "_NewCentroidBuffer", centroidBuffer); ComputeShaderManager.Instance.KMeansCS.SetBuffer(1, "_NewMembershipBuffer", membershipBuffer); ComputeShaderManager.Instance.KMeansCS.Dispatch(1, Mathf.CeilToInt(numCentroids / 64.0f), 1, 1); } var newCentroids = new Vector4[numCentroids]; centroidBuffer.GetData(newCentroids); pointBuffer.Release(); centroidBuffer.Release(); membershipBuffer.Release(); return newCentroids.ToList(); }
static public int Release(IntPtr l) { try { UnityEngine.ComputeBuffer self = (UnityEngine.ComputeBuffer)checkSelf(l); self.Release(); pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
// Use this for initialization void Start () { ComputeBuffer buffer = new ComputeBuffer(4,sizeof(int)); shader.SetBuffer(0, "buffer1", buffer); shader.Dispatch(0, 1, 1, 1); int[] data = new int[4]; buffer.GetData(data); for(int i = 0; i < 4; i++) { buffer.Release(); } }
/// <summary> /// Uses the GPU to process an array of 4D coordinates for noise and return an array with the noise at the specified coordinates. /// </summary> /// <returns>Float array</returns> /// <param name="positions"> Array of coordinates to process. </param> /// <param name="noiseScale"> Value to scale the noise coordinates by. </param> /// <param name="normalize"> Whether or not to remap the noise from (-1, 1) to (0, 1). </param> public static float[] NoiseArrayGPU(UnityEngine.Vector4[] positions, float noiseScale = 0.01f, bool normalize = true) { UnityEngine.ComputeShader shader = UnityEngine.Resources.Load(shaderPath) as UnityEngine.ComputeShader; if (shader == null) { UnityEngine.Debug.LogError(noShaderMsg); return(null); } int kernel = shader.FindKernel("ComputeNoiseArray"); SetShaderVars(shader, UnityEngine.Vector2.zero, normalize, noiseScale); shader.SetInt("dimension", 4); UnityEngine.ComputeBuffer permBuffer = new UnityEngine.ComputeBuffer(perm.Length, 4); permBuffer.SetData(perm); shader.SetBuffer(kernel, "perm", permBuffer); UnityEngine.ComputeBuffer posBuffer = new UnityEngine.ComputeBuffer(positions.Length, 16); posBuffer.SetData(positions); shader.SetBuffer(kernel, "float4Array", posBuffer); UnityEngine.ComputeBuffer outputBuffer = new UnityEngine.ComputeBuffer(positions.Length, 4); shader.SetBuffer(kernel, "outputArray", outputBuffer); shader.Dispatch(kernel, positions.Length / 14, 1, 1); float[] outputData = new float[positions.Length]; outputBuffer.GetData(outputData); permBuffer.Release(); posBuffer.Release(); outputBuffer.Release(); return(outputData); }
public void BuildMesh() { float startTime = Time.realtimeSinceStartup; // NOISE VOLUME! RenderTexture DensityVolume = new RenderTexture(16, 16, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.sRGB); DensityVolume.volumeDepth = 16; DensityVolume.isVolume = true; DensityVolume.enableRandomWrite = true; DensityVolume.filterMode = FilterMode.Bilinear; DensityVolume.wrapMode = TextureWrapMode.Repeat; DensityVolume.Create(); int mgen_id = CShaderSimplex.FindKernel("FillEmpty"); // uses renderTexture rather than StructuredBuffer? CShaderSimplex.SetTexture(mgen_id, "Result", DensityVolume); // Links RenderTexture to the "Result" RWTexture in the compute shader? CShaderSimplex.Dispatch(mgen_id, 1, 1, 16); // run computeShader "FillEmpty" with 1 x 1 x 31 threadGroups? mgen_id = CShaderSimplex.FindKernel("Simplex3d"); CShaderSimplex.SetTexture(mgen_id, "Result", DensityVolume); CShaderSimplex.Dispatch(mgen_id, 1, 1, 16); // Fill shared RenderTexture with GPU simplex Noise ComputeBuffer cBufferSegmentTransform = new ComputeBuffer(critterSegmentTransforms.Length, sizeof(float) * (3 + 3 + 4)); cBufferSegmentTransform.SetData(critterSegmentTransforms); int kernelID = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetBuffer(kernelID, "segmentTransformBuffer", cBufferSegmentTransform); CShaderBuildMC.SetTexture(kernelID, "noise_volume", DensityVolume); // Noise 3D texture //Debug.Log(DensityVolume.colorBuffer.ToString()); // Figure out how many chunks are needed: int numChunksX = Mathf.CeilToInt(GlobalBoundingBoxDimensions.x / (cellResolution * 8f)); int numChunksY = Mathf.CeilToInt(GlobalBoundingBoxDimensions.y / (cellResolution * 8f)); int numChunksZ = Mathf.CeilToInt(GlobalBoundingBoxDimensions.z / (cellResolution * 8f)); //Debug.Log("numChunks: (" + numChunksX.ToString() + ", " + numChunksY.ToString() + ", " + numChunksZ.ToString() + ")"); int totalNumChunks = numChunksX * numChunksY * numChunksZ; Poly[][] PolyArrayArray = new Poly[totalNumChunks][]; // This will hold the mesh data from the chunks calculated on the GPU int[] numPolysArray = new int[totalNumChunks]; int totalNumPolys = 0; // Get each chunk! int chunkIndex = 0; for(int x = 0; x < numChunksX; x++) { for(int y = 0; y < numChunksY; y++) { for(int z = 0; z < numChunksZ; z++) { // Figure out chunk offset amount: Vector3 chunkOffset = new Vector3(cellResolution * 8f * x, cellResolution * 8f * y, cellResolution * 8f * z) + GlobalBoundingBoxOffset - (GlobalBoundingBoxDimensions / 2f); int[] numPolys = new int[1]; ComputeBuffer cBufferNumPoly = new ComputeBuffer(1, sizeof(int)); cBufferNumPoly.SetData(numPolys); int id = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetInt("_CalcNumPolys", 1); // only calculate how many tris so I can correctly size the poly buffer CShaderBuildMC.SetFloat("_GlobalOffsetX", chunkOffset.x); CShaderBuildMC.SetFloat("_GlobalOffsetY", chunkOffset.y); CShaderBuildMC.SetFloat("_GlobalOffsetZ", chunkOffset.z); CShaderBuildMC.SetFloat("_CellSize", cellResolution); CShaderBuildMC.SetVector("_ColorPrimary", colorPrimary); CShaderBuildMC.SetVector("_ColorSecondary", colorSecondary); CShaderBuildMC.SetFloat("_ColorNoiseScale", colorNoiseScale); CShaderBuildMC.SetFloat("_ColorSmlAmplitude", colorSmlAmplitude); CShaderBuildMC.SetFloat("_ColorMedAmplitude", colorMedAmplitude); CShaderBuildMC.SetFloat("_ColorLrgAmplitude", colorLrgAmplitude); CShaderBuildMC.SetFloat("_ColorContrast", colorContrast); CShaderBuildMC.SetFloat("_ColorThreshold", colorThreshold); CShaderBuildMC.SetVector("_SkinNoiseScale", skinNoiseScale); CShaderBuildMC.SetFloat("_SkinNoiseAmplitude", skinNoiseAmplitude); CShaderBuildMC.SetVector("_SkinLocalTaper", skinLocalTaper); CShaderBuildMC.SetVector("_SkinLocalSinFreq", skinLocalSinFreq); CShaderBuildMC.SetVector("_SkinLocalSinAmp", skinLocalSinAmp); // Local Segment-space modifications, sin, taper, etc. CShaderBuildMC.SetBuffer(id, "numPolyBuffer", cBufferNumPoly); CShaderBuildMC.Dispatch(id, 1, 1, 1); // calc num polys cBufferNumPoly.GetData(numPolys); // get numPolys //Debug.Log("Chunk: " + (z + (numChunksZ * y) + (numChunksZ * numChunksY * x)).ToString() + ", cBufferNumPoly.GetData(numPolys): " + numPolys[0].ToString() + ", chunkOffset: " + chunkOffset.ToString()); totalNumPolys += numPolys[0]; numPolysArray[chunkIndex] = numPolys[0]; if(numPolys[0] > 0) { // only do this if there was at least 1 triangle in the test pass Poly[] polyArray = new Poly[numPolys[0]]; int cBufferStride = sizeof(float) * (18 + 9 + 6) + sizeof(int) * (6); ComputeBuffer cBuffer = new ComputeBuffer(numPolys[0], cBufferStride); // 18 floats x 4 bytes/float = 72 + COLORS! 9 x 4 = 36 = 108 + BONES! 6x4 = 24 + 6 xint... cBuffer.SetData(polyArray); CShaderBuildMC.SetBuffer(id, "buffer", cBuffer); CShaderBuildMC.SetInt("_CalcNumPolys", 0); // Actually calc tris CShaderBuildMC.Dispatch(id, 1, 1, 1); cBuffer.GetData(polyArray); // return data from GPU PolyArrayArray[chunkIndex] = polyArray; cBuffer.Dispose(); } cBufferNumPoly.Dispose(); chunkIndex++; } } } CritterDecorationsTest.decorationStruct[] points = new CritterDecorationsTest.decorationStruct[totalNumPolys]; //Construct mesh using received data int vindex = 0; int decindex = 0; // Why same number of tris as vertices? == // because all triangles have duplicate verts - no shared vertices? Vector3[] vertices = new Vector3[totalNumPolys * 3]; Color[] colors = new Color[totalNumPolys * 3]; int[] tris = new int[totalNumPolys * 3]; Vector2[] uvs = new Vector2[totalNumPolys * 3]; Vector3[] normals = new Vector3[totalNumPolys * 3]; BoneWeight[] weights = new BoneWeight[totalNumPolys * 3]; //Parse triangles for(int i = 0; i < PolyArrayArray.Length; i++) { if(numPolysArray[i] > 0) { // only do this if there was at least 1 triangle in the test pass for (int ix = 0; ix < numPolysArray[i]; ix++) { Vector3 vPos; Vector3 vOffset = new Vector3(0, 0, 0); //??? offsets all vertices by this amount, but why 30?? //A1,A2,A3 vPos = new Vector3(PolyArrayArray[i][ix].A1, PolyArrayArray[i][ix].A2, PolyArrayArray[i][ix].A3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NA1, PolyArrayArray[i][ix].NA2, PolyArrayArray[i][ix].NA3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); colors[vindex] = new Color(PolyArrayArray[i][ix].CAR, PolyArrayArray[i][ix].CAG, PolyArrayArray[i][ix].CAB, 1.0f); weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexA0; weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexA1; weights[vindex].weight0 = PolyArrayArray[i][ix].BoneWeightA0; weights[vindex].weight1 = PolyArrayArray[i][ix].BoneWeightA1; points[decindex].pos = vPos; points[decindex].normal = normals[vindex]; points[decindex].color = new Vector3(colors[vindex].r, colors[vindex].g, colors[vindex].b); decindex++; vindex++; //B1,B2,B3 vPos = new Vector3(PolyArrayArray[i][ix].B1, PolyArrayArray[i][ix].B2, PolyArrayArray[i][ix].B3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NB1, PolyArrayArray[i][ix].NB2, PolyArrayArray[i][ix].NB3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); colors[vindex] = new Color(PolyArrayArray[i][ix].CBR, PolyArrayArray[i][ix].CBG, PolyArrayArray[i][ix].CBB, 1.0f); weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexB0; weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexB1; weights[vindex].weight0 = PolyArrayArray[i][ix].BoneWeightB0; weights[vindex].weight1 = PolyArrayArray[i][ix].BoneWeightB1; vindex++; //C1,C2,C3 vPos = new Vector3(PolyArrayArray[i][ix].C1, PolyArrayArray[i][ix].C2, PolyArrayArray[i][ix].C3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NC1, PolyArrayArray[i][ix].NC2, PolyArrayArray[i][ix].NC3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); colors[vindex] = new Color(PolyArrayArray[i][ix].CCR, PolyArrayArray[i][ix].CCG, PolyArrayArray[i][ix].CCB, 1.0f); weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexC0; weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexC1; weights[vindex].weight0 = PolyArrayArray[i][ix].BoneWeightC0; weights[vindex].weight1 = PolyArrayArray[i][ix].BoneWeightC1; vindex++; } } } //We have got all data and are ready to setup a new mesh! Mesh newMesh = new Mesh(); newMesh.vertices = vertices; newMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh); newMesh.triangles = tris; newMesh.normals = normals; //NewMesh.RecalculateNormals(); newMesh.colors = colors; newMesh.Optimize(); // Set up SKINNING!!!: Transform[] bones = new Transform[critter.critterSegmentList.Count]; Matrix4x4[] bindPoses = new Matrix4x4[critter.critterSegmentList.Count]; // Try just using existing critter's GameObjects/Transforms: for(int seg = 0; seg < critter.critterSegmentList.Count; seg++) { bones[seg] = critter.critterSegmentList[seg].transform; bindPoses[seg] = bones[seg].worldToLocalMatrix * transform.localToWorldMatrix; // ????????????????? // the bind pose is the inverse of inverse transformation matrix of the bone, when the bone is in the bind pose .... unhelpful .... } newMesh.boneWeights = weights; newMesh.bindposes = bindPoses; SkinnedMeshRenderer skinnedMeshRenderer = this.GetComponent<SkinnedMeshRenderer>(); skinnedMeshRenderer.bones = bones; skinnedMeshRenderer.sharedMesh = newMesh; skinnedMeshRenderer.enabled = true; cBufferSegmentTransform.Release(); critterDecorationsTest.TurnOn(points); float calcTime = Time.realtimeSinceStartup - startTime; Debug.Log("MeshCreated! " + calcTime.ToString()); }
int RunGPUBenchmark(string text) { if (!SystemInfo.supportsComputeShaders) { m_output.text = m_output.text + text + "not available\n"; return 0; } ComputeBuffer cb_params = new ComputeBuffer(1, CSParams.size); ComputeBuffer cb_particles = new ComputeBuffer(BenchmarkParticleCount, peParticle.size); var particles = new peParticle[BenchmarkParticleCount]; { UnityEngine.Random.seed = 0; for (int i = 0; i < particles.Length; ++i) { particles[i].position = new Vector3( UnityEngine.Random.Range(-5.0f, 5.0f), UnityEngine.Random.Range(-5.0f, 5.0f) + 5.0f, UnityEngine.Random.Range(-5.0f, 5.0f) ); } cb_particles.SetData(particles); } { CSParams[] csparams = new CSParams[1]; csparams[0].particle_count = BenchmarkParticleCount; csparams[0].particle_size = m_particle_size; csparams[0].rcp_particle_size2 = 1.0f / (m_particle_size * 2.0f); csparams[0].pressure_stiffness = m_pressure_stiffness; csparams[0].wall_stiffness = m_wall_stiffness; csparams[0].timestep = BenchmarkDeltaTime; cb_params.SetData(csparams); } for (int i = 0; i < 2; ++i ) { m_cs_particle_core.SetBuffer(i, "g_params", cb_params); m_cs_particle_core.SetBuffer(i, "g_particles", cb_particles); } float elapsed_total = 0.0f; int num_try = 0; while (elapsed_total < BenchmarkTimeout) { float t = Time.realtimeSinceStartup; m_cs_particle_core.Dispatch(0, BenchmarkParticleCount / KernelBlockSize, 1, 1); m_cs_particle_core.Dispatch(1, BenchmarkParticleCount / KernelBlockSize, 1, 1); cb_particles.GetData(particles); elapsed_total += Time.realtimeSinceStartup - t; ++num_try; } cb_params.Release(); cb_particles.Release(); m_output.text = m_output.text + text + (elapsed_total / num_try * 1000.0f).ToString("0.00") + "ms\n"; return 0; }
public static int ReadPixelId(RenderTexture texture, Vector2 coord) { var outBuffer = new ComputeBuffer(1, sizeof(int)); ComputeShaderManager.Instance.ReadPixelCS.SetInts("_Coord", (int)coord.x, Screen.height - (int)coord.y); ComputeShaderManager.Instance.ReadPixelCS.SetTexture(0, "_IdTexture", texture); ComputeShaderManager.Instance.ReadPixelCS.SetBuffer(0, "_OutputBuffer", outBuffer); ComputeShaderManager.Instance.ReadPixelCS.Dispatch(0, 1, 1, 1); var pixelId = new[] { 0 }; outBuffer.GetData(pixelId); outBuffer.Release(); return pixelId[0]; }
void Start () { m_skyMap = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBHalf); m_skyMap.filterMode = FilterMode.Trilinear; m_skyMap.wrapMode = TextureWrapMode.Clamp; m_skyMap.anisoLevel = 9; m_skyMap.useMipMap = true; m_skyMap.Create(); //Transmittance is responsible for the change in the sun color as it moves //The raw file is a 2D array of 32 bit floats with a range of 0 to 1 string path = Application.dataPath + "/Textures/transmittance.raw"; m_transmittance = new RenderTexture(TRANSMITTANCE_WIDTH, TRANSMITTANCE_HEIGHT, 0, RenderTextureFormat.ARGBHalf); m_transmittance.wrapMode = TextureWrapMode.Clamp; m_transmittance.filterMode = FilterMode.Bilinear; m_transmittance.enableRandomWrite = true; m_transmittance.Create(); ComputeBuffer buffer = new ComputeBuffer(TRANSMITTANCE_WIDTH*TRANSMITTANCE_HEIGHT, sizeof(float)*TRANSMITTANCE_CHANNELS); CBUtility.WriteIntoRenderTexture(m_transmittance, TRANSMITTANCE_CHANNELS, path, buffer, m_writeData); buffer.Release(); //Iirradiance is responsible for the change in the sky color as the sun moves //The raw file is a 2D array of 32 bit floats with a range of 0 to 1 path = Application.dataPath + "/Textures/irradiance.raw"; m_irradiance = new RenderTexture(IRRADIANCE_WIDTH, IRRADIANCE_HEIGHT, 0, RenderTextureFormat.ARGBHalf); m_irradiance.wrapMode = TextureWrapMode.Clamp; m_irradiance.filterMode = FilterMode.Bilinear; m_irradiance.enableRandomWrite = true; m_irradiance.Create(); buffer = new ComputeBuffer(IRRADIANCE_WIDTH*IRRADIANCE_HEIGHT, sizeof(float)*IRRADIANCE_CHANNELS); CBUtility.WriteIntoRenderTexture(m_irradiance, IRRADIANCE_CHANNELS, path, buffer, m_writeData); buffer.Release(); //Inscatter is responsible for the change in the sky color as the sun moves //The raw file is a 4D array of 32 bit floats with a range of 0 to 1.589844 //As there is not such thing as a 4D texture the data is packed into a 3D texture //and the shader manually performs the sample for the 4th dimension path = Application.dataPath + "/Textures/inscatter.raw"; m_inscatter = new RenderTexture(INSCATTER_WIDTH, INSCATTER_HEIGHT, 0, RenderTextureFormat.ARGBHalf); m_inscatter.volumeDepth = INSCATTER_DEPTH; m_inscatter.wrapMode = TextureWrapMode.Clamp; m_inscatter.filterMode = FilterMode.Bilinear; m_inscatter.isVolume = true; m_inscatter.enableRandomWrite = true; m_inscatter.Create(); buffer = new ComputeBuffer(INSCATTER_WIDTH*INSCATTER_HEIGHT*INSCATTER_DEPTH, sizeof(float)*INSCATTER_CHANNELS); CBUtility.WriteIntoRenderTexture(m_inscatter, INSCATTER_CHANNELS, path, buffer, m_writeData); buffer.Release(); InitMaterial(m_skyMapMaterial); InitMaterial(m_skyMaterial); InitMaterial(m_oceanMaterial); //ocean mat needs some of these uniforms so may as well set them here }
private void InitTerrain() { int meshGridSize = 16; int numTerrainMeshVertices = meshGridSize * meshGridSize; terrainMeshBuffer = new ComputeBuffer(numTerrainMeshVertices, sizeof(float) * (3 + 3 + 2 + 4)); int numStrokesPerVertX = 16; int numStrokesPerVertZ = 16; int numTerrainStrokes = meshGridSize * meshGridSize * numStrokesPerVertX * numStrokesPerVertZ; terrainStrokesBuffer = new ComputeBuffer(numTerrainStrokes, sizeof(float) * (3 + 3 + 3 + 3 + 3 + 2) + sizeof(int) * 1); //terrainGeneratorCompute = new ComputeShader(); int kernel_id = terrainGeneratorCompute.FindKernel("CSMain"); terrainGeneratorCompute.SetFloat("_GridSideLength", terrainSize); terrainGeneratorCompute.SetFloat("_NoiseFrequency", terrainNoiseFrequency); terrainGeneratorCompute.SetFloat("_NoiseAmplitude", terrainNoiseAmplitude); terrainGeneratorCompute.SetFloat("_GroundHeight", terrainAltitude); terrainGeneratorCompute.SetInt("_NumGroupsX", numStrokesPerVertX); terrainGeneratorCompute.SetInt("_NumGroupsZ", numStrokesPerVertZ); terrainGeneratorCompute.SetBuffer(kernel_id, "buf_StrokeData", terrainStrokesBuffer); terrainGeneratorCompute.SetBuffer(kernel_id, "buf_MeshData", terrainMeshBuffer); meshData[] meshDataArray = new meshData[numTerrainMeshVertices]; // memory to receive data from computeshader terrainGeneratorCompute.Dispatch(kernel_id, numStrokesPerVertX, 1, numStrokesPerVertZ); // fill buffers terrainMeshBuffer.GetData(meshDataArray); // download mesh Data // generate Mesh from data: //Construct mesh using received data // Why same number of tris as vertices? == // because all triangles have duplicate verts - no shared vertices? Vector3[] vertices = new Vector3[numTerrainMeshVertices]; Color[] colors = new Color[numTerrainMeshVertices]; int[] tris = new int[2 * (meshGridSize - 1) * (meshGridSize - 1) * 3]; Vector2[] uvs = new Vector2[numTerrainMeshVertices]; Vector3[] normals = new Vector3[numTerrainMeshVertices]; for(int i = 0; i < numTerrainMeshVertices; i++) { vertices[i] = meshDataArray[i].pos; normals[i] = meshDataArray[i].normal; uvs[i] = meshDataArray[i].uv; colors[i] = meshDataArray[i].color; } // Figure out triangles: int index = 0; int numSquares = meshGridSize - 1; for (int y = 0; y < numSquares; y++) { for(int x = 0; x < numSquares; x++) { // counterclockwise winding order: tris[index] = ((y + 1) * meshGridSize) + x; tris[index + 1] = (y * meshGridSize) + x + 1; tris[index + 2] = (y * meshGridSize) + x; tris[index + 3] = ((y + 1) * meshGridSize) + x; tris[index + 4] = ((y + 1) * meshGridSize) + x + 1; tris[index + 5] = (y * meshGridSize) + x + 1; index = index + 6; } } Mesh terrainMesh = new Mesh(); terrainMesh.vertices = vertices; terrainMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh); terrainMesh.triangles = tris; terrainMesh.normals = normals; //NewMesh.RecalculateNormals(); terrainMesh.colors = colors; terrainMesh.RecalculateNormals(); terrainMesh.RecalculateBounds(); trainerTerrainManager.GetComponent<MeshFilter>().sharedMesh = terrainMesh; trainerTerrainManager.GetComponent<MeshCollider>().sharedMesh = terrainMesh; terrainMeshBuffer.Release(); terrainMeshBuffer.Dispose(); }
///<summary> /// Input a cubemap, and then prefilter this cubemap for image-based lighting equation. ///</summary> public static void PreFilterEnviromentMap(Cubemap cubemap) { if (cubemap) { int cube_width = cubemap.width; Vector3 vec3 = new Vector3(); // Create a read buffer to store cubemap direction data. ComputeBuffer cubeMatrix = new ComputeBuffer(sgFaceInput.Length, Marshal.SizeOf(vec3)); cubeMatrix.SetData(sgFaceInput); Vector4 vec4 = new Vector4(); // Create a output buffer. ComputeBuffer dstData = new ComputeBuffer(cube_width * cube_width * 6, Marshal.SizeOf(vec4)); ComputeShader CSEnvFilter; CSEnvFilter = (ComputeShader)AssetDatabase.LoadAssetAtPath("Assets/EnvironmentMapTool/ComputeShader/FilterCubeMap.compute", typeof(ComputeShader)); // Set cubemap to shader. CSEnvFilter.SetTexture(0, "gCubemap", cubemap); // Set read write buffer for data output. CSEnvFilter.SetBuffer(0, "gOutput", dstData); // Set cubemap direction data. CSEnvFilter.SetBuffer(0, "sgFace2DMapping", cubeMatrix); Color[] outputData = new Color[cube_width * cube_width * 6]; // How many mipmap level? float mipLevelNum = Mathf.Log(cube_width, 2); // Loop each mipmap level with different roughness. for (int i = 0; i < mipLevelNum + 1; i++) { // The texel number of a face. int image_size = cube_width * cube_width; // The texel number of a cubemap. int num_threads = image_size * 6; // Set roughness value (between 0~1). CSEnvFilter.SetFloat("gRoughness", (i / mipLevelNum)); // The width of a mipmap level of a cube map. CSEnvFilter.SetInt("gWidth", cube_width); // The total number of thread groups (the number of my thread group : 64). num_threads = (int)Mathf.Ceil((float)num_threads / 64.0f); // Run compute shader. CSEnvFilter.Dispatch(0, num_threads, 1, 1); // Get data from the read & write buffer. dstData.GetData(outputData); // Copy data to the original cubemap. SetCubeMipMap(cubemap, outputData, image_size, i); // Half the size for the next mipmap level. cube_width = cube_width / 2; } // Set false to disable auto-generating mipmap. cubemap.Apply(false); // Use trilinear mode to interpolate different mipmap levels. cubemap.filterMode = FilterMode.Trilinear; cubemap.wrapMode = TextureWrapMode.Clamp; cubemap.name = cubemap.name + "(PreFilter)"; // Release data. dstData.Release(); cubeMatrix.Release(); } }
void SaveAsRaw(int size, int channels, string fileName, RenderTexture rtex) { ComputeBuffer buffer = new ComputeBuffer(size, sizeof(float)*channels); CBUtility.ReadFromRenderTexture(rtex, channels, buffer, m_readData); float[] data = new float[size * channels]; buffer.GetData(data); byte[] byteArray = new byte[size * 4 * channels]; System.Buffer.BlockCopy(data, 0, byteArray, 0, byteArray.Length); System.IO.File.WriteAllBytes(Application.dataPath + m_filePath + fileName + ".raw", byteArray); buffer.Release(); }
void SaveAs8bit(int width, int height, int channels, string fileName, RenderTexture rtex, float scale = 1.0f) { //Only used to get a visible image for debugging. ComputeBuffer buffer = new ComputeBuffer(width*height, sizeof(float)*channels); CBUtility.ReadFromRenderTexture(rtex, channels, buffer, m_readData); float[] data = new float[width*height* channels]; buffer.GetData(data); Texture2D tex = new Texture2D(width, height); for(int x = 0; x < width; x++) { for(int y = 0; y < height; y++) { Color col = new Color(0,0,0,1); col.r = data[(x + y * width) * channels + 0]; if(channels > 1) col.g = data[(x + y * width) * channels + 1]; if(channels > 2) col.b = data[(x + y * width) * channels + 2]; tex.SetPixel(x, y, col * scale); } } tex.Apply(); byte[] bytes = tex.EncodeToPNG(); System.IO.File.WriteAllBytes(Application.dataPath + m_filePath + fileName + ".png", bytes); buffer.Release(); }
public void BuildMesh() { float startTime = Time.realtimeSinceStartup; // CritterSegmentTransforms!! SegmentTransform[] critterSegmentTransforms = new SegmentTransform[2]; Quaternion rot = Quaternion.Euler(55f, 12f, -230f); Quaternion rot2 = Quaternion.Euler(-35f, 112f, -67f); SegmentTransform segmentTransform; segmentTransform.PX = 10f; segmentTransform.PY = 8f; segmentTransform.PZ = 13f; segmentTransform.RX = rot.x; segmentTransform.RY = rot.y; segmentTransform.RZ = rot.z; segmentTransform.RW = rot.w; segmentTransform.SX = 6f; segmentTransform.SY = 7f; segmentTransform.SZ = 2.5f; SegmentTransform segmentTransform2; segmentTransform2.PX = 22f; segmentTransform2.PY = 11f; segmentTransform2.PZ = 15f; segmentTransform2.RX = rot2.x; segmentTransform2.RY = rot2.y; segmentTransform2.RZ = rot2.z; segmentTransform2.RW = rot2.w; segmentTransform2.SX = 9f; segmentTransform2.SY = 3f; segmentTransform2.SZ = 7f; critterSegmentTransforms[0] = segmentTransform; critterSegmentTransforms[1] = segmentTransform2; ComputeBuffer cBufferSegmentTransform = new ComputeBuffer(critterSegmentTransforms.Length, sizeof(float) * (3 + 3 + 4)); cBufferSegmentTransform.SetData(critterSegmentTransforms); int kernelID = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetBuffer(kernelID, "segmentTransformBuffer", cBufferSegmentTransform); // Figure out how many chunks are needed: int numChunksX = Mathf.CeilToInt(GlobalBoundingBoxDimensions.x * cellResolution / 8f); int numChunksY = Mathf.CeilToInt(GlobalBoundingBoxDimensions.y * cellResolution / 8f); int numChunksZ = Mathf.CeilToInt(GlobalBoundingBoxDimensions.z * cellResolution / 8f); Debug.Log("numChunks: (" + numChunksX.ToString() + ", " + numChunksY.ToString() + ", " + numChunksZ.ToString() + ")"); int totalNumChunks = numChunksX * numChunksY * numChunksZ; Poly[][] PolyArrayArray = new Poly[totalNumChunks][]; // This will hold the mesh data from the chunks calculated on the GPU int[] numPolysArray = new int[totalNumChunks]; int totalNumPolys = 0; // Get each chunk! int chunkIndex = 0; for(int x = 0; x < numChunksX; x++) { for(int y = 0; y < numChunksY; y++) { for(int z = 0; z < numChunksZ; z++) { // Figure out chunk offset amount: Vector3 chunkOffset = new Vector3(cellResolution * 8f * x, cellResolution * 8f * y, cellResolution * 8f * z); int[] numPolys = new int[1]; ComputeBuffer cBufferNumPoly = new ComputeBuffer(1, sizeof(int)); cBufferNumPoly.SetData(numPolys); int id = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetInt("_CalcNumPolys", 1); // only calculate how many tris so I can correctly size the poly buffer CShaderBuildMC.SetFloat("_GlobalOffsetX", chunkOffset.x); CShaderBuildMC.SetFloat("_GlobalOffsetY", chunkOffset.y); CShaderBuildMC.SetFloat("_GlobalOffsetZ", chunkOffset.z); CShaderBuildMC.SetBuffer(id, "numPolyBuffer", cBufferNumPoly); CShaderBuildMC.Dispatch(id, 1, 1, 1); // calc num polys cBufferNumPoly.GetData(numPolys); // get numPolys Debug.Log("Chunk: " + (z + (numChunksZ * y) + (numChunksZ * numChunksY * x)).ToString() + ", cBufferNumPoly.GetData(numPolys): " + numPolys[0].ToString() + ", chunkIndex: " + chunkIndex.ToString()); totalNumPolys += numPolys[0]; numPolysArray[chunkIndex] = numPolys[0]; //_MaxBufferSize = numPolys[0]; if(numPolys[0] > 0) { // only do this if there was at least 1 triangle in the test pass Poly[] polyArray = new Poly[numPolys[0]]; ComputeBuffer cBuffer = new ComputeBuffer(numPolys[0], 72); // 18 floats x 4 bytes/float = 72 cBuffer.SetData(polyArray); CShaderBuildMC.SetBuffer(id, "buffer", cBuffer); CShaderBuildMC.SetInt("_CalcNumPolys", 0); // Actually calc tris CShaderBuildMC.Dispatch(id, 1, 1, 1); cBuffer.GetData(polyArray); // return data from GPU PolyArrayArray[chunkIndex] = polyArray; cBuffer.Dispose(); } cBufferNumPoly.Dispose(); chunkIndex++; } } } //Construct mesh using received data Mesh newMesh = new Mesh(); int vindex = 0; // Why same number of tris as vertices? == // because all triangles have duplicate verts - no shared vertices? Vector3[] vertices = new Vector3[totalNumPolys * 3]; int[] tris = new int[totalNumPolys * 3]; Vector2[] uvs = new Vector2[totalNumPolys * 3]; Vector3[] normals = new Vector3[totalNumPolys * 3]; //Parse triangles for(int i = 0; i < PolyArrayArray.Length; i++) { if(numPolysArray[i] > 0) { // only do this if there was at least 1 triangle in the test pass for (int ix = 0; ix < numPolysArray[i]; ix++) { Vector3 vPos; Vector3 vOffset = new Vector3(0, 0, 0); //??? offsets all vertices by this amount, but why 30?? //A1,A2,A3 vPos = new Vector3(PolyArrayArray[i][ix].A1, PolyArrayArray[i][ix].A2, PolyArrayArray[i][ix].A3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NA1, PolyArrayArray[i][ix].NA2, PolyArrayArray[i][ix].NA3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; //B1,B2,B3 vPos = new Vector3(PolyArrayArray[i][ix].B1, PolyArrayArray[i][ix].B2, PolyArrayArray[i][ix].B3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NB1, PolyArrayArray[i][ix].NB2, PolyArrayArray[i][ix].NB3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; //C1,C2,C3 vPos = new Vector3(PolyArrayArray[i][ix].C1, PolyArrayArray[i][ix].C2, PolyArrayArray[i][ix].C3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NC1, PolyArrayArray[i][ix].NC2, PolyArrayArray[i][ix].NC3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; } } } //We have got all data and are ready to setup a new mesh! //newMesh.Clear(); newMesh.vertices = vertices; newMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh); newMesh.triangles = tris; newMesh.normals = normals; //NewMesh.RecalculateNormals(); newMesh.RecalculateNormals(); newMesh.Optimize(); //cBuffer.Dispose(); //cBufferNumPoly.Dispose(); //cBuffer.Release(); cBufferSegmentTransform.Release(); this.GetComponent<MeshFilter>().sharedMesh = newMesh; float calcTime = Time.realtimeSinceStartup - startTime; Debug.Log("MeshCreated! " + calcTime.ToString()); }
void GenerateWavesSpectrum() { // Slope variance due to all waves, by integrating over the full spectrum. float theoreticSlopeVariance = 0.0f; float k = 5e-3f; while (k < 1e3f) { float nextK = k * 1.001f; theoreticSlopeVariance += k * k * Spectrum(k, 0, true) * (nextK - k); k = nextK; } float[] spectrum01 = new float[m_size*m_size*4]; float[] spectrum23 = new float[m_size*m_size*4]; int idx; float i; float j; float totalSlopeVariance = 0.0f; Vector2 sample12XY; Vector2 sample12ZW; Vector2 sample34XY; Vector2 sample34ZW; Random.seed = 0; for (int x = 0; x < m_size; x++) { for (int y = 0; y < m_size; y++) { idx = x+y*m_size; i = (x >= m_size / 2) ? (float)(x - m_size) : (float)x; j = (y >= m_size / 2) ? (float)(y - m_size) : (float)y; sample12XY = GetSpectrumSample(i, j, m_gridSizes.x, Mathf.PI / m_gridSizes.x); sample12ZW = GetSpectrumSample(i, j, m_gridSizes.y, Mathf.PI * m_fsize / m_gridSizes.x); sample34XY = GetSpectrumSample(i, j, m_gridSizes.z, Mathf.PI * m_fsize / m_gridSizes.y); sample34ZW = GetSpectrumSample(i, j, m_gridSizes.w, Mathf.PI * m_fsize / m_gridSizes.z); spectrum01[idx*4+0] = sample12XY.x; spectrum01[idx*4+1] = sample12XY.y; spectrum01[idx*4+2] = sample12ZW.x; spectrum01[idx*4+3] = sample12ZW.y; spectrum23[idx*4+0] = sample34XY.x; spectrum23[idx*4+1] = sample34XY.y; spectrum23[idx*4+2] = sample34ZW.x; spectrum23[idx*4+3] = sample34ZW.y; i *= 2.0f * Mathf.PI; j *= 2.0f * Mathf.PI; totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.x, j / m_gridSizes.x, sample12XY); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.y, j / m_gridSizes.y, sample12ZW); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.z, j / m_gridSizes.z, sample34XY); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.w, j / m_gridSizes.w, sample34ZW); } } //Write floating point data into render texture ComputeBuffer buffer = new ComputeBuffer(m_size*m_size, sizeof(float)*4); buffer.SetData(spectrum01); CBUtility.WriteIntoRenderTexture(m_spectrum01, 4, buffer, m_writeData); buffer.SetData(spectrum23); CBUtility.WriteIntoRenderTexture(m_spectrum23, 4, buffer, m_writeData); buffer.Release(); m_varianceShader.SetFloat("_SlopeVarianceDelta", 0.5f * (theoreticSlopeVariance - totalSlopeVariance)); m_varianceShader.SetFloat("_VarianceSize", (float)m_varianceSize); m_varianceShader.SetFloat("_Size", m_fsize); m_varianceShader.SetVector("_GridSizes", m_gridSizes); m_varianceShader.SetTexture(0, "_Spectrum01", m_spectrum01); m_varianceShader.SetTexture(0, "_Spectrum23", m_spectrum23); m_varianceShader.SetTexture(0, "des", m_variance); m_varianceShader.Dispatch(0,m_varianceSize/4,m_varianceSize/4,m_varianceSize/4); }
void CreateWTable() { //Some values need for the InitWaveSpectrum function can be precomputed Vector2 uv, st; float k1, k2, k3, k4, w1, w2, w3, w4; float[] table = new float[m_size*m_size*4]; for (int x = 0; x < m_size; x++) { for (int y = 0; y < m_size; y++) { uv = new Vector2(x,y) / m_fsize; st.x = uv.x > 0.5f ? uv.x - 1.0f : uv.x; st.y = uv.y > 0.5f ? uv.y - 1.0f : uv.y; k1 = (st * m_inverseGridSizes.x).magnitude; k2 = (st * m_inverseGridSizes.y).magnitude; k3 = (st * m_inverseGridSizes.z).magnitude; k4 = (st * m_inverseGridSizes.w).magnitude; w1 = Mathf.Sqrt(9.81f * k1 * (1.0f + k1 * k1 / (WAVE_KM*WAVE_KM))); w2 = Mathf.Sqrt(9.81f * k2 * (1.0f + k2 * k2 / (WAVE_KM*WAVE_KM))); w3 = Mathf.Sqrt(9.81f * k3 * (1.0f + k3 * k3 / (WAVE_KM*WAVE_KM))); w4 = Mathf.Sqrt(9.81f * k4 * (1.0f + k4 * k4 / (WAVE_KM*WAVE_KM))); table[(x+y*m_size)*4+0] = w1; table[(x+y*m_size)*4+1] = w2; table[(x+y*m_size)*4+2] = w3; table[(x+y*m_size)*4+3] = w4; } } //Write floating point data into render texture ComputeBuffer buffer = new ComputeBuffer(m_size*m_size, sizeof(float)*4); buffer.SetData(table); CBUtility.WriteIntoRenderTexture(m_WTable, 4, buffer, m_writeData); buffer.Release(); }