forked from simon-budig/shadertoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
getshader.py
executable file
·111 lines (94 loc) · 3.56 KB
/
getshader.py
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
#!/usr/bin/env python3
# Standalone Shadertoy
# Copyright (C) 2014 Simon Budig <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys, json, urllib.request, urllib.parse
shaderinfo = """\
// Shader downloaded from https://www.shadertoy.com/view/%(id)s
// written by shadertoy user %(username)s
//
// Name: %(name)s
// Description: %(description)s
"""
shaderdecls = """
uniform vec3 iResolution; // viewport resolution (in pixels)
uniform float iGlobalTime; // shader playback time (in seconds)
uniform float iChannelTime[4]; // channel playback time (in seconds)
uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)
uniform vec4 iMouse; // mouse pixel coords. xy: current (if MLB down), zw: click
uniform sampler2D iChannel0; // input channel. XX = 2D/Cube
uniform sampler2D iChannel1; // input channel. XX = 2D/Cube
uniform vec4 iDate; // (year, month, day, time in secs)
uniform float iSampleRate; // sound sample rate (i.e., 44100)
\n"""
# see https://www.shadertoy.com/js/effect.js?v=8
shadermain = """\n
void main (void)
{
vec4 color = vec4 (0.0, 0.0, 0.0, 1.0);
mainImage (color, gl_FragCoord.xy);
color.w = 1.0;
gl_FragColor = color;
}
"""
def get_shader (id):
url = 'https://www.shadertoy.com/shadertoy'
headers = { 'Referer' : 'https://www.shadertoy.com/' }
values = { 's' : json.dumps ({'shaders' : [id]}) }
data = urllib.parse.urlencode (values).encode ('utf-8')
req = urllib.request.Request (url, data, headers)
response = urllib.request.urlopen (req)
shader_json = response.read ().decode ('utf-8')
j = json.loads (shader_json)
f = open ("/tmp/current-shader.json", "w")
f.write (json.dumps (j, indent=2))
f.close ()
assert (len (j) == 1)
for s in j:
name = s["info"]["name"]
desc = s["info"]["description"]
desc = "".join (desc.split("\r"))
desc = "\n// ".join (desc.split("\n"))
s["info"]["description"] = desc
for p in s["renderpass"]:
code = (p["code"])
return name, code, s["info"]
if __name__ == '__main__':
if len (sys.argv) < 2:
print ("Usage: %s <id>" % sys.argv[0], file=sys.stderr)
for id in sys.argv[1:]:
attempt = 0
id = id.split("/")[-1]
name, code, info = get_shader (id)
code = "".join (code.split ("\r"))
f = None
while f == None:
try:
if attempt == 0:
fname = "%s.glsl" % name
else:
fname = "%s.glsl.%d" % (name, attempt)
f = open (fname, "x")
except FileExistsError:
attempt += 1
if attempt > 10:
print ("clean out your files please...", file=sys.stderr)
sys.exit (0)
f.write (shaderinfo % info)
f.write (shaderdecls)
f.write (code)
f.write (shadermain)
f.close ()
print ("wrote shader to \"%s\"" % fname, file=sys.stderr)