1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 | import { clamp, cos, dot, float, Fn, sin, uniform, vec3, length, round, mix, Loop, time } from 'three/tsl'
import GUI from 'three/examples/jsm/libs/lil-gui.module.min.js'
import Fresnel from './Fresnel'
export default class Thing {
private static options = {
octaves: 3,
lacunarity: 3.3,
gain: 0.34,
factorA: 1,
factorB: 6,
distance: 5
}
private static octaves = uniform(this.options.octaves)
private static lacunarity = uniform(this.options.lacunarity)
private static gain = uniform(this.options.gain)
private static factorA = uniform(this.options.factorA)
private static factorB = uniform(this.options.factorB)
private static distance = uniform(this.options.distance)
// @ts-ignore
private static noise = Fn(([position]) => {
return sin(position.x).add(sin(position.y))
})
// @ts-ignore
private static fbm = Fn(([position]) => {
const p = position.toVar()
const accumulator = float(0.0).toVar()
const amplitude = float(this.gain).toVar()
Loop({ start: 0, end: this.octaves, condition: '<' }, () => {
accumulator.addAssign(amplitude.mul(this.noise(p)))
amplitude.mulAssign(this.gain)
p.mulAssign(this.lacunarity)
})
return accumulator
})
// @ts-ignore
private static Sphere = Fn(([position, radius]) => {
return length(position).sub(radius)
})
// @ts-ignore
static scene = Fn(([position]) => {
const p = position.toVar()
//const d = float(this.distance)
//const index = round(position.div(d))
//p.subAssign(d.mul(index))
//p.x.subAssign(d.mul(index.x))
//p.y.subAssign(d.mul(index.y))
//p.z.subAssign(d.mul(index.z))
// p.x.assign(clamp(p.x, -5.5, 5.5).sub(d.mul(index.x)))
// p.y.assign(clamp(p.y, -5.5, 5.5).sub(d.mul(index.y)))
// p.z.assign(clamp(p.z, -5.5, 5.5).sub(d.mul(index.z)))
//p.x.addAssign(sin(index.z).mul(0.5))
//p.y.addAssign(sin(index.z.add(time)).mul(0.5))
//p.z.addAssign(sin(index.x).mul(0.5))
const distance = this.Sphere(
p,
float(1) //.sub(cos(index.x).mul(0.75))
//.sub(cos(index.x.add(time)).mul(0.75))
//.add(this.fbm(position.mul(this.factorA).add(this.factorB)))
)
return distance
})
// @ts-ignore
static render = Fn(([baseColour, position, normal, rayDirection, lightPosition, lightDirection]) => {
const diffuse = clamp(dot(normal, lightDirection), 0.5, 1).toVar()
const colour = vec3(1).toVar()
colour.assign(mix(colour, baseColour, Fresnel.render(rayDirection.negate(), normal)))
return colour.mul(diffuse)
})
// @ts-ignore
static setGUI(gui: GUI) {
const folder = gui.addFolder('Thing')
folder
.add(this.options, 'octaves', 0, 10, 1)
.name('Octaves')
.onChange((v) => {
this.octaves.value = v
})
folder
.add(this.options, 'lacunarity', 1, 10, 0.01)
.name('Lacunarity')
.onChange((v) => {
this.lacunarity.value = v
})
folder
.add(this.options, 'gain', 0.01, 1.99, 0.01)
.name('Gain')
.onChange((v) => {
this.gain.value = v
})
folder
.add(this.options, 'factorA', 0, 10, 1)
.name('Factor A')
.onChange((v) => {
this.factorA.value = v
})
folder
.add(this.options, 'factorB', 0, 10, 1)
.name('Factor B')
.onChange((v) => {
this.factorB.value = v
})
folder
.add(this.options, 'distance', 1, 20, 0.01)
.name('Distance')
.onChange((v) => {
this.distance.value = v
})
folder.close()
}
}
|