Author Topic: Shadertoy  (Read 3058 times)

Offline AGP

  • quad
  • ******
  • Posts: 1616
    • View Profile
Shadertoy
« on: December 12, 2013, 02:06:30 am »
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:

Code: [Select]
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.

Code: [Select]
// 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;
}

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11970
    • View Profile
    • http://www.jpct.net
Re: Shadertoy
« Reply #1 on: December 12, 2013, 09:43:41 pm »
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.

Offline AGP

  • quad
  • ******
  • Posts: 1616
    • View Profile
Re: Shadertoy
« Reply #2 on: December 13, 2013, 08:02:09 am »
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:

Quote
ERROR: 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:
Code: [Select]
// 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;
}

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11970
    • View Profile
    • http://www.jpct.net
Re: Shadertoy
« Reply #3 on: December 13, 2013, 09:24:59 am »
For me, it compiles fine when is replace this

Code: [Select]
uniform sampler2D iChannel0..3;
with this

Code: [Select]
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;
uniform sampler2D iChannel3;

Offline AGP

  • quad
  • ******
  • Posts: 1616
    • View Profile
Re: Shadertoy
« Reply #4 on: December 13, 2013, 05:20:57 pm »
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

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11970
    • View Profile
    • http://www.jpct.net
Re: Shadertoy
« Reply #5 on: December 13, 2013, 07:17:23 pm »
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.

Offline AGP

  • quad
  • ******
  • Posts: 1616
    • View Profile
Re: Shadertoy
« Reply #6 on: December 13, 2013, 07:31:31 pm »
No, it throws a NullPointerException if I do that. And I'd like for it to work on both platforms, if possible.

Offline AGP

  • quad
  • ******
  • Posts: 1616
    • View Profile
Re: Shadertoy
« Reply #7 on: December 14, 2013, 07:38:02 am »
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?

Code: [Select]
attribute vec4 tangent;

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


Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11970
    • View Profile
    • http://www.jpct.net
Re: Shadertoy
« Reply #8 on: December 14, 2013, 01:07:57 pm »
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.

Offline AGP

  • quad
  • ******
  • Posts: 1616
    • View Profile
Re: Shadertoy
« Reply #9 on: December 14, 2013, 07:46:41 pm »
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?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11970
    • View Profile
    • http://www.jpct.net
Re: Shadertoy
« Reply #10 on: December 14, 2013, 07:56:41 pm »
That's reading a pixel from the texture assigned to the sampler (in this case normalMap) at the given texture coordinates.

Offline AGP

  • quad
  • ******
  • Posts: 1616
    • View Profile
Re: Shadertoy
« Reply #11 on: December 14, 2013, 08:00:01 pm »
But what I don't understand is how any texture is being assigned to the sampler2d normalMap.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11970
    • View Profile
    • http://www.jpct.net
Re: Shadertoy
« Reply #12 on: December 14, 2013, 09:39:38 pm »
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.

Offline AGP

  • quad
  • ******
  • Posts: 1616
    • View Profile
Re: Shadertoy
« Reply #13 on: December 14, 2013, 09:57:03 pm »
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?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11970
    • View Profile
    • http://www.jpct.net
Re: Shadertoy
« Reply #14 on: December 14, 2013, 10:03:11 pm »
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.