Skip to content

Commit f8555b0

Browse files
author
Luigi De Rosa
committed
Initial commit
1 parent 1cde121 commit f8555b0

File tree

6 files changed

+234
-0
lines changed

6 files changed

+234
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
package-lock.json
3+
.cache
4+
dist/

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,9 @@
22
🔮 Tiny helper for three.js to debug and write shaders
33

44
Coming soon...
5+
6+
/*
7+
todo:
8+
- support spector reload
9+
- inspect/edit threejs default uniforms
10+
*/

example/example.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {
2+
Scene,
3+
Mesh,
4+
PerspectiveCamera,
5+
WebGLRenderer,
6+
BoxBufferGeometry,
7+
RawShaderMaterial,
8+
} from 'three';
9+
10+
import MagicShader from '../index';
11+
12+
const renderer = new WebGLRenderer();
13+
renderer.setSize(window.innerWidth, window.innerHeight);
14+
document.body.appendChild(renderer.domElement);
15+
16+
const scene = new Scene();
17+
const camera = new PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
18+
camera.position.z = 1;
19+
20+
const geometry = new BoxBufferGeometry(.2, .2, .2);
21+
const material = new MagicShader({
22+
vertexShader: `
23+
precision highp float;
24+
25+
attribute vec3 position;
26+
uniform mat4 modelViewMatrix;
27+
uniform mat4 projectionMatrix;
28+
29+
void main() {
30+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
31+
}
32+
`,
33+
fragmentShader: `
34+
precision highp float;
35+
36+
uniform vec3 color; // ms({ value: '#ff0000' })
37+
38+
void main() {
39+
gl_FragColor = vec4(color, 1.0);
40+
}
41+
`
42+
});
43+
44+
const mesh = new Mesh(geometry, material);
45+
scene.add(mesh);
46+
47+
function animate() {
48+
requestAnimationFrame(animate);
49+
50+
mesh.rotation.x += 0.01;
51+
mesh.rotation.y += 0.01;
52+
53+
renderer.render(scene, camera);
54+
}
55+
56+
animate();

example/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<html>
2+
<head>
3+
<style>
4+
html, body {
5+
margin: 0;
6+
padding: 0;
7+
}
8+
</style>
9+
</head>
10+
<body>
11+
<script src="./example.js"></script>
12+
</body>
13+
</html>

index.js

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import { RawShaderMaterial, Color } from 'three';
2+
import * as dat from 'dat.gui';
3+
4+
const magicUniformsToThree = uniforms => {
5+
const r = {};
6+
7+
for (const k in uniforms) {
8+
const uniform = uniforms[k];
9+
let value = uniforms[k].json.value;
10+
11+
if (uniform.type === 'bool') {
12+
value = !!value;
13+
}
14+
15+
if (typeof value === 'string') {
16+
value = new Color(value);
17+
}
18+
19+
r[k] = { value };
20+
}
21+
22+
return r;
23+
};
24+
25+
const parseShaders = (vertex, fragment) => {
26+
const vertexUniforms = parseGLSL(vertex);
27+
const fragmentUniforms = parseGLSL(fragment);
28+
29+
return {
30+
...vertexUniforms,
31+
...fragmentUniforms,
32+
};
33+
};
34+
35+
const parseGLSL = source => {
36+
const lines = source.match(/uniform (.+?) (.+?);.+\/\/.+ms\((.+?)\)/gm);
37+
38+
if (!lines) {
39+
return {};
40+
}
41+
42+
const uniforms = {};
43+
44+
lines.forEach(line => {
45+
const [, type, name, jsonString] = line.match(/uniform (.+?) (.+?);.+\/\/.+ms\((.+?)\)/);
46+
let json = {};
47+
48+
try {
49+
eval(`json = ${jsonString}`);
50+
} catch (e) {
51+
throw new Error(e);
52+
}
53+
54+
if (!json.value) {
55+
json.value = 0;
56+
}
57+
58+
uniforms[name] = {
59+
name,
60+
type,
61+
json,
62+
};
63+
});
64+
65+
return uniforms;
66+
};
67+
68+
const gui = new dat.GUI({
69+
name: 'MagicShader',
70+
});
71+
72+
let id = 0;
73+
74+
class MagicShader extends RawShaderMaterial {
75+
constructor(params) {
76+
const magicUniforms = parseShaders(params.vertexShader, params.fragmentShader);
77+
78+
params.uniforms = {
79+
...magicUniformsToThree(magicUniforms),
80+
...params.uniforms,
81+
};
82+
83+
super(params);
84+
85+
this.params = params;
86+
this.magicUniforms = magicUniforms;
87+
88+
this.bindUI();
89+
}
90+
91+
bindUI() {
92+
this.gui = gui.addFolder(this.params.name || `Shader n. ${++id}`);
93+
94+
Object.keys(this.magicUniforms).forEach(key => {
95+
const magicUniform = this.magicUniforms[key];
96+
const magicJson = magicUniform.json;
97+
const uniform = this.uniforms[key];
98+
const folder = this.gui.addFolder(magicJson.name || `🔮 ${magicUniform.type} - ${key}`);
99+
100+
101+
if (uniform.value instanceof Color) {
102+
const add = folder.addColor(magicJson, 'value').onChange(res => {
103+
uniform.value.set(res);
104+
});
105+
} else if (Array.isArray(magicJson.value)) {
106+
Object.keys(uniform.value).forEach(index => {
107+
const add = folder.add(uniform.value, index);
108+
109+
magicJson.step && add.step(magicJson.step);
110+
111+
if (magicJson.range && magicJson.range[index] && magicJson.range[index].length === 2) {
112+
add.min(magicJson.range[index][0]);
113+
add.max(magicJson.range[index][1]);
114+
}
115+
});
116+
} else {
117+
const add = folder.add(uniform, 'value');
118+
119+
magicJson.step && add.step(magicJson.step);
120+
magicJson.options && add.options(magicJson.options);
121+
122+
if (magicJson.range && magicJson.range.length === 2) {
123+
add.min(magicJson.range[0]);
124+
add.max(magicJson.range[1]);
125+
}
126+
}
127+
});
128+
}
129+
}
130+
131+
export { gui };
132+
export default MagicShader;

package.json

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "magicshader",
3+
"version": "0.1.0",
4+
"description": "🔮 Tiny helper for three.js to debug and write shaders",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/luruke/magicshader.git"
12+
},
13+
"author": "luruke",
14+
"license": "MIT",
15+
"bugs": {
16+
"url": "https://github.com/luruke/magicshader/issues"
17+
},
18+
"homepage": "https://github.com/luruke/magicshader#readme",
19+
"dependencies": {
20+
"dat.gui": "^0.7.6",
21+
"three": "^0.103.0"
22+
}
23+
}

0 commit comments

Comments
 (0)