Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ameobea/three-hex-tiling
Adds support for hiding repeating texture patterns to Three.JS
https://github.com/ameobea/three-hex-tiling
glsl glsl-shaders hex-tiling shaders texture texture-synthesis threejs
Last synced: 5 days ago
JSON representation
Adds support for hiding repeating texture patterns to Three.JS
- Host: GitHub
- URL: https://github.com/ameobea/three-hex-tiling
- Owner: Ameobea
- License: mit
- Created: 2023-06-12T10:00:52.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-12-11T22:15:55.000Z (about 2 months ago)
- Last Synced: 2025-01-17T11:10:40.080Z (14 days ago)
- Topics: glsl, glsl-shaders, hex-tiling, shaders, texture, texture-synthesis, threejs
- Language: TypeScript
- Homepage: https://three-hex-tiling.ameo.design/
- Size: 780 KB
- Stars: 65
- Watchers: 3
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# `three-hex-tiling`
[![npm version](https://img.shields.io/npm/v/three-hex-tiling.svg?style=flat-square)](https://www.npmjs.com/package/three-hex-tiling)
[![twitter](https://flat.badgen.net/badge/twitter/@ameobea10/?icon&label)](https://twitter.com/ameobea10)Extends built-in Three.JS materials to support infinite, non-repeating, seamless texture tiling.
![Screenshot showing comparison between a repeating seamless rock texture with and without three-hex-tiling. The image is divided in half horizontally by a gray bar. The left side is labeled "baseline" and shows a gray rock-like texture that clearly repeats, resulting in an artifical grid-like pattern. The right side has the same rock texture but without any visible tiling and is labeled three-hex-tiling.](https://i.ameo.link/bpu.jpg)
Live interactive demo:
## Installation
`npm install three-hex-tiling`
Then, to enable it, just add this to your project as early as possible:
```ts
import 'three-hex-tiling';
```This import will patch Three.JS's shaders and materials to support the hex tiling algorithm and it will extend the types for the patched materials with parameters to control it.
### Three.JS Version Support
This library has been tested with Three.JS versions `0.151` to `0.171`. Although it may work with other versions, support is not guaranteed.
## Usage
After adding the `three-hex-tiling` import at the top of your project, a new `hexTiling` parameter is added to the parameters of supported materials. If your project uses TypeScript, these should be included in the types you see when creating those materials.
By setting the `hexTiling` property when creating a material, hex tiling will be enabled for that material. It is disabled by default.
```ts
const mat = new THREE.MeshStandardMaterial({
map: myTexture,
normalMap: myTextureNormalMap,
roughnessMap: myTextureRoughnessMap,
hexTiling: {
// default values shown
patchScale: 2,
useContrastCorrectedBlending: true,
lookupSkipThreshold: 0.01,
textureSampleCoefficientExponent: 8,
}
});
```Hex tiling cannot be enabled or disabled after a material is created, but the values of individual parameters can be changed dynamically:
```ts
mat.hexTiling.patchScale = newPatchScale;
```### Texture Scaling
When enabling hex tiling for a material, you may find that your textures need a scale adjustment to look optimal. This can be done using built-in Three.JS texture scaling support:
```ts
myTexture.scale.set(1.5, 1.5);
myTextureNormalMap.scale.set(1.5, 1.5);
myTextureRoughnessMap.scale.set(1.5, 1.5);myTexture.needsUpdate = true;
myTextureNormalMap.needsUpdate = true;
myTextureRoughnessMap.needsUpdate = true;
```### Supported Textures
Textures used with `three-hex-tiling` must be seamless - meaning that there are no sharp cutoffs when the texture is tiled. There's a good chance your textures are seamless already and if they aren't, it will be obvious.
### Supported Materials
The following materials are currently supported for use with `three-hex-tiling`:
* `MeshStandardMaterial`
* `MeshPhysicalMaterial`You can still use all of the other materials that Three.JS provides, but they will not have support for hex tiling.
### Supported Maps
In addition to the base texture/color of a material provided in the `map` property, `three-hex-tiling` supports with the following maps:
* `normalMap`
* `roughnessMap`
* `metalnessMap`## Config Options
`three-hex-tiling` accepts the following configuration properties in the `hexTiling` object:
### `patchScale: number`
- **Description**: Scale factor for the hexagonal tiles used to break up the texture. This parameter is crucial in controlling the hex tiling's appearance and requires adjustment for each texture.
- **Default**: `2`
- **Range**: `[0, Infinity]`, typically between 0.1 and 8. Optimal values depend on the texture and desired effect.
- **Behavior**: Larger values create smaller hexagonal tiles, resulting in more texture breakup.| ![Screenshot of a black and red lava-like texture with three-hex-tiling applied with a patch scale of 1](https://i.ameo.link/bp2.jpg) | ![Screenshot of a black and red lava-like texture with three-hex-tiling applied with a patch scale of 2](https://i.ameo.link/bp3.jpg) | ![Screenshot of a black and red lava-like texture with three-hex-tiling applied with a patch scale of 6](https://i.ameo.link/bp5.jpg) |
|----------------------------------|----------------------------------|----------------------------------|
| Patch Scale: 1 | Patch Scale: 2 | Patch Scale: 6 |### `useContrastCorrectedBlending: boolean`
- **Description**: Determines if contrast-corrected blending is used for texture samples. This method often enhances blending quality but might result in overly bright or dark patches in high-contrast textures.
- **Default**: `true`
- **Reference**: [ShaderToy Demo](https://www.shadertoy.com/view/4dcSDr)| ![Screenshot of a rocky/mineral-like texture with three-hex-tiling applied and contrast-corrected blending enabled](https://i.ameo.link/bp8.jpg) | ![Screenshot of a rocky/mineral-like texture with three-hex-tiling applied and contrast-corrected blending disabled](https://i.ameo.link/bp9.jpg) |
|--------------------------------------|---------------------------------------|
| Contrast-Corrected Blending: Enabled | Contrast-Corrected Blending: Disabled |### `lookupSkipThreshold: number`
- **Description**: The minimum magnitude below which texture lookups are skipped, mainly for optimization purposes.
- **Default**: `0.01`
- **Range**: `[0, 1]` (but you'll probably always want to keep it <0.1)
- **Advice**: Usually doesn't require modification.
- **Details**: The shader mixes up to three texture samples per fragment. Texture lookups with a final coefficient less than this threshold are skipped to reduce GPU memory bandwidth usage.### `textureSampleCoefficientExponent: number`
- **Description**: The exponent for texture sample coefficients before comparison with `lookupSkipThreshold`. Adjusting this value affects shader efficiency and the visibility of hexagonal tile borders.
- **Default**: `8`
- **Range**: `(0, 64]`
- **Advice**: The default value is suitable for most textures. Modification is usually unnecessary.
- **Details**: Coefficients raised to this exponent modify the steepness of the threshold for skipping texture lookups. Higher exponents increase efficiency by reducing texture lookups, potentially making the shader more efficient.| ![Screenshot of a gray rock-like texture with three-hex-tiling applied with a texture sample coefficient exponent of 1](https://i.ameo.link/bpi.jpg) | ![Screenshot of a gray rock-like texture with three-hex-tiling applied with a texture sample coefficient exponent of 2](https://i.ameo.link/bph.jpg) | ![Screenshot of a gray rock-like texture with three-hex-tiling applied with a texture sample coefficient exponent of 8](https://i.ameo.link/bpg.jpg) |
|----------------------------------|----------------------------------|----------------------------------|
| Texture Sample Coefficient Exponent: 1 | Texture Sample Coefficient Exponent: 2 | Texture Sample Coefficient Exponent: 8 |## Performance
The hex tiling shader used by this library needs to make up to 3 texture fetches per map per fragment in order to function.
Usually, this is fine and doesn't result in any noticeable performance hit. But in some situations, hex tiling can create a significant amount of texture bandwidth usage on the GPU and impact performance on weaker devices.
### Optimizing Performance
There are some ways to tune `three-hex-tiling` to lessen its performance impact:
* Increase `textureSampleCoefficientExponent` and/or `lookupSkipThreshold`
* This directly reduces the average number of texture samples made per fragment, but it can make the borders between hex tiles more obvious.
* Use a [depth pre-pass](https://cprimozic.net/blog/threejs-depth-pre-pass-optimization/) to your scene to reduce the number of calls to the fragment shader.
* For some scenes, especially those with high overdraw, this can be a big win
* Reduce the number of maps used by your material
* Reduce the size of textures used or use [compressed textures](https://threejs.org/docs/#api/en/textures/CompressedTexture)## Implementation Details
The hex tiling shader itself is adapted from [a Shadertoy](https://www.shadertoy.com/view/MdyfDV) by [Fabrice Neyret](http://evasion.imag.fr/Membres/Fabrice.Neyret/).
`three-hex-tiling` works by modifying Three.JS's shaders directly, patching in the hex tiling algorithm and conditionally enabling it for materials that opt in. Materials that do not explicitly set `hexTiling` will work normally.
In addition to patching the shaders, it also installs a custom [`onBeforeCompile`](https://threejs.org/docs/#api/en/materials/Material.onBeforeCompile) callback on materials. If you make use of `onBeforeCompile` in your own code, there's a good chance that `three-hex-tiling` will interfere with it and cause problems.