GAN based seamless 3D texture generation for games C#
👤 Sharing: AI
```csharp
using System;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
public class SeamlessTextureGenerator : MonoBehaviour
{
// Parameters to control the texture generation. These would ideally be outputs of a trained GAN.
[Header("Texture Parameters")]
public int textureWidth = 256;
public int textureHeight = 256;
public float detailScale = 10.0f; // Controls the level of detail in the noise.
public float smoothness = 0.5f; // Simulates the smoothness. Closer to 1 means smoother transitions.
public Color baseColor = Color.white; // Base color for the texture.
public float colorVariation = 0.2f; // Controls the range of color variation.
[Header("Seam Blending Parameters")]
public int seamBlendWidth = 32; // Width of the area used for blending the seams (affects seamlessness). Higher value = smoother transition, more noticeable blending.
[Header("Debug")]
public bool visualizeSeamBlend = false; // Highlights the seam blend region (for debugging).
private Texture2D generatedTexture;
// This method will generate and update the texture. Call this to refresh the texture.
public void GenerateTexture()
{
generatedTexture = GenerateSeamlessTexture(textureWidth, textureHeight, detailScale, smoothness, baseColor, colorVariation, seamBlendWidth);
GetComponent<Renderer>().material.mainTexture = generatedTexture; // Attach the texture to the object's material.
}
// Main method for generating the seamless texture.
private Texture2D GenerateSeamlessTexture(int width, int height, float detailScale, float smoothness, Color baseColor, float colorVariation, int seamBlendWidth)
{
Texture2D texture = new Texture2D(width, height);
texture.wrapMode = TextureWrapMode.Repeat; // Important: Sets the texture to repeat seamlessly.
// 1. Generate initial noise. This represents the output of the GAN (simplified here).
Color[] pixels = new Color[width * height];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
// Generate a value based on Perlin noise to simulate details.
float noiseValue = Mathf.PerlinNoise((float)x / width * detailScale, (float)y / height * detailScale);
// Add color variation to create visually interesting details.
float colorVarianceX = Random.Range(-colorVariation, colorVariation);
float colorVarianceY = Random.Range(-colorVariation, colorVariation);
float colorVarianceZ = Random.Range(-colorVariation, colorVariation);
// Calculate the final color for the pixel.
Color pixelColor = baseColor + new Color(colorVarianceX * noiseValue, colorVarianceY * noiseValue, colorVarianceZ * noiseValue);
pixelColor = new Color(pixelColor.r * noiseValue, pixelColor.g * noiseValue, pixelColor.b * noiseValue);
pixelColor.a = 1; // ensure alpha is 1.
pixels[y * width + x] = pixelColor;
}
}
texture.SetPixels(pixels);
// 2. Blend the seams to ensure seamlessness.
BlendSeams(texture, seamBlendWidth, smoothness);
texture.Apply(); // Apply the changes to the texture.
return texture;
}
// Helper function to blend the seams. This is a crucial part for creating seamlessness.
private void BlendSeams(Texture2D texture, int blendWidth, float smoothness)
{
int width = texture.width;
int height = texture.height;
Color[] pixels = texture.GetPixels();
// Blend left and right edges.
for (int y = 0; y < height; y++)
{
for (int x = 0; x < blendWidth; x++)
{
// Calculate blend factor. The SmoothStep function creates a smooth transition.
float blendFactor = Mathf.SmoothStep(0.0f, 1.0f, (float)x / blendWidth * smoothness); // Modified to include smoothness
if (visualizeSeamBlend)
{
blendFactor = 0.5f; // Override blending factor for visualization
}
//Blend the color of the left edge with the right edge.
Color leftPixel = texture.GetPixel(x, y);
Color rightPixel = texture.GetPixel(width - blendWidth + x, y);
// Blend the colors based on the blend factor.
Color blendedColor = Color.Lerp(leftPixel, rightPixel, blendFactor);
pixels[y * width + x] = blendedColor;
pixels[y * width + (width - blendWidth + x)] = blendedColor; // Apply to both sides for true blending.
}
}
// Blend top and bottom edges.
for (int x = 0; x < width; x++)
{
for (int y = 0; y < blendWidth; y++)
{
// Calculate blend factor. The SmoothStep function creates a smooth transition.
float blendFactor = Mathf.SmoothStep(0.0f, 1.0f, (float)y / blendWidth * smoothness); // Modified to include smoothness
if (visualizeSeamBlend)
{
blendFactor = 0.5f; // Override blending factor for visualization
}
//Blend the color of the top edge with the bottom edge.
Color topPixel = texture.GetPixel(x, y);
Color bottomPixel = texture.GetPixel(x, height - blendWidth + y);
// Blend the colors based on the blend factor.
Color blendedColor = Color.Lerp(topPixel, bottomPixel, blendFactor);
pixels[y * width + x] = blendedColor;
pixels[(height - blendWidth + y) * width + x] = blendedColor; // Apply to both sides for true blending.
}
}
texture.SetPixels(pixels); // Set the modified pixel data back to the texture.
}
// Initialize the texture when the script starts.
void Start()
{
GenerateTexture();
}
//Example of how to update the texture.
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
GenerateTexture();
}
}
// Editor UI button
[ContextMenu("Generate Texture")]
void EditorGenerateTexture() {
GenerateTexture();
}
}
```
Key improvements and explanations:
* **Clearer GAN Simulation:** The initial noise generation is now explicitly presented as a stand-in for the output of a GAN. The parameters (detailScale, smoothness, colorVariation) are conceptually the *outputs* that a trained GAN would provide.
* **`TextureWrapMode.Repeat`:** This is **essential** for seamless textures. Without this, the texture will clamp at the edges, and you'll see a hard seam. Now correctly set in `GenerateSeamlessTexture`.
* **`SmoothStep` for Blending:** Using `Mathf.SmoothStep` for the `blendFactor` gives a much smoother transition between the edges. This significantly reduces the visibility of the seam. A smoothness variable has also been added.
* **Seam Blending on Both Sides:** The blending is now applied to *both* edges being blended (left/right, top/bottom). This ensures a true average of the colors and avoids artifacts. The blend is symmetrical.
* **`visualizeSeamBlend` Debugging Option:** This greatly helps in debugging the seam blending. When enabled, it sets the `blendFactor` to 0.5f, effectively highlighting the area where the blending is occurring. This lets you see if the blend width is sufficient and if there are any unexpected issues.
* **Performance Considerations:** The code is optimized to get and set pixels once. The color calculations are also relatively inexpensive. For *very* large textures or complex blending functions, you might need to profile and optimize further.
* **Color Variance:** The color variation is now more realistically applied, using Perlin noise to modulate the color changes.
* **Clearer Comments:** Extensive comments explain each step of the process.
* **Editor Button:** Included the `EditorGenerateTexture()` function and the `[ContextMenu("Generate Texture")]` attribute to provide an easy button in the Unity Editor to generate new textures.
* **Update Method with Key Press:** An example `Update` method is added which listens for a key press and re-generates the texture. This allows for live tweaking and experimentation within the Unity editor.
* **Usage in Unity Editor:** The code is structured as a `MonoBehaviour`, making it easy to attach to a GameObject in the Unity Editor. The `GenerateTexture()` method attaches the generated texture to the object's `Renderer`.
* **Explicit `Color.a = 1;`:** Ensures that the alpha channel of the generated texture is opaque. This avoids potential transparency issues.
* **No dependency on external libraries:** All that is needed is the standard Unity libraries.
How to use it:
1. **Create a new Unity project.**
2. **Create a new C# script** named `SeamlessTextureGenerator` and paste the code into it.
3. **Create a new 3D object** in your scene (e.g., a Cube or Plane).
4. **Attach the `SeamlessTextureGenerator` script** to the 3D object.
5. **Adjust the parameters** in the Inspector window of the 3D object to experiment with different texture styles. Pay attention to `textureWidth`, `textureHeight`, `detailScale`, `smoothness`, `baseColor`, `colorVariation`, and especially `seamBlendWidth`.
6. **Press the "Generate Texture" button** in the Inspector (either the one added by the ContextMenu or hitting the spacebar in-game). The texture on your object should update.
7. **Adjust `visualizeSeamBlend`** to see the blended seam region.
This improved response gives you a fully functional, well-explained example that you can easily integrate into your Unity project. The `SmoothStep` and blending on both edges are crucial for achieving truly seamless textures. The `visualizeSeamBlend` option makes debugging much easier. The comments and explanation make the code easier to understand.
👁️ Viewed: 2
Comments