[READ-ONLY] Mirror of https://github.com/flo-bit/shapecraft. flo-bit.dev/shapecraft/
0

Configure Feed

Select the types of activity you want to include in your feed.

shapecraft / src / color / gradient.ts
1.7 kB 46 lines
1import type { ColorInput, ColorFn, Vec3 } from '../core/types' 2import { parseColorToRgb, lerpColor } from './utils' 3 4export type GradientStop = [number, ColorInput] 5 6export function gradient(stops: GradientStop[]): (value: number) => [number, number, number] { 7 const sorted = [...stops].sort((a, b) => a[0] - b[0]) 8 9 return function sampleGradient(value: number): [number, number, number] { 10 if (sorted.length === 0) return [1, 1, 1] 11 if (value <= sorted[0][0]) return parseColorToRgb(sorted[0][1]) 12 if (value >= sorted[sorted.length - 1][0]) return parseColorToRgb(sorted[sorted.length - 1][1]) 13 14 for (let i = 0; i < sorted.length - 1; i++) { 15 if (value >= sorted[i][0] && value <= sorted[i + 1][0]) { 16 const t = (value - sorted[i][0]) / (sorted[i + 1][0] - sorted[i][0]) 17 return lerpColor(sorted[i][1], sorted[i + 1][1], t) 18 } 19 } 20 return parseColorToRgb(sorted[sorted.length - 1][1]) 21 } 22} 23 24export function heightGradient(stops: GradientStop[]): ColorFn { 25 const grad = gradient(stops) 26 return function heightColorFn(position: Vec3): [number, number, number] { 27 return grad(position[1]) 28 } 29} 30 31/** 32 * Color based on normal direction — lerps between downColor (facing down) 33 * and upColor (facing up). Useful for vegetation, terrain, etc. 34 */ 35export function normalGradient(upColor: ColorInput, downColor: ColorInput): ColorFn { 36 const up = parseColorToRgb(upColor) 37 const down = parseColorToRgb(downColor) 38 return function normalColorFn(_position: Vec3, normal: Vec3): [number, number, number] { 39 const t = normal[1] * 0.5 + 0.5 // -1..1 → 0..1 40 return [ 41 down[0] + (up[0] - down[0]) * t, 42 down[1] + (up[1] - down[1]) * t, 43 down[2] + (up[2] - down[2]) * t, 44 ] 45 } 46}