We are about to switch to a new forum software. Until then we have removed the registration on this forum.
this fragment shader always fails to compile, irrespective of what I try. Why???
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 resolution;
uniform sampler2D ppixels;
uniform float DA;
uniform float DB;
uniform float feed;
uniform float kill;
uniform float dt;
void main (void) {
vec2 position = ( gl_FragCoord.xy / resolution.xy );
vec2 pixel = 1./resolution;
float A = texture2D(ppixels, position).r;
float sumA = -A;
sumA += 0.05*texture2D(ppixels, position + pixel * vec2(-1., -1.)).r;
sumA += 0.05*texture2D(ppixels, position + pixel * vec2(-1., 1.)).r;
sumA += 0.05*texture2D(ppixels, position + pixel * vec2(1., -1.)).r;
sumA += 0.05*texture2D(ppixels, position + pixel * vec2(1., 1.)).r;
sumA += 0.2*texture2D(ppixels, position + pixel * vec2(1., 0.)).r;
sumA += 0.2*texture2D(ppixels, position + pixel * vec2(-1., 0.)).r;
sumA += 0.2*texture2D(ppixels, position + pixel * vec2(0., -1.)).r;
sumA += 0.2*texture2D(ppixels, position + pixel * vec2(0., 1.)).r;
float B = texture2D(ppixels, position).g;
float sumB = -B;
sumB += 0.05*texture2D(ppixels, position + pixel * vec2(-1., -1.)).g;
sumB += 0.05*texture2D(ppixels, position + pixel * vec2(-1., 1.)).g;
sumB += 0.05*texture2D(ppixels, position + pixel * vec2(1., -1.)).g;
sumB += 0.05*texture2D(ppixels, position + pixel * vec2(1., 1.)).g;
sumB += 0.2*texture2D(ppixels, position + pixel * vec2(1., 0.)).g;
sumB += 0.2*texture2D(ppixels, position + pixel * vec2(-1., 0.)).g;
sumB += 0.2*texture2D(ppixels, position + pixel * vec2(0., -1.)).g;
sumB += 0.2*texture2D(ppixels, position + pixel * vec2(0., 1.)).g
float nA = A + ((DA*sumA) - (A*B*B) + (feed*(1.0 - A)))*dt;
float nB = B + ((DB*sumB) + (A*B*B) - ((kill + feed)*B))*dt;
gl_FragColor = vec4(nA, nB, 0.0, 1.0);
}
The code I use is this -
PShader algorithm;
PGraphics pg;
public static final float DA = 1;
public static final float DB = 0.5;
public static final float feed = 0.055;
public static final float kill = 0.062;
public static final float dt = 1;
void setup() {
size(500, 500, P2D);
algorithm = loadShader("algorithm.glsl");
pg = createGraphics(width, height, P2D);
pg.noSmooth();
pg.beginDraw();
pg.fill(255, 255, 0);
pg.noStroke();
pg.background(255, 0, 0);
pg.rect(width/2 - 10, height/2 - 10, 20, 20);
pg.endDraw();
algorithm.set("resolution", float(pg.width), float(pg.height));
algorithm.set("DA", DA);
algorithm.set("DB", DB);
algorithm.set("feed", feed);
algorithm.set("kill", kill);
algorithm.set("dt", dt);
}
void draw() {
pg.beginDraw();
//pg.background(0);
pg.shader(algorithm);
pg.rect(0, 0, pg.width, pg.height);
pg.endDraw();
image(pg, 0, 0, width, height);
}
Answers
Notes -
fragment shader line 41 missing semilicon.
line number and exact error message is always better than 'fails to compile'
@koogs I couldn't even read the error message, so I couldn't really post the error message.
Note that no stack trace was printed, nor was it printed to the console.
@nabr I think that should be it, thanks! I wonder why I did the notice that :P
@Lord_of_the_Galaxy OFFTOPIC:
Processing Scetch
looks like a lot of work (&bytes) for the compiler would it make more sence:
fragment:
or is it the common the way you java guys do this stuff?
just a note for myself : texture2d is deprecated<=OpenGL 3.3 use texture() the default precision is highp otherwise you targeting mobile devices. can also save few frames on older graphic hardware.
@nabr Actually, the "shortest" method would be this -
float DA = 1, DB = 0.5, feed = 0.055, kill = 0.062, dt = 1;
, and the "best" method would bepublic static final float DA = 1, DB = 0.5, feed = 0.055, kill = 0.062, dt = 1;
, but I chose that long method for readability. In fact, in most of my code, I do that do that, but since I'm posting to the forum, I did that. You must admit that it looks better when fully typed out.Note that I've omitted the f suffix because we're using Processing, otherwise Java has it too.
I thought
GL_ES
is only defined for mobile devices?I'll use
texture()
from now on.@Lord_of_the_Galaxy Great! I also often confuse myself with GL_ES :) I learned how to use ppixel. Thank you!
I see.
@nabr -- re:
Is your question "why declare static/final arguments in the Processing(Java) sketch, then pass them to the shader at setup() -- why not just declare them directly in the shader?"
One advantage to this approach is that once the GLSL shader is written and parameterized, it can be manipulated entirely at the sketch level in the future -- with any mix of static and dynamic arguments -- without further modifying the shader.
In general, Java is very verbose, and the compiler doing bytes of extra work is a non-issue outside very specialized circumstances. If there is a performance penalty from calling PShader.set() it would be very small and incurred only once, during setup -- or am I misunderstanding how GLSL works, and would there be an ongoing penalty? Shaders aren't my area of expertise.
@jeremydouglass Even if the penalty was ongoing, it won't matter as passing in a few floats every frame is insignificant compared to the amount of work already happening.
@jeremydouglass
i know few things, also not a shader expert, - and if i scroll down in the docs, i see their some crazy stuff is going on just to overload a "position" or uniform from processing to glsl. (at least at low level, - you have to type a lot) idk, i going to put as much as possibel in the frag. (actually, if we are talking about opimatation i would put as much as possible in the vertex, because fragment shader runs per pixel computation) https://github.com/processing/processing/wiki/Advanced-OpenGL
(also discovered that Processing using #version 150 per default)
i'm using sometimes processing, with 2years of break in between and java stuff that looks like public static final is kind of weird, just to replace a singel "char" in a string array.
this is what it might look like one state after uploading .glsl file to the scetch (minimal version)
Actually, in most cases, you use the fragment shader if you need to compute things in parallel.
This is because in that case, you can compute thousands of things in parallel, and it is comparatively easy to access the information, even through something like Processing.
Of course, libraries exist that help you directly run code on the GPU in parallel, but they are very complex.
@Lord_of_the_Galaxy
No i mean sometimes its also efficient!
Compute math based on Pixels : 640X360*4(RGBA) = Fragment Shader
Compute same math based on Rect : 12 vertices = Vertex Shader
could make a difference. Is also know for inaccuracy (at large scale)
Oh, you're talking of actually manipulating what is on the screen. I'm talking of using the GPU to run actual math in the background, in parallel.
@Lord_of_the_Galaxy
how?
(In Processing) Say, for example, the Reaction Diffusion algorithm, or Conway's game of life. Instead of using a grid and trying to calculate each cell one by one on the CPU, you convert the data to an image and send it to the GPU. Then each pixel of the image (each pixel contains one piece of the data) is processed by the same math, as it runs through the fragment shader. Then, you have the final output, which can then be converted back to data. Voilà, you have just done the math on the GPU.
Note that the overhead is only worth it when you're doing the same math on thousands of pieces of data.