UNPKG

pet-gen

Version:

Procedural Equirectangular Texture Generators

196 lines (118 loc) 5.08 kB
// Procedural Equirectangular Textures // Polka Dots Pattern // // defaults = {...} - default parameters // pattern( ... ) - calculate color of pixel // texture( params ) - generate a texture // material( ... ) - material shader fix import { Vector3, Color, PolyhedronGeometry, TetrahedronGeometry, OctahedronGeometry, DodecahedronGeometry, IcosahedronGeometry, MathUtils } from "three"; import { mergeVertices } from 'three/addons/utils/BufferGeometryUtils.js'; import { retexture, map } from "../texture-generator.js"; // internal class to have the cube as one of the Platonic solids class HexahedronGeometry extends PolyhedronGeometry { constructor( radius, level ) { var verticesOfCube = [ -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ]; var indicesOfFaces = [ 2, 1, 0, 0, 3, 2, 0, 4, 7, 7, 3, 0, 0, 1, 5, 5, 4, 0, 1, 2, 6, 6, 5, 1, 2, 3, 7, 7, 6, 2, 4, 5, 6, 6, 7, 4 ]; super( verticesOfCube, indicesOfFaces, radius, level ); } } // generate predefined layouts of points on a unit sphere var layouts = [ { geometry: TetrahedronGeometry, level: 0, points: [], maxScale: 106 }, // #2, pts=4 { geometry: OctahedronGeometry, level: 0, points: [], maxScale: 95 }, // #3, pts=6 { geometry: OctahedronGeometry, level: 1, points: [], maxScale: 77 }, // #6, pts=18 { geometry: HexahedronGeometry, level: 0, points: [], maxScale: 96 }, // #4, pts=8 { geometry: HexahedronGeometry, level: 1, points: [], maxScale: 69 }, // #8, pts=26 { geometry: DodecahedronGeometry, level: 0, points: [], maxScale: 79 }, // #7, pts=20 { geometry: IcosahedronGeometry, level: 0, points: [], maxScale: 79 }, // #5, pts=12 { geometry: IcosahedronGeometry, level: 1, points: [], maxScale: 59 }, // #9, pts=42 { geometry: IcosahedronGeometry, level: 2, points: [], maxScale: 48 }, // #10, pts=92 { geometry: IcosahedronGeometry, level: 3, points: [], maxScale: 42 }, // #11, pts=162 { geometry: IcosahedronGeometry, level: 4, points: [], maxScale: 37 }, // #12, pts=252 { geometry: IcosahedronGeometry, level: 5, points: [], maxScale: 32 }, // #13, pts=361 { count: 1, points: [], maxScale: 141 }, // #1, pts=1 { count: 500, points: [], maxScale: 33 }, // #14, pts=500 { count: 750, points: [], maxScale: 30 }, // #15, pts=750 { count: 1000, points: [], maxScale: 28 }, // #16, pts=1000 { count: 1500, points: [], maxScale: 25 }, // #17, pts=1500 { count: 2000, points: [], maxScale: 23 }, // #18, pts=2000 { count: 3000, points: [], maxScale: 21 }, // #19, pts=3000 { count: 5000, points: [], maxScale: 18 }, // #20, pts=5000 ]; // generate dot positions for ( var index=0; index<layouts.length; index++ ) { var level = layouts[ index ].level, geometryClass = layouts[ index ].geometry; if ( geometryClass ) { // platonic var geometry = new geometryClass( 1, level ); geometry.deleteAttribute( 'normal' ); geometry.deleteAttribute( 'uv' ); var mergedGeometry = mergeVertices( geometry ); var positions = mergedGeometry.getAttribute( 'position' ); for ( var i=0; i<positions.count; i++ ) layouts[ index ].points.push( new Vector3().fromBufferAttribute( positions, i ) ); geometry.dispose( ); mergedGeometry.dispose( ); } else { // fibonaccic var n = layouts[ index ].count; var gr = ( 1+5**0.5 )/2; for ( var i=0; i<n; i++ ) { var theta = 2*Math.PI*i/gr; var phi = Math.acos( 1-( 2*i+1 )/n ); layouts[ index ].points.push( new Vector3().setFromSphericalCoords( 1, phi, theta ) ); } } } layouts.sort( ( a, b )=>a.points.length-b.points.length ); var defaults = { $name: 'Polka dots', $layouts: layouts, width: 512, height: 256, layout: 9, scale: 50, blur: 20, color: 0x000000, background: 0xFFFFFF, }; var vec = new Vector3(); function pattern( x, y, z, color, options, /*u, v, px, py*/ ) { vec.set( z, y, x ); var dist = 1e10; for ( var point of options.points ) dist = Math.min( dist, vec.distanceTo( point ) ); var k = MathUtils.smoothstep( dist, options.minSmooth, options.maxSmooth ); color.lerpColors( options.color, options.background, k ); } function options( params ) { var data = layouts[ ( params.layout ?? defaults.layout )-1 ]; var blur = map( params.blur??defaults.blur )**2.5 / 3; var scale = map( params.scale??defaults.scale, 0, data.maxScale ); scale = ( scale / 100 )**2; return { color: new Color( params.color ?? defaults.color ), background: new Color( params.background ?? defaults.background ), points: data.points, minSmooth: scale - blur, maxSmooth: scale + blur, width: params.width ?? defaults.width, height: params.height ?? defaults.height, }; } function texture( ...opt ) { return retexture( opt, defaults, options, pattern ); } export { pattern, defaults, texture }; export { material } from "../texture-generator.js";