@ccp-nc/crystvis-js 0.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/.eslintrc.json +16 -0
  2. package/.github/workflows/test-mocha.yml +30 -0
  3. package/.vscode/settings.json +4 -0
  4. package/LICENSE +21 -0
  5. package/README.html +1127 -0
  6. package/README.md +76 -0
  7. package/demo/demo.css +30 -0
  8. package/demo/index.html +76 -0
  9. package/demo/main.js +143 -0
  10. package/docs/.nojekyll +0 -0
  11. package/docs-tutorials/Events.md +57 -0
  12. package/docs-tutorials/Queries.md +50 -0
  13. package/fonts/Rubik/OFL.txt +93 -0
  14. package/fonts/Rubik/README.txt +77 -0
  15. package/fonts/Rubik/Rubik-Italic-VariableFont_wght.ttf +0 -0
  16. package/fonts/Rubik/Rubik-VariableFont_wght.ttf +0 -0
  17. package/fonts/Rubik/static/Rubik-Black.ttf +0 -0
  18. package/fonts/Rubik/static/Rubik-BlackItalic.ttf +0 -0
  19. package/fonts/Rubik/static/Rubik-Bold.ttf +0 -0
  20. package/fonts/Rubik/static/Rubik-BoldItalic.ttf +0 -0
  21. package/fonts/Rubik/static/Rubik-ExtraBold.ttf +0 -0
  22. package/fonts/Rubik/static/Rubik-ExtraBoldItalic.ttf +0 -0
  23. package/fonts/Rubik/static/Rubik-Italic.ttf +0 -0
  24. package/fonts/Rubik/static/Rubik-Light.ttf +0 -0
  25. package/fonts/Rubik/static/Rubik-LightItalic.ttf +0 -0
  26. package/fonts/Rubik/static/Rubik-Medium.ttf +0 -0
  27. package/fonts/Rubik/static/Rubik-MediumItalic.ttf +0 -0
  28. package/fonts/Rubik/static/Rubik-Regular.ttf +0 -0
  29. package/fonts/Rubik/static/Rubik-SemiBold.ttf +0 -0
  30. package/fonts/Rubik/static/Rubik-SemiBoldItalic.ttf +0 -0
  31. package/index.html +25 -0
  32. package/index.js +11 -0
  33. package/jsconf.json +14 -0
  34. package/lib/assets/fonts/Rubik-Medium.fnt +297 -0
  35. package/lib/assets/fonts/Rubik-Medium.png +0 -0
  36. package/lib/assets/fonts/bmpfonts.in.js +16 -0
  37. package/lib/assets/fonts/bmpfonts.js +9 -0
  38. package/lib/assets/fonts/font.js +82 -0
  39. package/lib/assets/fonts/index.js +14 -0
  40. package/lib/assets/fonts/threebmfont.js +28 -0
  41. package/lib/data.js +125 -0
  42. package/lib/formats/cell.js +114 -0
  43. package/lib/formats/cif.js +22 -0
  44. package/lib/formats/magres.js +337 -0
  45. package/lib/formats/xyz.js +124 -0
  46. package/lib/loader.js +87 -0
  47. package/lib/model.js +2076 -0
  48. package/lib/modelview.js +382 -0
  49. package/lib/nmrdata.js +2898 -0
  50. package/lib/orbit.js +1233 -0
  51. package/lib/primitives/atoms.js +261 -0
  52. package/lib/primitives/cell.js +160 -0
  53. package/lib/primitives/dither.js +156 -0
  54. package/lib/primitives/ellipsoid.js +183 -0
  55. package/lib/primitives/geometries.js +20 -0
  56. package/lib/primitives/index.js +48 -0
  57. package/lib/primitives/isosurface.js +171 -0
  58. package/lib/primitives/shapes.js +100 -0
  59. package/lib/primitives/sprites.js +172 -0
  60. package/lib/query.js +158 -0
  61. package/lib/render.js +440 -0
  62. package/lib/selbox.js +361 -0
  63. package/lib/shaders/aura.frag +26 -0
  64. package/lib/shaders/aura.vert +37 -0
  65. package/lib/shaders/dither.frag +42 -0
  66. package/lib/shaders/dither.vert +8 -0
  67. package/lib/shaders/index.in.js +17 -0
  68. package/lib/shaders/index.js +25 -0
  69. package/lib/shaders/msdf300.frag +25 -0
  70. package/lib/shaders/msdf300.vert +45 -0
  71. package/lib/tensor.js +227 -0
  72. package/lib/utils.js +168 -0
  73. package/lib/visualizer.js +480 -0
  74. package/package.json +106 -0
  75. package/scripts/build-bundle.js +17 -0
  76. package/scripts/build-fonts.js +43 -0
  77. package/scripts/build-resources.js +46 -0
  78. package/scripts/plugins-shim.js +10 -0
  79. package/test/chemdata.js +69 -0
  80. package/test/data/CHA.cif +74 -0
  81. package/test/data/H2O.xyz +8 -0
  82. package/test/data/H2_bound.xyz +4 -0
  83. package/test/data/ethanol.cell +25 -0
  84. package/test/data/ethanol.magres +238 -0
  85. package/test/data/example_single.cif +789 -0
  86. package/test/data/frac.cell +8 -0
  87. package/test/data/org.cif +427 -0
  88. package/test/data/pyridine.xyz +13 -0
  89. package/test/data/si8.xyz +10 -0
  90. package/test/loader.js +107 -0
  91. package/test/model.js +368 -0
  92. package/test/query.js +135 -0
  93. package/test/tensor.js +133 -0
  94. package/test/test-html/examples.js +1485 -0
  95. package/test/test-html/index.html +33 -0
  96. package/test/test-html/index.js +279 -0
  97. package/tools/compile_colors.py +120 -0
  98. package/tools/compile_periodic.py +96 -0
  99. package/tools/ptable.json +497 -0
  100. package/tools/test +5844 -0
@@ -0,0 +1,261 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @fileoverview Classes for Atom and Bond primitives
5
+ */
6
+
7
+ import _ from 'lodash';
8
+ import * as THREE from 'three';
9
+ import {
10
+ unitSphere,
11
+ unitCylinder,
12
+ unitCircle
13
+ } from './geometries.js';
14
+ import * as Shaders from '../shaders/index.js';
15
+
16
+ // Basic materials
17
+ const _phong = new THREE.MeshPhongMaterial({});
18
+
19
+ class AtomMesh extends THREE.Mesh {
20
+
21
+ /**
22
+ * Constructor for the AtomMesh object
23
+ *
24
+ * @param {Array} position Position of the atom
25
+ * @param {Number} radius Radius of the atom
26
+ * @param {Number} color Color of the atom (hex number)
27
+ */
28
+ constructor(position, radius = 1, color = 0xffffff) {
29
+
30
+ var mat = _phong.clone();
31
+ mat.color = new THREE.Color(color);
32
+
33
+ super(unitSphere, mat);
34
+
35
+ this.scale.set(radius, radius, radius);
36
+ this.position.set(position[0], position[1], position[2]);
37
+ this.image = null;
38
+
39
+ }
40
+
41
+ get atom_radius() {
42
+ return this.geometry.parameters.radius * this.scale.x;
43
+ }
44
+
45
+ set atom_radius(r) {
46
+ var s = r / this.geometry.parameters.radius;
47
+ this.scale.set(s, s, s);
48
+ }
49
+
50
+ get atom_color() {
51
+ return this.material.color.getHex();
52
+ }
53
+
54
+ set atom_color(c) {
55
+ this.material.color = new THREE.Color(c);
56
+ this.needsUpdate = true;
57
+ }
58
+
59
+ get atom_opacity() {
60
+ return this.material.opacity;
61
+ }
62
+
63
+ set atom_opacity(o) {
64
+ this.material.transparent = (o < 1);
65
+ this.material.opacity = o;
66
+ this.needsUpdate = true;
67
+ }
68
+
69
+ }
70
+
71
+ class BondMesh extends THREE.Group {
72
+
73
+ /**
74
+ * Constructor for the BondMesh object
75
+ *
76
+ * @param {Array} p0 Position of the first atom
77
+ * @param {Array} p1 Position of the second atom
78
+ * @param {Number} radius Radius of the bond
79
+ * @param {Number} color0 Color of the first atom (hex number)
80
+ * @param {Number} color1 Color of the second atom (hex number)
81
+ */
82
+ constructor(p0, p1, radius = 1, color0 = 0xff0000, color1 = 0x00ff00) {
83
+
84
+ super();
85
+
86
+ p0 = new THREE.Vector3(p0[0], p0[1], p0[2]);
87
+ p1 = new THREE.Vector3(p1[0], p1[1], p1[2]);
88
+
89
+ var dp = p1.clone();
90
+ dp.sub(p0);
91
+ var l = dp.length();
92
+
93
+ // Halfpoint?
94
+ var hv = p0.clone();
95
+ hv.addScaledVector(dp, 0.5);
96
+
97
+ var rmat = new THREE.Matrix4();
98
+ rmat.lookAt(p0, p1, new THREE.Vector3(0, 0, 1));
99
+
100
+ var mat0 = _phong.clone();
101
+ mat0.color = new THREE.Color(color0);
102
+ var mat1 = _phong.clone();
103
+ mat1.color = new THREE.Color(color1);
104
+
105
+ var bond0 = new THREE.Mesh(unitCylinder, mat0);
106
+ bond0.scale.set(radius, radius, l / 2.0);
107
+ bond0.position.copy(p0.clone().addScaledVector(dp, 0.25));
108
+ bond0.setRotationFromMatrix(rmat);
109
+ var bond1 = new THREE.Mesh(unitCylinder, mat1);
110
+ bond1.scale.set(radius, radius, l / 2.0);
111
+ bond1.position.copy(p1.clone().addScaledVector(dp, -0.25));
112
+ bond1.setRotationFromMatrix(rmat);
113
+
114
+ this.add(bond0);
115
+ this.add(bond1);
116
+ }
117
+
118
+ get bond_radius() {
119
+ return this.children[0].geometry.parameters.radiusTop * this.children[0].scale.x;
120
+ }
121
+
122
+ set bond_radius(r) {
123
+ var r0 = this.children[0].geometry.parameters.radiusTop;
124
+ var s = r / r0;
125
+ var z = this.children[0].scale.z;
126
+ this.children[0].scale.set(s, s, z);
127
+ this.children[1].scale.set(s, s, z);
128
+ }
129
+
130
+ get bond_color_1() {
131
+ return this.children[0].material.color.getHex();
132
+ }
133
+
134
+ set bond_color_1(c) {
135
+ this.children[0].material.color = new THREE.Color(c);
136
+ }
137
+
138
+ get bond_color_2() {
139
+ return this.children[1].material.color.getHex();
140
+ }
141
+
142
+ set bond_color_2(c) {
143
+ this.children[1].material.color = new THREE.Color(c);
144
+ }
145
+
146
+ get bond_opacity_1() {
147
+ return this.children[0].material.opacity;
148
+ }
149
+
150
+ set bond_opacity_1(o) {
151
+ this.children[0].material.transparent = (o < 1);
152
+ this.children[0].material.opacity = o;
153
+ this.children[0].material.needsUpdate = true;
154
+ }
155
+
156
+ get bond_opacity_2() {
157
+ return this.children[1].material.opacity;
158
+ }
159
+
160
+ set bond_opacity_2(o) {
161
+ this.children[1].material.transparent = (o < 1);
162
+ this.children[1].material.opacity = o;
163
+ this.children[1].material.needsUpdate = true;
164
+ }
165
+
166
+ }
167
+
168
+ class AuraMesh extends THREE.Mesh {
169
+
170
+ constructor(parameters = {}) {
171
+
172
+ var defaults = {
173
+ scale: 1,
174
+ radius: 1,
175
+ fill: 0xaaaa00,
176
+ border: 0xffff00,
177
+ opacity: 0.5,
178
+ borderFraction: 0.08
179
+ };
180
+
181
+ parameters = _.merge(defaults, parameters);
182
+
183
+ var mat = new THREE.RawShaderMaterial({
184
+ uniforms: {
185
+ targScale: new THREE.Uniform(parameters.scale),
186
+ targRadius: new THREE.Uniform(parameters.radius),
187
+ fill: new THREE.Uniform(new THREE.Color(parameters.fill)),
188
+ border: new THREE.Uniform(new THREE.Color(parameters.border)),
189
+ border_f: new THREE.Uniform(parameters.borderFraction),
190
+ opacity: new THREE.Uniform(parameters.opacity)
191
+ },
192
+ side: THREE.DoubleSide,
193
+ transparent: true,
194
+ vertexShader: Shaders.auraVertShader,
195
+ fragmentShader: Shaders.auraFragShader
196
+ });
197
+
198
+ super(unitCircle, mat);
199
+
200
+ }
201
+
202
+ get scale() {
203
+ return this.material.uniforms.targScale.value;
204
+ }
205
+
206
+ set scale(s) {
207
+ this.material.uniforms.targScale.value = s;
208
+ this.material.uniformsNeedUpdate = true;
209
+ }
210
+
211
+ get radius() {
212
+ return this.material.uniforms.targRadius.value;
213
+ }
214
+
215
+ set radius(r) {
216
+ this.material.uniforms.targRadius.value = r;
217
+ this.material.uniformsNeedUpdate = true;
218
+ }
219
+
220
+ get fill() {
221
+ return this.material.uniforms.fill.value.getHex();
222
+ }
223
+
224
+ set fill(c) {
225
+ this.material.uniforms.fill.value = new THREE.Color(c);
226
+ this.material.uniformsNeedUpdate = true;
227
+ }
228
+
229
+ get border() {
230
+ return this.material.uniforms.border.value.getHex();
231
+ }
232
+
233
+ set border(c) {
234
+ this.material.uniforms.border.value = new THREE.Color(c);
235
+ this.material.uniformsNeedUpdate = true;
236
+ }
237
+
238
+ get borderFraction() {
239
+ return this.material.uniforms.border_f.value;
240
+ }
241
+
242
+ set borderFraction(f) {
243
+ this.material.uniforms.border_f.value = f;
244
+ this.material.uniformsNeedUpdate = true;
245
+ }
246
+
247
+ get opacity() {
248
+ return this.material.uniforms.opacity.value;
249
+ }
250
+
251
+ set opacity(o) {
252
+ this.material.uniforms.opacity.value = o;
253
+ this.material.uniformsNeedUpdate = true;
254
+ }
255
+ }
256
+
257
+ export {
258
+ AtomMesh,
259
+ BondMesh,
260
+ AuraMesh
261
+ };
@@ -0,0 +1,160 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @fileoverview Classes for lattice box primitives
5
+ */
6
+
7
+ import _ from 'lodash';
8
+ import * as THREE from 'three';
9
+ import { Vector3 } from 'three';
10
+ import { cellMatrix3 } from '../utils.js';
11
+
12
+ // Cell box
13
+ class BoxMesh extends THREE.LineSegments {
14
+
15
+ /**
16
+ * Constructor for BoxMesh primitive
17
+ *
18
+ * @param {Array} lattice Lattice parameters for the unit cell
19
+ * @param {Object} parameters Options:
20
+ * color
21
+ *
22
+ */
23
+ constructor(lattice, parameters = {}) {
24
+
25
+ const defaults = {
26
+ color: 0xffffff,
27
+ }
28
+
29
+ parameters = _.merge(defaults, parameters);
30
+
31
+ if (lattice instanceof Array) {
32
+ lattice = cellMatrix3(lattice);
33
+ }
34
+
35
+ var boxGeom = new THREE.BoxGeometry(1, 1, 1);
36
+ boxGeom = new THREE.EdgesGeometry(boxGeom); // Convert to wireframe
37
+
38
+ var boxMat = new THREE.LineBasicMaterial({
39
+ color: parameters.color,
40
+ });
41
+
42
+ super(boxGeom, boxMat);
43
+
44
+ // Set the actual lattice basis
45
+ this.matrix.setFromMatrix3(lattice);
46
+ this.matrix.setPosition( (new Vector3(0.5, 0.5, 0.5)).applyMatrix3(lattice) );
47
+ this.matrixAutoUpdate = false;
48
+ }
49
+
50
+ get color() {
51
+ return this.material.color.getHex();
52
+ }
53
+
54
+ set color(c) {
55
+ this.material.color = new THREE.Color(c);
56
+ this.needsUpdate = true;
57
+ }
58
+
59
+
60
+ }
61
+
62
+ // Arrows for axes
63
+ class AxesMesh extends THREE.Group {
64
+
65
+ /**
66
+ * Constructor for AxesMesh primitive
67
+ *
68
+ * @param {Array} lattice Lattice parameters for the unit cell
69
+ * @param {Object} parameters Options:
70
+ * linewidth
71
+ * xColor
72
+ * yColor
73
+ * zColor
74
+ *
75
+ */
76
+ constructor(lattice, parameters = {}) {
77
+
78
+ var defaults = {
79
+ linewidth: 1.2,
80
+ xColor: 0xff0000,
81
+ yColor: 0x00ff00,
82
+ zColor: 0x0000ff
83
+ };
84
+
85
+ parameters = _.merge(defaults, parameters);
86
+
87
+ super();
88
+
89
+ if (lattice instanceof Array) {
90
+ var lc = lattice;
91
+ lattice = new THREE.Matrix3();
92
+ lattice.set(lc[0][0], lc[1][0], lc[2][0],
93
+ lc[0][1], lc[1][1], lc[2][1],
94
+ lc[0][2], lc[1][2], lc[2][2]);
95
+ }
96
+
97
+ var origin = new THREE.Vector3(0, 0, 0);
98
+ var elems = lattice.elements;
99
+
100
+ var colors = [
101
+ parameters.xColor,
102
+ parameters.yColor,
103
+ parameters.zColor
104
+ ];
105
+
106
+ for (var i = 0; i < 3; ++i) {
107
+ var dir = new THREE.Vector3(elems[3 * i],
108
+ elems[3 * i + 1],
109
+ elems[3 * i + 2]);
110
+ var l = dir.length() / 3.0;
111
+ dir.normalize();
112
+ var arr = new THREE.ArrowHelper(dir, origin, l, colors[i]);
113
+ arr.line.material.linewidth = parameters.linewidth;
114
+ this.add(arr);
115
+ }
116
+ }
117
+
118
+ get xColor() {
119
+ return this.children[0].line.material.color.getHex();
120
+ }
121
+
122
+ set xColor(c) {
123
+ this.children[0].line.material.color = new THREE.Color(c);
124
+ this.children[0].cone.material.color = new THREE.Color(c);
125
+ }
126
+
127
+ get yColor() {
128
+ return this.children[1].line.material.color.getHex();
129
+ }
130
+
131
+ set yColor(c) {
132
+ this.children[1].line.material.color = new THREE.Color(c);
133
+ this.children[1].cone.material.color = new THREE.Color(c);
134
+ }
135
+
136
+ get zColor() {
137
+ return this.children[2].line.material.color.getHex();
138
+ }
139
+
140
+ set zColor(c) {
141
+ this.children[2].line.material.color = new THREE.Color(c);
142
+ this.children[2].cone.material.color = new THREE.Color(c);
143
+ }
144
+
145
+ get linewidth() {
146
+ return this.children[0].line.material.linewidth;
147
+ }
148
+
149
+ set linewidth(lw) {
150
+ for (var i = 0; i < 3; ++i) {
151
+ this.children[i].line.material.linewidth = lw;
152
+ }
153
+ }
154
+
155
+ }
156
+
157
+ export {
158
+ BoxMesh,
159
+ AxesMesh
160
+ };
@@ -0,0 +1,156 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @fileoverview Functions for a dithering-based transparent material
5
+ * @module
6
+ */
7
+
8
+ import _ from 'lodash';
9
+ import * as THREE from 'three';
10
+ import * as Shaders from '../shaders/index.js';
11
+
12
+ /**
13
+ * Recursive function to generate a power-of-two ordered dithering matrix
14
+ *
15
+ * @param {int} n Power of two index. The returned matrix will have a 2^n side.
16
+ */
17
+ function makeDitherMatrix(n) {
18
+ var dM2 = [0., 0.5, 0.75, 0.25];
19
+ if (n <= 1) {
20
+ return dM2;
21
+ } else {
22
+ var M1 = [];
23
+ var M0 = makeDitherMatrix(n - 1);
24
+ var N0 = Math.pow(2, n - 1);
25
+ var N1 = Math.pow(2, n);
26
+ var N02 = Math.pow(2, 2 * n - 2);
27
+ var N12 = Math.pow(2, 2 * n);
28
+ for (var i = 0; i < N12; ++i) {
29
+ var x1 = i % N1;
30
+ var y1 = Math.floor(i / N1);
31
+ var x2 = Math.floor(x1 / N0);
32
+ var y2 = Math.floor(y1 / N0);
33
+ var v = M0[x1 % N0 + (y1 % N0) * N0] + dM2[x2 + 2 * y2] / N02;
34
+ M1.push(v);
35
+ }
36
+ return M1;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Generate an ordered dithering matrix in the form of a THREE.js DataTexture
42
+ *
43
+ * @param {int} n Power of two index. The returned matrix will have a 2^n side.
44
+ */
45
+ function makeDitherTexture(n) {
46
+ // n is the power of two exponent
47
+ var N = Math.pow(2, n);
48
+ var dM = makeDitherMatrix(n);
49
+ dM = dM.map(function(x) {
50
+ return Math.floor((x + 0.5 / (N * N)) * 256);
51
+ });
52
+ dM = new Uint8Array(dM);
53
+
54
+ var tx = new THREE.DataTexture(dM, N, N, THREE.RedFormat);
55
+ tx.needsUpdate = true;
56
+
57
+ return tx;
58
+ }
59
+
60
+ /**
61
+ * Generate a pseudorandom shift for the dither texture. Designed to ensure
62
+ * reproducibility given a float seed
63
+ *
64
+ * @param {int} N Size of texture
65
+ * @param {float} seed Seed number used to generate the shift
66
+ */
67
+ function rndShift(N, seed) {
68
+ var a = 349588123;
69
+ var b = 123958341;
70
+ var sx = Math.pow(Math.sin(a*seed+b), 2)*N;
71
+ var sy = Math.pow(Math.cos(b*seed+a), 2)*N;
72
+ return new THREE.Vector2(sx, sy);
73
+ }
74
+
75
+ class DitherMaterial extends THREE.ShaderMaterial {
76
+
77
+ /**
78
+ * Initialise a DitherMaterial, a material that offers transparency with a
79
+ * dithering method (and thus meshes better when multiple transparent
80
+ * surfaces are overlapping).
81
+ *
82
+ * @param {Object} parameters Options:
83
+ * - color
84
+ * - opacity
85
+ * - illumination
86
+ * - n (controls the size of the dither texture, mostly can be left alone)
87
+ * - netting (if true, uses a different dithering system, applying object instead of screen
88
+ * coordinates)
89
+ * - netScale (scaling factor for the object coordinates; only used if netting = true)
90
+ */
91
+ constructor(parameters = {}) {
92
+
93
+ var defaults = {
94
+ color: 0xffffff,
95
+ opacity: 0.5,
96
+ illumination: 0.5,
97
+ n: 5,
98
+ netting: false,
99
+ netScale: 5.0,
100
+ shiftSeed: null
101
+ };
102
+
103
+
104
+ parameters = _.merge(defaults, parameters);
105
+
106
+ // Safety check to avoid completely bricking the user's memory
107
+ var n = Math.min(parameters.n, 10); // This way ditherTex will never be bigger than 1024x1024
108
+ var N = Math.pow(2, n);
109
+ var shift = rndShift(N, (parameters.shiftSeed == null? Math.random() : parameters.shiftSeed));
110
+ var ditherTex = makeDitherTexture(n);
111
+
112
+ super({
113
+ uniforms: {
114
+ color: new THREE.Uniform(new THREE.Color(parameters.color)),
115
+ opacity: new THREE.Uniform(parameters.opacity),
116
+ illum: new THREE.Uniform(parameters.illumination),
117
+ shift: new THREE.Uniform(shift),
118
+ ditherN: new THREE.Uniform(N),
119
+ ditherTex: new THREE.Uniform(ditherTex),
120
+ netting: new THREE.Uniform(parameters.netting),
121
+ netScale: new THREE.Uniform(parameters.netScale),
122
+ },
123
+ fragmentShader: Shaders.ditherFragShader,
124
+ vertexShader: Shaders.ditherVertShader,
125
+ depthTest: true,
126
+ });
127
+
128
+ this.side = THREE.DoubleSide;
129
+ }
130
+
131
+ get color() {
132
+ return this.uniforms.color.value.getHex();
133
+ }
134
+
135
+ set color(c) {
136
+ this.uniforms.color.value = new THREE.Color(c);
137
+ this.uniformsNeedUpdate = true;
138
+ }
139
+
140
+ get opacity() {
141
+ return this.uniforms.opacity.value;
142
+ }
143
+
144
+ set opacity(o) {
145
+ if (this.uniforms) {
146
+ // This check is necessary since we're overriding the original
147
+ // property, otherwise we get an error when calling super()
148
+ this.uniforms.opacity.value = o;
149
+ this.uniformsNeedUpdate = true;
150
+ }
151
+ }
152
+ }
153
+
154
+ export {
155
+ DitherMaterial
156
+ };