/// <summary> /// Generates both textures and saves them to the given file paths. /// Returns whether the operation succeeded. /// </summary> private bool GenerateTextures(string texPath, string normalTexPath = null) { //The base data set should be large enough for both textures. int baseDataSizeX = X, baseDataSizeY = Y, baseDataSizeZ = Z; if (GenerateNormals) { baseDataSizeX = Math.Max(baseDataSizeX, Normals_X); baseDataSizeY = Math.Max(baseDataSizeY, Normals_Y); baseDataSizeZ = Math.Max(baseDataSizeZ, Normals_Z); } Graph graph = LoadGraph(); GraphParamCollection graphParams = GraphParams; //Generate the initial data. float[,,] baseData = GraphEditorUtils.GenerateToArray(graph, graphParams, baseDataSizeX, baseDataSizeY, baseDataSizeZ); //Generate the value texture. float[,,] valueTexData = baseData.ResampleFull(Mathf.Lerp, X, Y, Z); Gradient colorGradient = MakeGradient(); Color[] valueTexPixels = new Color[X * Y * Z]; for (int z = 0; z < Z; ++z) { for (int y = 0; y < Y; ++y) { for (int x = 0; x < X; ++x) { float value = valueTexData[x, y, z]; int index = x + (y * X) + (z * X * Y); valueTexPixels[index] = colorGradient.Evaluate(value); } } } Texture3D valueTex = new Texture3D(X, Y, Z, TextureFormat.ARGB32, false); valueTex.wrapMode = Wrapping; valueTex.filterMode = Filtering; valueTex.SetPixels(valueTexPixels); valueTex.Apply(UseMipmaps, !LeaveReadable); AssetDatabase.CreateAsset(valueTex, StringUtils.GetRelativePath(texPath, "Assets")); //Generate the normals texture. if (normalTexPath == null) { return(true); } float[,,] normalsValueData = baseData.ResampleFull(Mathf.Lerp, Normals_X, Normals_Y, Normals_Z); Color[] normalsPixels = new Color[Normals_X * Normals_Y * Normals_Z]; for (int z = 0; z < Normals_Z; ++z) { for (int y = 0; y < Normals_Y; ++y) { for (int x = 0; x < Normals_X; ++x) { //The first digit is the X, the second is the Y, the third is the Z. float _000, _100, _010, _110, _001, _101, _011, _111; normalsValueData.Sample(x, y, z, true, out _000, out _100, out _010, out _110, out _001, out _101, out _011, out _111); Vector3 gradient = new Vector3(); gradient.x = (_100 - _000) + (_110 - _010) + (_101 - _001) + (_111 - _011); gradient.y = (_010 - _000) + (_110 - _100) + (_011 - _001) + (_111 - _101); gradient.z = (_001 - _000) + (_101 - _100) + (_011 - _010) + (_111 - _110); //Normalize. if (gradient == Vector3.zero) { gradient = Vector3.up; } else { gradient = gradient.normalized; } //Pack into a color. int index = x + (y * Normals_X) + (z * Normals_X * Normals_Y); normalsPixels[index] = new Color(0.5f + (0.5f * gradient.x), 0.5f + (0.5f * gradient.y), 0.5f + (0.5f * gradient.z)); } } } Texture3D normalsTex = new Texture3D(Normals_X, Normals_Y, Normals_Z, Normals_Format, Normals_UseMipmaps); normalsTex.wrapMode = Normals_Wrapping; normalsTex.filterMode = Normals_Filtering; normalsTex.SetPixels(normalsPixels); normalsTex.Apply(Normals_UseMipmaps, !Normals_LeaveReadable); AssetDatabase.CreateAsset(normalsTex, StringUtils.GetRelativePath(normalTexPath, "Assets")); return(true); }