public void GenerateThumbnail() { Texture2D thumb = new Texture2D(32, 32, TextureFormat.ARGB32, false); //create a new texture Color[] pixels = new Color[thumb.width * thumb.height]; //fill with black for (int c = 0; c < pixels.Length; c++) { pixels[c] = new Color(0f, 0f, 0f, 1f); } // plot the function on a line for (int x = 0; x < thumb.width; x++) { // scale from -PI to PI float scaledX = Scale(x, thumb.width) * Mathf.PI; float plot = ActivationFunctions.Activation(fTYPE, scaledX); int mappedPlot; //if (plot < -1 || plot > 1) mappedPlot = Remap(plot, -Mathf.PI, Mathf.PI, 0, thumb.height - 1); //else mappedPlot = Remap(plot, -1, 1, 0, thumb.height - 1); Color color = new Color(1f, 1f, 1f, 1f); if (ArtGallery.DEBUG_LEVEL >= ArtGallery.DEBUG.VERBOSE) { Debug.Log(mappedPlot); } pixels[x + mappedPlot * thumb.width] = color; } thumb.SetPixels(pixels); thumb.Apply(); Texture = thumb; Image = Sprite.Create(thumb, new Rect(0, 0, thumb.width, thumb.height), new Vector2(0.5f, 0.5f)); }
Texture2D CreateCPPNImage(int width, int height) { GenerateCPPN(); //Texture2D img = new Texture2D(width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float scaledX = Scale(x, width); float scaledY = Scale(y, height); float distCenter = GetDistFromCenter(scaledX, scaledY); float[] hsv = ProcessCPPNInput(scaledX, scaledY, GetDistFromCenter(scaledX, scaledY), BIAS); // This initial hue is in the range [-1,1] as in the MM-NEAT code float initialHue = ActivationFunctions.Activation(FTYPE.PIECEWISE, hsv[TWO_DIMENSIONAL_HUE_INDEX]); // However, C Sharp's Colors do not automatically map negative numbers to the proper hue range as in Java, so an additional step is needed float finalHue = initialHue < 0 ? initialHue + 1 : initialHue; Color colorHSV = Color.HSVToRGB( finalHue, ActivationFunctions.Activation(FTYPE.HLPIECEWISE, hsv[TWO_DIMENSIONAL_SATURATION_INDEX]), Mathf.Abs(ActivationFunctions.Activation(FTYPE.PIECEWISE, hsv[TWO_DIMENSIONAL_BRIGHTNESS_INDEX])), true ); img.SetPixel(x, y, colorHSV); } } img.Apply(); return(img); }
private float[] FormatHSV(float[] hsv) { float[] result = new float[hsv.Length]; float range = MaxValue - MinValue; result[TWO_DIMENSIONAL_HUE_INDEX] = ((hsv[TWO_DIMENSIONAL_HUE_INDEX] - MinValue) / range); //result[TWO_DIMENSIONAL_HUE_INDEX] = Mathf.Abs((ActivationFunctions.Activation(FTYPE.PIECEWISE, hsv[TWO_DIMENSIONAL_HUE_INDEX]))); result[TWO_DIMENSIONAL_SATURATION_INDEX] = ActivationFunctions.Activation(FTYPE.HLPIECEWISE, hsv[TWO_DIMENSIONAL_SATURATION_INDEX]); result[TWO_DIMENSIONAL_BRIGHTNESS_INDEX] = Mathf.Abs(ActivationFunctions.Activation(FTYPE.PIECEWISE, hsv[TWO_DIMENSIONAL_BRIGHTNESS_INDEX])); return(result); }
private float[] FixHue(Vector4 outputFromCPPN) { float[] result = new float[4]; float range = MaxValue - MinValue; result[THREE_DIMENSIONAL_HUE_INDEX] = ((outputFromCPPN[THREE_DIMENSIONAL_HUE_INDEX] - MinValue) / range); //result[TWO_DIMENSIONAL_HUE_INDEX] = Mathf.Abs((ActivationFunctions.Activation(FTYPE.PIECEWISE, hsv[TWO_DIMENSIONAL_HUE_INDEX]))); result[THREE_DIMENSIONAL_SATURATION_INDEX] = ActivationFunctions.Activation(FTYPE.HLPIECEWISE, outputFromCPPN[THREE_DIMENSIONAL_SATURATION_INDEX]); result[THREE_DIMENSIONAL_BRIGHTNESS_INDEX] = Mathf.Abs(ActivationFunctions.Activation(FTYPE.PIECEWISE, outputFromCPPN[THREE_DIMENSIONAL_BRIGHTNESS_INDEX])); result[THREE_DIMENSIONAL_VOXEL_INDEX] = outputFromCPPN[THREE_DIMENSIONAL_VOXEL_INDEX]; return(result); }
/// <summary> /// Internal activation function /// </summary> private void Activate() { activation = ActivationFunctions.Activation(fType, sum); // Debug.Log("Activation of " + GetInnovationID() + " is " + activation); }
/// <summary> /// Change voxels in sculpture based on CPPN outputs /// </summary> private void DrawSculpture() { processingCPPN = true; float halfVoxelSize = voxelSize / 2; cppn = new TWEANN(geno); Vector4[] outArr = new Vector4[SCULP_X * SCULP_Z * SCULP_Y]; voxArray = new Color[SCULP_X, SCULP_Z, SCULP_Y]; for (int x = 0; x < SCULP_X; x++) { for (int z = 0; z < SCULP_Z; z++) { for (int y = 0; y < SCULP_Y; y++) { float actualX = -(halfVoxelSize * SCULP_X / 2.0f) + halfVoxelSize + x * halfVoxelSize; float actualZ = -(halfVoxelSize * SCULP_Z / 2.0f) + halfVoxelSize + z * halfVoxelSize; float actualY = -(halfVoxelSize * SCULP_Y / 2.0f) + halfVoxelSize + y * halfVoxelSize; float distFromCenter = GetDistFromCenter(actualX, actualZ, actualY); float distFromCenterXZ = GetDistFromCenterXY(actualX, actualZ); float distfromCenterYZ = GetDistFromCenterZY(actualY, actualZ); float distfromCenterZY = GetDistFromCenterZY(actualX, actualZ); //float[] outputs = cppn.Process(new float[] { actualX, actualY, actualZ, distFromCenter, BIAS}); float[] outputs = cppn.Process(new float[] { actualX, actualY, actualZ, distFromCenter, distFromCenterXZ, distfromCenterYZ, distfromCenterZY, BIAS }); //TODO move all of the CPPN render out of the draw function if (MaxValue < outputs[THREE_DIMENSIONAL_HUE_INDEX]) { MaxValue = outputs[THREE_DIMENSIONAL_HUE_INDEX]; } if (MinValue > outputs[THREE_DIMENSIONAL_HUE_INDEX]) { MinValue = outputs[THREE_DIMENSIONAL_HUE_INDEX]; } outArr[x + (SCULP_Z * z) + (SCULP_Y * y)] = new Vector4(outputs[THREE_DIMENSIONAL_HUE_INDEX], outputs[THREE_DIMENSIONAL_SATURATION_INDEX], outputs[THREE_DIMENSIONAL_BRIGHTNESS_INDEX], outputs[THREE_DIMENSIONAL_VOXEL_INDEX]); } } } for (int x = 0; x < SCULP_X; x++) { for (int z = 0; z < SCULP_Z; z++) { for (int y = 0; y < SCULP_Y; y++) { float[] o = FixHue(outArr[x + (SCULP_Z * z) + (SCULP_Y * y)]); if (o[THREE_DIMENSIONAL_VOXEL_INDEX] > PRESENCE_THRESHOLD) { Color colorHSV = Color.HSVToRGB( o[THREE_DIMENSIONAL_HUE_INDEX], o[THREE_DIMENSIONAL_SATURATION_INDEX], o[THREE_DIMENSIONAL_BRIGHTNESS_INDEX], true ); float alpha = 1f; if (transparent) { alpha = ActivationFunctions.Activation(FTYPE.HLPIECEWISE, o[THREE_DIMENSIONAL_VOXEL_INDEX]); } //float alpha = -1.0f; Color color = new Color(colorHSV.r, colorHSV.g, colorHSV.b, alpha); voxArray[x, z, y] = color; } else { // This option will make the voxel turn off (requires matching = true statement above) voxArray[x, z, y] = new Color(0f, 0f, 0f, 0f); // This option will enable the "glass block" effect //rend.material.SetColor("_Color", new Color(0f, 0f, 0f, 0f)); } } } } processingCPPN = false; needsRedraw = true; }