Main Menu

Shadertoy

Started by AGP, December 12, 2013, 02:06:30 AM

Previous topic - Next topic

AGP

I'd like to play around with Shadertoy's shaders. To start with, I would like to use this one: https://www.shadertoy.com/view/4slGRM. From what I gather, Shadertoy only has fragment shaders (am I right?). So I wrote a skeleton of a vertex shader that looks like this:


void main(void) {

}

I know, breathtaking, right? Still, GLSLShader tells me that the fragment shader (not my brilliant vertexshader, mind you) isn't compiled. How come?

Quote[ Wed Dec 11 23:02:13 EST 2013 ] - ERROR: Attached fragment shader is not compiled.


// Simple Water shader. (c) Victor Korsun, bitekas@gmail.com; 2012.
//
// Attribution-ShareAlike CC License.

#ifdef GL_ES
precision highp float;
#endif

const float PI = 3.1415926535897932;

// play with these parameters to custimize the effect
// ===================================================

//speed
const float speed = 0.2;
const float speed_x = 0.3;
const float speed_y = 0.3;

// refraction
const float emboss = 0.50;
const float intensity = 2.4;
const int steps = 8;
const float frequency = 6.0;
const int angle = 7; // better when a prime

// reflection
const float delta = 60.;
const float intence = 700.;

const float reflectionCutOff = 0.012;
const float reflectionIntence = 200000.;

// ===================================================

float time = iGlobalTime*1.3;

  float col(vec2 coord)
  {
    float delta_theta = 2.0 * PI / float(angle);
    float col = 0.0;
    float theta = 0.0;
    for (int i = 0; i < steps; i++)
    {
      vec2 adjc = coord;
      theta = delta_theta*float(i);
      adjc.x += cos(theta)*time*speed + time * speed_x;
      adjc.y -= sin(theta)*time*speed - time * speed_y;
      col = col + cos( (adjc.x*cos(theta) - adjc.y*sin(theta))*frequency)*intensity;
    }

    return cos(col);
  }

//---------- main

void main(void)
{
vec2 p = (gl_FragCoord.xy) / iResolution.xy, c1 = p, c2 = p;
float cc1 = col(c1);

c2.x += iResolution.x/delta;
float dx = emboss*(cc1-col(c2))/delta;

c2.x = p.x;
c2.y += iResolution.y/delta;
float dy = emboss*(cc1-col(c2))/delta;

c1.x += dx*2.;
c1.y = -(c1.y+dy*2.);

float alpha = 1.+dot(dx,dy)*intence;

float ddx = dx - reflectionCutOff;
float ddy = dy - reflectionCutOff;
if (ddx > 0. && ddy > 0.)
alpha = pow(alpha, ddx*ddy*reflectionIntence);

vec4 col = texture2D(iChannel0,c1)*(alpha);
gl_FragColor = col;
}

EgonOlsen

If the driver reports one, there should be a log output that shows the actual compilation error. Might be that your hardware/driver doesn't support something used in that shader. The syntax of GLSL is extended from version to version.

AGP

I replaced that version of jpct (the one I'd been using wasn't even 300k in size) given what you said about syntax versions, and fixed some output messages by declaring (if not filling) some variables. Now I get the following:

QuoteERROR: 0:? : 'pre-mature EOF' : syntax error syntax error



[ Fri Dec 13 04:57:04 BRST 2013 ] - ERROR: Attached fragment shader is not compiled.

Tangent handle not found (tangents needed: true)!
Shader compiled!

Basically, it's whining about a premature end-of-file. The following is "my" revised shader code:

// Simple Water shader. (c) Victor Korsun, bitekas@gmail.com; 2012.
//
// Attribution-ShareAlike CC License.

uniform float iGlobalTime;
uniform vec3 iResolution;
uniform sampler2D iChannel0..3;

#ifdef GL_ES
precision highp float;
#endif

const float PI = 3.1415926535897932;

// play with these parameters to customize the effect
// ===================================================

//speed
const float speed = 0.2;
const float speed_x = 0.3;
const float speed_y = 0.3;

// refraction
const float emboss = 0.50;
const float intensity = 2.4;
const int steps = 8;
const float frequency = 6.0;
const int angle = 7; // better when a prime

// reflection
const float delta = 60.;
const float intence = 700.;

const float reflectionCutOff = 0.012;
const float reflectionIntence = 200000.;

// ===================================================

float time = iGlobalTime*1.3;

  float col(vec2 coord) {
    float delta_theta = 2.0 * PI / float(angle);
    float col = 0.0;
    float theta = 0.0;
    for (int i = 0; i < steps; i++) {
      vec2 adjc = coord;
      theta = delta_theta*float(i);
      adjc.x += cos(theta)*time*speed + time * speed_x;
      adjc.y -= sin(theta)*time*speed - time * speed_y;
      col = col + cos( (adjc.x*cos(theta) - adjc.y*sin(theta))*frequency)*intensity;
    }

    return cos(col);
  }

void main(void) {
     vec2 p = (gl_FragCoord.xy) / iResolution.xy, c1 = p, c2 = p;
     float cc1 = col(c1);

     c2.x += iResolution.x/delta;
     float dx = emboss*(cc1-col(c2))/delta;

     c2.x = p.x;
     c2.y += iResolution.y/delta;
     float dy = emboss*(cc1-col(c2))/delta;

     c1.x += dx*2.;
     c1.y = -(c1.y+dy*2.);

     float alpha = 1.+dot(dx,dy)*intence;

     float ddx = dx - reflectionCutOff;
     float ddy = dy - reflectionCutOff;
     if (ddx > 0. && ddy > 0.)
alpha = pow(alpha, ddx*ddy*reflectionIntence);

     vec4 col = texture2D(iChannel0,c1)*(alpha);
     gl_FragColor = col;
}

EgonOlsen

For me, it compiles fine when is replace this

uniform sampler2D iChannel0..3;

with this


uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;
uniform sampler2D iChannel3;


AGP

I guess I should've tried that. But are you not getting an error like the following?

Quote[ Fri Dec 13 14:19:57 EST 2013 ] - ERROR: Vertex info
-----------
(0) : error C5145: must write to gl_Position

EgonOlsen

No, but that depends on the driver. It's a reasonable error though, because your vertex shader doesn't do anything. If you want omit the vertex shader, i think you can just null it in desktop jPCT.

AGP

No, it throws a NullPointerException if I do that. And I'd like for it to work on both platforms, if possible.

AGP

OK, with the following vertex shader the fragment shader compiles with no complaints. But now all I get is a black plain. I suppose this is because I didn't assign any textures to the water plane. So now, how do I go about initializing iChannel0-3?


attribute vec4 tangent;

void main(void) {
gl_Position = ftransform();
}


EgonOlsen

These are texture samplers...you set them to 0, 1, 2 and 3. Similar to the colorMap and normalMap setters in the example in the wiki.

AGP

I see the line texture2D(normalMap, texCoord), which I expect is where normalMap gets initialized. But I don't know how it references any image. Put simply: is texture2D a method that returns a sampler2D image and how do I use it?

EgonOlsen

That's reading a pixel from the texture assigned to the sampler (in this case normalMap) at the given texture coordinates.

AGP

But what I don't understand is how any texture is being assigned to the sampler2d normalMap.

EgonOlsen

That's simply the texture layer in the engine. By setting <samplerName> in the shader to some value, you assign the layer on that layer. For example, if you set normalMap to 0, the texture 0 will be sampled. If you set it to 3, the texture on layer 3.

AGP

But I don't see normalMap being assigned to any integer in the shader. And, more importantly, where, then, do you add the textures to the layers?

EgonOlsen

No, not in the shader, but in the Java code. The idea is this: You create a sampler2D uniform in the shader and in the java code, you have to set it to 0, 1, 2 or 3. The textures are then added to the layer by using a TextureInfo.