Last active
March 29, 2020 14:47
-
-
Save KrabCode/d350549bfc55844e15f1589babb1407f to your computer and use it in GitHub Desktop.
Reload your shaders on the fly with Processing using this code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // put this in the data folder | |
| // when the sketch is running, change something here in a text editor and hit CTRL+S to see the changes | |
| uniform sampler2D texture; | |
| uniform vec2 resolution; | |
| uniform float time; | |
| void main(){ | |
| vec2 uv = (gl_FragCoord.xy-.5*resolution) / resolution.y; | |
| vec3 col = 0.5 + 0.5*cos(time+uv.xyx+vec3(0,2,4)); | |
| gl_FragColor = vec4(col, 1.); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| void setup() { | |
| size(600, 600, P2D); | |
| } | |
| void draw() { | |
| float t = radians(frameCount); | |
| String testShader = "frag.glsl"; | |
| uniform(testShader).set("time", t); | |
| hotFilter(testShader); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import static java.lang.System.currentTimeMillis; | |
| ArrayList<ShaderSnapshot> snapshots = new ArrayList<ShaderSnapshot>(); | |
| int shaderRefreshRateInMillis = 100; | |
| public PShader uniform(String fragPath) { | |
| ShaderSnapshot snapshot = findSnapshotByPath(fragPath); | |
| snapshot = initIfNull(snapshot, fragPath, null); | |
| return snapshot.compiledShader; | |
| } | |
| public PShader uniform(String fragPath, String vertPath) { | |
| ShaderSnapshot snapshot = findSnapshotByPath(fragPath); | |
| snapshot = initIfNull(snapshot, fragPath, vertPath); | |
| return snapshot.compiledShader; | |
| } | |
| public void hotFilter(String path, PGraphics canvas) { | |
| hotShader(path, null, true, canvas); | |
| } | |
| public void hotFilter(String path) { | |
| hotShader(path, null, true, g); | |
| } | |
| public void hotShader(String fragPath, String vertPath, PGraphics canvas) { | |
| hotShader(fragPath, vertPath, false, canvas); | |
| } | |
| public void hotShader(String fragPath, String vertPath) { | |
| hotShader(fragPath, vertPath, false, g); | |
| } | |
| public void hotShader(String fragPath, PGraphics canvas) { | |
| hotShader(fragPath, null, false, canvas); | |
| } | |
| public void hotShader(String fragPath) { | |
| hotShader(fragPath, null, false, g); | |
| } | |
| private void hotShader(String fragPath, String vertPath, boolean filter, PGraphics canvas) { | |
| ShaderSnapshot snapshot = findSnapshotByPath(fragPath); | |
| snapshot = initIfNull(snapshot, fragPath, vertPath); | |
| snapshot.update(filter, canvas); | |
| } | |
| private ShaderSnapshot initIfNull(ShaderSnapshot snapshot, String fragPath, String vertPath) { | |
| if (snapshot == null) { | |
| snapshot = new ShaderSnapshot(fragPath, vertPath); | |
| snapshots.add(snapshot); | |
| } | |
| return snapshot; | |
| } | |
| private ShaderSnapshot findSnapshotByPath(String path) { | |
| for (ShaderSnapshot snapshot : snapshots) { | |
| if (snapshot.fragPath.equals(path)) { | |
| return snapshot; | |
| } | |
| } | |
| return null; | |
| } | |
| private class ShaderSnapshot { | |
| String fragPath; | |
| String vertPath; | |
| File fragFile; | |
| File vertFile; | |
| PShader compiledShader; | |
| long fragLastKnownModified, vertLastKnownModified, lastChecked; | |
| boolean compiledAtLeastOnce = false; | |
| long lastKnownUncompilable = -shaderRefreshRateInMillis; | |
| ShaderSnapshot(String fragPath, String vertPath) { | |
| if (vertPath != null) { | |
| compiledShader = loadShader(fragPath, vertPath); | |
| vertFile = dataFile(vertPath); | |
| vertLastKnownModified = vertFile.lastModified(); | |
| if (!vertFile.isFile()) { | |
| println("Could not find shader at " + vertFile.getPath()); | |
| } | |
| } else { | |
| compiledShader = loadShader(fragPath); | |
| } | |
| fragFile = dataFile(fragPath); | |
| fragLastKnownModified = fragFile.lastModified(); | |
| lastChecked = currentTimeMillis(); | |
| if (!fragFile.isFile()) { | |
| println("Could not find shader at " + fragFile.getPath()); | |
| } | |
| this.fragPath = fragPath; | |
| this.vertPath = vertPath; | |
| } | |
| long max(long a, long b) { | |
| if (a > b) { | |
| return a; | |
| } | |
| return b; | |
| } | |
| void update(boolean filter, PGraphics pg) { | |
| long currentTimeMillis = currentTimeMillis(); | |
| long lastModified = fragFile.lastModified(); | |
| if (vertFile != null) { | |
| lastModified = max(lastModified, vertFile.lastModified()); | |
| } | |
| if (compiledAtLeastOnce && currentTimeMillis < lastChecked + shaderRefreshRateInMillis) { | |
| // println("compiled at least once, not checking, standard apply"); | |
| applyShader(compiledShader, filter, pg); | |
| return; | |
| } | |
| if (!compiledAtLeastOnce && lastModified > lastKnownUncompilable) { | |
| // println("first try"); | |
| tryCompileNewVersion(filter, pg, lastModified); | |
| return; | |
| } | |
| lastChecked = currentTimeMillis; | |
| if (lastModified > fragLastKnownModified && lastModified > lastKnownUncompilable) { | |
| // println("file changed, repeat try"); | |
| tryCompileNewVersion(filter, pg, lastModified); | |
| } else if (compiledAtLeastOnce) { | |
| // println("file didn't change, standard apply"); | |
| applyShader(compiledShader, filter, pg); | |
| } | |
| } | |
| private void applyShader(PShader shader, boolean filter, PGraphics pg) { | |
| if (filter) { | |
| pg.filter(shader); | |
| } else { | |
| pg.shader(shader); | |
| } | |
| } | |
| private void tryCompileNewVersion(boolean filter, PGraphics pg, long lastModified) { | |
| try { | |
| PShader candidate; | |
| if (vertFile == null) { | |
| candidate = loadShader(fragPath); | |
| } else { | |
| candidate = loadShader(fragPath, vertPath); | |
| } | |
| // we need to call filter() or shader() here in order to catch any compilation errors and not halt | |
| // the sketch | |
| applyShader(candidate, filter, pg); | |
| compiledShader = candidate; | |
| compiledAtLeastOnce = true; | |
| fragLastKnownModified = lastModified; | |
| } | |
| catch (Exception ex) { | |
| lastKnownUncompilable = lastModified; | |
| println("\n" + fragFile.getName() + ": " + ex.getMessage()); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment