Skip to content

Instantly share code, notes, and snippets.

@KrabCode
Last active September 22, 2019 11:20
Show Gist options
  • Select an option

  • Save KrabCode/a4a715e49f08eccfc870f3b383636eb8 to your computer and use it in GitHub Desktop.

Select an option

Save KrabCode/a4a715e49f08eccfc870f3b383636eb8 to your computer and use it in GitHub Desktop.
HotShader.pde
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D texture;
uniform vec2 resolution;
uniform float time;
void main(){
gl_FragColor = vec4(vec3(0.), 1.);
}
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform sampler2D texture;
uniform vec2 resolution;
uniform float time;
void main(){
vec2 uv = gl_FragCoord.xy / resolution;
vec3 col = 0.5 + 0.5*cos(time+uv.xyx+vec3(0,2,4));
gl_FragColor = vec4(col, 1.);
}
import java.io.File;
import java.util.ArrayList;
import static java.lang.System.currentTimeMillis;
public void setup() {
size(800, 800, P3D);
}
public void draw() {
uniform("frag.glsl").set("time", radians(frameCount));
hotFilter("frag.glsl");
hotShader("dark.glsl", "vert.glsl");
translate(width/2, height/2);
rotateY(radians(frameCount));
stroke(255);
box(250);
}
/* The following code can apply shaders on the fly as you change the last changed timestamp of the shader files
* - use uniform() to get a reference to the shader file in order to pass uniforms to it
* - use hotFilter() and hotShader() to apply your last compilable shader as filter or shader respectively
* - no need to call loadShader() manually at all
*
* - to see the effects you have to actually change the last modified timestamp of the file, (try CTRL+S)
* - the results of any compilation errors will be printed to standard processing console
*/
ArrayList<ShaderSnapshot> snapshots = new ArrayList<ShaderSnapshot>();
int refreshRateInMillis = 60;
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 = -refreshRateInMillis;
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 + refreshRateInMillis) {
// 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());
}
}
}
uniform mat4 transform;
attribute vec4 position;
attribute vec4 color;
varying vec4 vertColor;
varying vec4 vertCoord;
void main() {
gl_Position = transform * position;
vertColor = color;
vertCoord = position;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment