github.com/jphsd/texture
Package texture contains functions that can be combined to create image textures. Here's a simple example that creates a Perlin value field and renders it to an image: Fields are interfaces that support returning a value for any given point in the field. Three types of texture field are supported: All fields provide an Eval2(x, y float64) function which takes any x and y and returns either a value, vector or color. If a field type doesn't support the entire 2D plane, then it must return 0, {0, ..., 0}, or image/color.Black for values of x and y not supported. A texture is a tree made up of field nodes and leaves. A field is considered a leaf if it is not dependent on any other fields. Examples of leaves are the gradient fields LinearGradient, RadialGradient and ConicGradient. Any field that relies on another field or fields is considered a node. Examples of nodes are the filter fields like AbsFilter, ClipFilter and InvertFilter. All of these require at least one source field in order to operate. Textures are built from the leaves upward until a root node has been created. This node can then be passed to a function that will realize it, such as NewTextureRGBA which generates an image.RGBA by repeatedly calling the root's ColorField Eval2 function for each image pixel. 1D leaves vary only in one dimension, typically x. Different rotations, scalings and offsets can be obtained using Transform. As the name suggests, these return a single value independent of the location within the field. This field defines a gradient going from left to right using a Wave starting at 0 and repeating as a function of the wave's wave length (lambda). 2D leaves vary in x and y. Different rotations, scalings and offsets can be obtained using Transform. A collection of leaves for generating triangles, squares and hexagonal chequer boards. The size of the cells is determined by the scale value. The triangle and square boards are colored -1 and 1, whereas the hexagonal board is colored -1, 0 and 1. This field defines a gradient that rotates around {0,0} using a Wave starting at 0 and mapping x to theta / (2 * Pi). The image field uses the underlying image to figure the color value to return for any given location. Supported interpolations are NearestInterp, LinearInterp, CubicInterp, P3Interp and P5Interp. This field provides Perlin noise (aka gradient noise) using the supplied seed. The field repeats over [256,256]. See Perlin93. This field defines a gradient that extends from {0,0} using a Wave starting at 0 and mapping to the absolute distance from {0,0}. This field is defined by a graphics2d.Shape. Locations within the shape return 1 and all others -1. Like the heading says, these are 2D field generator experiments, your mileage may vary. Filters are nodes that do something with the value supplied by their source. They map values in [-1,1] to another in [-1,1]. Some filters take A and B parameters, in which case the value filtered is A*value+B The expressive range of the texture package is due to the ability to combine multiple source fields together using some heuristic. Convert between F, VF and CF fields Transformers affect the value of x and y used when a field's Evals method is called. They map (x, y) to (x', y'). This transformer applies an affine transform graphics2d.Aff3 to input coordinates allowing for translations, rotations, scalings and shearings. When something other than a gradient in x is required, the affine transform can be used to move, scale and rotate it to the desired location. Tiler transforms allow finite areas to be replicated across the infinite plane. Useful for creating repeating patterns and images. The relection transforms take a line defined by two points as the location of a mirror. Points on the positive side of the line remain unchanged while those on the negative are remapped. The warp transforms provide generalized image warping functionality not provided by the preceding. They rely on a function WarpFunc to map points from one domain to the other. The displace transforms use two fields to perturb the location returned from a third field. The degree of perturbation is controlled by a scaling factor. The second version of each transform allows a generalized affine transform to be supplied rather than just a fixed scaling. Distort provides a self referential transform that samples the field three times, once each for the x and y displacements and once with the new x' and y'. These transforms apply a resolution filter to x and y. Note that pixelate does not perform true pixelation in terms of averaging values over the desired resolution. These transforms replace y with a fixed value when performing Eval2(x, y). Strip also implements the Wave interface and can be used in gradient leaves. Three type of fractal nodel are available, Fractal, VariableFractal and IFS. Fractal nodes are a combination of both combiner and transformer nodes. Each location is evaluated for each octave, with an affine transform being applied between evaluations to x and y, and the resulting values then combined using an OctaveCombiner. Two OctaveCombiner are provided IFS, or Iterated Fractal Systems Barnsley88, take a series of contractive affine transformations and apply them repeatedely to some depth (akin to octaves above). Any type that implements Wave can be used to drive a gradient field. This interface defines two methods - Eval(x float64) which returns a value in [-1, 1], and Lambda() which returns the wave length of the wave. Three types are defined as starting points and allow a variety of waveforms to be generated: All of them utilize the non-linear functions provided in graphics2d. For convenience these are wrapped in NonLinear, primarily so that the output is mapped from [0,1] to [-1,1], and so that the slope name can be captured for JSON marshalling. NLWave takes a slice of wave lengths and a slice of slopes, together with flags that indicate if slopes should be mirrored, and whether only a single cycle shold be generated. DCWave takes a slice of one or two wave lengths and a slice of one or two slopes, together with a flag that indicate if only a single cycle shold be generated. If only one wave length is provided, then it is used for both the rising and falling halves of the wave. If only one slope type is provided, then it is used for both the rising and falling halves of the wave. Hence, providing only one wave length and slope type is equivalent to mirroring. When once is set, values less than 0 or greater than the wave length are returned as -1. ACWave takes a slice of one, two or four wave lengths and a slice of one, two or four slopes, together with a flag that indicate if only a single cycle shold be generated. Note this waveform starts at 0, unlike the other two which both start at -1. If only one wave length is provided, then it is used for all quadrants of the wave. If only one slope type is provided, then it is used for all quadrants of the wave. If only two wave lengths are provided, then they are used for both halves of the wave. If only two slope types are provided, then they are used for both halves of the wave. When once is set, values less than 0 or greater than the wave length are returned as 0. Textures are realized by calling the root node's Eval2(x, y) method. Image wrappers are provided that perform this step lazily and in a cacheable fashion. The wrapper is responsible for defining the image bounds, the texture offset and step values. These images can then be passed to image/draw.Draw, graphics2d.RenderShape or to graphics2d.NewFilledPen as source images. Caching determines whether a value is evaluated once and cached, or always evaluated. If a particular texture subgraph is expensive to compute, it may be better to evaluate it's domain once and cache it in an image that can then be referenced through an Image node. The 2D graphics packages in other languages, such as Java and SVG, have a notion of a gradient fill or paint. Go, however, doesn't since it's golang.org/x/image/vector.Draw takes an image. To address this texture has some utility functions that use simple gradient textures to create the same effect. The gradients are all value fields and mapped to either image/color.Gray16 or image/color.RGBA. In the latter case, by using github.com/jphsd/graphics2d/image.Colorizer.
proxy.golang.org
v0.0.0-20240110053551-4982ab182aff
over 2 years ago
13
Links
| Registry | proxy.golang.org |
| Source | Repository |
| Docs | Documentation |
| JSON API | View JSON |
| CodeMeta | codemeta.json |
Package Details
| PURL |
pkg:golang/github.com/jphsd/texture
spec |
| License | Apache-2.0 |
| Namespace | github.com/jphsd |
| First Release | over 3 years ago |
| Last Synced | 30 days ago |
Repository
| Stars | 17 on GitHub |
| Forks | 1 on GitHub |