Last active
July 8, 2016 15:57
-
-
Save hageldave/bae62f5abeb6fa6c69cec944245f4e3d to your computer and use it in GitHub Desktop.
mini shader (scalar field vis)
This file contains 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 java.awt.Color; | |
import java.awt.Graphics; | |
import java.awt.image.BufferedImage; | |
import java.io.IOException; | |
import java.net.URL; | |
import java.util.Random; | |
import java.util.function.BiConsumer; | |
import javax.swing.JFrame; | |
import javax.swing.JPanel; | |
import javax.swing.SwingUtilities; | |
import hageldave.imagingkit.core.BufferedImageFactory; | |
import hageldave.imagingkit.core.ImageLoader; | |
import hageldave.imagingkit.core.Img; | |
import hageldave.imagingkit.core.Pixel; | |
public class testmain { | |
public static void main(String[] args) throws InterruptedException { | |
// BiConsumer<Pixel, Long> shader = (px, time)->{ | |
// px.setRGB( | |
// (int)(px.getXnormalized()*255)+(int)((time/10)%255), | |
// (int)(px.getYnormalized()*255), | |
// (int)(px.getYnormalized()*255)); | |
// ColorSpaceTransformation.HSV_2_RGB.get().accept(px); | |
// }; | |
BiConsumer<Pixel, Long> shader = getShader(); | |
Img img = new Img(256, 256); | |
BufferedImage bimg = img.getRemoteBufferedImage(); | |
JPanel canvas = new JPanel(){ public void paint(Graphics g) { | |
long now = System.currentTimeMillis(); | |
img.forEachParallel(px->{shader.accept(px, now);}); | |
g.drawImage(bimg, 0,0,getWidth(),getHeight(), 0,0,img.getWidth(),img.getHeight(), null); | |
String shaderTime = String.format("%02dms",System.currentTimeMillis()-now); | |
g.drawString(shaderTime, 2, getHeight()); g.setColor(Color.white); | |
g.drawString(shaderTime, 1, getHeight()-1); | |
}}; | |
canvas.setPreferredSize(img.getDimension()); | |
JFrame f = new JFrame("IMG"); f.setContentPane(canvas); | |
f.pack(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
SwingUtilities.invokeLater(()->{f.setVisible(true);}); | |
final long fpsLimitTime = 1000/25; // 25fps | |
long target = System.currentTimeMillis()+fpsLimitTime; | |
while(true){ | |
long now = System.currentTimeMillis(); | |
canvas.repaint(); | |
Thread.sleep(Math.max(0, target-now)); | |
target = now+fpsLimitTime; | |
} | |
} | |
static BiConsumer<Pixel, Long> getShader() { | |
return (px, time)-> { | |
int w = px.getImg().getWidth(); | |
int h = px.getImg().getHeight(); | |
float x = ((px.getX())-w/2); | |
float y = ((px.getY())-h/2); | |
float x1 = x+1f; | |
float y1 = y; | |
float x2 = x; | |
float y2 = y+1f; | |
if(true){ | |
float cos = (float) Math.cos(time/3000.0); | |
float sin = (float) Math.sin(time/3000.0); | |
float xRot = x*cos+sin*y; | |
float yRot = -x*sin+cos*y; | |
x = (xRot+w/2); | |
y = (yRot+h/2); | |
xRot = x1*cos+sin*y1; | |
yRot = -x1*sin+cos*y1; | |
x1 = (xRot+w/2); | |
y1 = (yRot+h/2); | |
xRot = x2*cos+sin*y2; | |
yRot = -x2*sin+cos*y2; | |
x2 = (xRot+w/2); | |
y2 = (yRot+h/2); | |
} | |
float s00 = getScalar(x, y, w, h); | |
float s10 = getScalar(x1, y1, w, h); | |
float s01 = getScalar(x2, y2, w, h); | |
float vecA0=1,vecA1=0,vecA2=s10-s00;// = {1,0,s10-s00}; | |
float vecB0=0,vecB1=1,vecB2=s01-s00;// = {0,1,s01-s00}; | |
// cross product | |
float vecC0=vecA1*vecB2-vecB1*vecA2; | |
float vecC1=vecA2*vecB0-vecB2*vecA0; | |
float vecC2=vecA0*vecB1-vecB0*vecA1; | |
// normalize | |
float length = (float) Math.sqrt(vecC0*vecC0+vecC1*vecC1+vecC2*vecC2); | |
vecC0/=(length); | |
vecC1/=(length); | |
vecC2/=(length); | |
vec2pixel(px, vecC0, vecC1, vecC2); | |
}; | |
} | |
static void vec2pixel(Pixel px, float v0, float v1, float v2){ | |
// px.setRGB_fromNormalized(v0/2+0.5f, v1/2+0.5f, v2/2+0.5f); | |
float up = Math.max(0, v2); | |
float right = Math.max(0, v0); | |
float val = Math.min(1,up*right+up+right); | |
px.setRGB_fromNormalized(val,val,val); | |
} | |
static final Img heightmap = getHeightmap(); | |
static float getScalar(float x, float y, int w, int h){ | |
float xf = x/(w); | |
float yf = y/(h); | |
return Pixel.b(heightmap.interpolateARGB(clamp(xf), clamp(yf))); | |
} | |
static float clamp(float f){ | |
return Math.min(1, Math.max(0, f)); | |
} | |
static Img getHeightmap(){ | |
try { | |
// URL url = new URL("https://upload.wikimedia.org/wikipedia/commons/5/57/Heightmap.png"); | |
// URL url = new URL("http://johnflower.org/sites/default/files/tutorial/finding-height-maps-web/lake-taupo-15m-dem.png"); | |
URL url = new URL("http://johnflower.org/sites/default/files/tutorial/finding-height-maps-web/mt-tarawera-15m-dem.png"); | |
return Img.createRemoteImg(BufferedImageFactory.getINT_ARGB(ImageLoader.loadImage(url.openStream()))); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
Random r = new Random(); | |
Img img = new Img(1000, 1000); | |
img.forEach(px->{int val = r.nextInt(256); px.setRGB(val, val, val);}); | |
return img; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment