Created
June 20, 2025 14:17
-
-
Save sampavlovic/980bba74c4d52aeb3b44338c349a0eb9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using Sandbox; | |
| using Sandbox.Utility; | |
| /// <summary> | |
| /// Procedurally builds a 3‑dimensional Perlin noise volume texture for use in materials and shaders. | |
| /// </summary> | |
| public sealed class PerlinVolumeTexture | |
| { | |
| /// <summary>Width of the 3D texture in voxels.</summary> | |
| public int Width { get; } | |
| /// <summary>Height of the 3D texture in voxels.</summary> | |
| public int Height { get; } | |
| /// <summary>Depth of the 3D texture in voxels.</summary> | |
| public int Depth { get; } | |
| /// <summary> | |
| /// Spatial scale applied to the noise coordinates. Higher values zoom out; lower values zoom in. | |
| /// </summary> | |
| public float Scale { get; set; } = 1.0f; | |
| /// <summary>Number of Fractal Brownian Motion octaves layered together.</summary> | |
| public int Octaves { get; set; } = 4; | |
| /// <summary>Resource name given to the resulting <see cref="Texture"/>.</summary> | |
| public string Name { get; set; } | |
| /// <summary> | |
| /// Creates a new Perlin 3D texture generator. | |
| /// </summary> | |
| public PerlinVolumeTexture( int width, int height, int depth, string name = null ) | |
| { | |
| if ( width <= 0 || height <= 0 || depth <= 0 ) | |
| throw new ArgumentOutOfRangeException( "Texture dimensions must be positive non‑zero." ); | |
| Width = width; | |
| Height = height; | |
| Depth = depth; | |
| Name = name ?? $"perlin_volume_{width}x{height}x{depth}"; | |
| } | |
| /// <summary> | |
| /// Generates the noise on the CPU and uploads the data to a GPU. | |
| /// </summary> | |
| public Texture Generate() | |
| { | |
| var buffer = new byte[ Width * Height * Depth ]; | |
| var idx = 0; | |
| for ( int z = 0; z < Depth; z++ ) | |
| { | |
| for ( int y = 0; y < Height; y++ ) | |
| { | |
| for ( int x = 0; x < Width; x++ ) | |
| { | |
| // Noise.Fbm returns [0,1]. Convert to byte range. | |
| float n = Noise.Fbm( Octaves, x * Scale, y * Scale, z * Scale ); | |
| buffer[ idx++ ] = (byte)( n * 255f ); | |
| } | |
| } | |
| } | |
| return Texture.CreateVolume( Width, Height, Depth, ImageFormat.I8 ) | |
| .WithName( Name ) | |
| .WithData( buffer ) | |
| .Finish(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment