0

I want to re-use a shader I've found here. It's a THREE.js project of reaction/diffusion and it uses a GLSL program to do it.

Vertex Shader goes like this :

varying vec2 vUv;

 void main()
 {
     vUv = uv;
     gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
 }

And Fragment Shader (the main one) like that :

varying vec2 vUv;
uniform float screenWidth;
uniform float screenHeight;
uniform sampler2D tSource;
uniform float delta;
uniform float feed;
uniform float kill;
uniform vec2 brush;

vec2 texel = vec2(1.0/screenWidth, 1.0/screenHeight);
float step_x = 1.0/screenWidth;
float step_y = 1.0/screenHeight;

void main()
{
    if(brush.x < -5.0)
    {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        return;
    }

    //float feed = vUv.y * 0.083;
    //float kill = vUv.x * 0.073;

    vec2 uv  = texture2D(tSource, vUv).rg;
    vec2 uv0 = texture2D(tSource, vUv + vec2(-step_x, 0.0)).rg;
    vec2 uv1 = texture2D(tSource, vUv + vec2(step_x, 0.0)).rg;
    vec2 uv2 = texture2D(tSource, vUv + vec2(0.0, -step_y)).rg;
    vec2 uv3 = texture2D(tSource, vUv + vec2(0.0, step_y)).rg;

    vec2 lapl = (uv0 + uv1 + uv2 + uv3 - 4.0*uv);//10485.76;
    float du = /*0.00002*/0.2097*lapl.r - uv.r*uv.g*uv.g + feed*(1.0 - uv.r);
    float dv = /*0.00001*/0.105*lapl.g + uv.r*uv.g*uv.g - (feed+kill)*uv.g;
    vec2 dst = uv + delta*vec2(du, dv);

    if(brush.x > 0.0)
    {
        vec2 diff = (vUv - brush)/texel;
        float dist = dot(diff, diff);
        if(dist < 5.0)
            dst.g = 0.9;
    }

    gl_FragColor = vec4(dst.r, dst.g, 0.0, 1.0);
}  

I want to translate the whole javascript code to Python using PyOpenGL, In fact I'm near to be done but it doesn't works very well. OpenGL is new for me as well as THREE.js. What's complicated to figure out for me is that vUv = uv; line. With THREE.js, this is a built-in attribute, I understand that THREE.js provide it automatically, of course you can't do the same thing with PyOpenGL so this line has to be modified.

I tried something like that instead :

void main(void)
{
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
   gl_TexCoord[0]=gl_TextureMatrix[0] * gl_MultiTexCoord0;
}

And, in the fragment shader I use this now :

vec2 uv  = texture2D(BaseImage, gl_TexCoord[0].st).rg;
vec2 uv0 = texture2D(BaseImage, gl_TexCoord[0].st + vec2(-step_x , 0.0)).rg;
vec2 uv1 = texture2D(BaseImage, gl_TexCoord[0].st + vec2( step_x , 0.0)).rg;
vec2 uv2 = texture2D(BaseImage, gl_TexCoord[0].st + vec2(0.0, -step_y)).rg;
vec2 uv3 = texture2D(BaseImage, gl_TexCoord[0].st + vec2(0.0, step_y )).rg;

I think it's wrong but It's hard to debug GLSL.

So, my question is : By what 'uv' should be replaced ?

snoob dogg
  • 2,491
  • 3
  • 31
  • 54
  • uv is your mapping attribute, which seems to be this `layout (location=1) in vec2 texCoords;` doesn't look like you're using it though. – pailhead Dec 15 '17 at 17:53
  • sorry, it's an error, I removed this line now. Anyway, I wasn't using it anymore, I'm using gl_TexCoord[0].st instead. Do you think it should be better to use texCoords ? I'm lost :/ – snoob dogg Dec 15 '17 at 18:08
  • I don't have that much experience with opengl. A casual glance seems to imply that these two are the same, but i'm not certain. I'm certain that it's in section 5.5 of the spec :D Bottom line is `uv` in three.js is a shortcut to setting a vec2 attribute ie. it has been done for you. You need to provide this attribute yourself otherwise. Even when using RawShaderMaterial, you'd have to do this yourself. – pailhead Dec 15 '17 at 18:30
  • More specifically `gl_MultiTexCoord0` sounds like your attribute. – pailhead Dec 15 '17 at 18:30
  • In fact, after some test, it seems that using gl_TexCoord[0].st work properly. I did some experimentations that prove me it works. – snoob dogg Dec 15 '17 at 19:29

0 Answers0