1

I write a little program to explain simply my problem, I try to change the pixel position of picture with a texture one where the component x is the direction, and where the other represent the velocity. The final objective is to use my data from CPU where are compute a NAVIER-STROKE fluid to move the pixel in GLSL. The CPU code is in Processing java library. I try to undestand what is buggy in my code, but I don't understand how work the pixel translation. in the first I transform my direction in value color from 0 to 255 in the CPU and after in the GPU transform this one in vectorial direction, and multiply this one by the velocity and scale this one in 1x1 but that's don't work... sorry if my explication is not really understable, but english is not really fluent.

link to the sketch

Processing :

PImage tex_velocity, tex_direction ;
PShader warping;
PImage img ;
int grid_w, grid_h ;
void setup() {
  size(600,375,P2D);
  // img = loadImage("pirate_small.jpg");
  img = loadImage("puros_girl_small.jpg");
  grid_w = 60 ;
  grid_h = 37 ;
  tex_velocity = createImage(grid_w,grid_h,RGB);
  tex_direction = createImage(grid_w,grid_h,RGB);  
  warping = loadShader("shader/warp/rope_warp_frag.glsl");
  noise_img(tex_velocity, 20, .1, .1); // max translate for the pixel
    noise_img(tex_direction, 360, .1, .1); // degree direction
}

void draw() {

    println(frameRate);
    if(frameCount%30 == 0) {
        noise_img(tex_velocity, 20, .1, .1); // max translate for the pixel
        noise_img(tex_direction, 360, .1, .1); // degree direction
    }

    warping.set("mode", 0) ;
    warping.set("texture",img);
    warping.set("roof_component_colour",g.colorModeX);
    warping.set("wh_ratio",1f/grid_w, 1f/grid_h);

  warping.set("vel_texture",tex_velocity);
  warping.set("dir_texture",tex_direction);

  shader(warping);

  image(img,0,0);
  resetShader();
  image(tex_velocity,5,5);
  image(tex_direction,grid_w +15 ,5 );
}


float x_offset, y_offset ;
void noise_img(PImage dst, int max, float ratio_x, float ratio_y) {
    noiseSeed((int)random(10000));
    for(int x = 0 ; x < dst.width ; x++) {
        x_offset += ratio_x ;
        for(int y = 0 ; y < dst.height ; y++) {
            y_offset += ratio_y ;
            float v = map(noise(x_offset,y_offset),0,1,0,max);
            v = (int)map(v,0,max,0,g.colorModeX);
            int c = color(v,v,v,g.colorModeA) ;
            dst.set(x,y,c);
        }
    }
}

GLSL

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

#define PROCESSING_TEXTURE_SHADER

#define PI 3.1415926535897932384626433832795

varying vec4 vertTexCoord;
uniform sampler2D texture;

uniform int mode;
uniform float roof_component_colour;

uniform sampler2D vel_texture;
uniform sampler2D dir_texture;
uniform vec2 wh_ratio;




float map(float value, float start1, float stop1, float start2, float stop2) {
  float result = start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
  return result;
}

vec2 cartesian_coord(float angle) {
  float x = cos(angle);
  float y = sin(angle);
  return vec2(x,y);
}


vec2 translate(float fdir, float fvel) {
  float angle_in_radian = map(fdir, 0, roof_component_colour, -PI, PI);
  vec2 dir_cart = cartesian_coord(angle_in_radian);
  return dir_cart *fvel ;
}



void main() {
  vec2 ratio = gl_FragCoord.xy *wh_ratio;

  vec4 vel = texture2D(vel_texture, ratio);
  vec4 dir = texture2D(dir_texture, ratio);

  // rendering picture ;
  if(mode == 0) {
    float direction = dir.x;
    float velocity = vel.x;
    vec2 translation = translate(direction,velocity);

    // not bad, but totaly wrong
   //  vec2 coord_dest = vertTexCoord.st +translation 

   vec2 coord_dest = vertTexCoord.st *ratio +translation ;
   // not bad, but totaly wrong
    vec2 coord_dest = vertTexCoord.st *ratio +translation ;
    vec4 tex_colour = texture2D(texture, coord_dest);

    gl_FragColor = tex_colour;
  }


  // velocity
  if(mode == 1 ) {
    gl_FragColor = texture2D(vel_texture, vertTexCoord.st);;
  }
  // direction force field
  if(mode == 2) {
    gl_FragColor = texture2D(dir_texture, vertTexCoord.st);;
  }
}

enter image description here

Syfer
  • 4,262
  • 3
  • 20
  • 37
Knupel
  • 323
  • 2
  • 14

3 Answers3

1

The texture format is GL_RGBA8, this means each color channel is stored to a byte in, which is a integral data tyoe in rage from 0 to 255.
But when you read texts from the texture sampler, the you will get a floating point value in the range from 0.0 to 1.0. (see glTexImage2D - GL_RGBA).

In the fragment shader you have to map the color channel (in [0, 1]), which you read from the texture sampler, to the range from -PI to PI. For this you can use the GLSL function mix, which does a linear interpolation between 2 values:

vec2 translate(float fdir, float fvel) // fdir, fvel in [0.0, 1.0] 
{
  float angle = mix(-PI, PI, fdir);
  return vec2(cos(angle), sin(angle)) * fvel;
}

The texture coordinates are in range [0, 1]. You have to transform the translation to texture coordinates. For this you have to know the size of your image texture:

vec2 wh_ratio;     // 1f/grid_w, 1f/grid_h
vec2 imageTexSize; // size of "texture"

vec2 scale = imageTexSize * wh_ratio;
vec2 coord_dest = vertTexCoord.st + translation / scale;
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
1

Thx for the help, now I know the picture size of picture in GLSL :) [0,1], but that's don't work expected, I use the the rendering size or the picture of the must be warp, so in my idea the vec2 imageTexSize is img.widthand img.height is passed from Processing for imageTexSize

uniform vec2 imageTexSize;
.../...
vec2 scale = imageTexSize * wh_ratio;
vec2 coord_dest = vertTexCoord.st + translation / scale;

the result is the top image

and when I try this code

vec2 ratio = gl_FragCoord.xy *wh_ratio;
vec2 coord_dest = vertTexCoord.st +translation / ratio ;

the result is the middle image

and when I try this one

vec2 coord_dest = vertTexCoord.st +translation / wh_ratio ;

the result is the bottom image

Sorry i post a single image because I cannot post more than one pic with my beginner reputation :) enter image description here

Knupel
  • 323
  • 2
  • 14
1

I fix the display bug for the full window display, but now it's the y coord who is reverse for the translation, that's weird because the texture velocity and direction are not reversed in y, the reverse y effect is in the interpretation. that's happened on the 3 mode. I try to reverse coord_dest.y like that

float coord_dest_y = mix(coord_dest.y, vertTexCoord.t, 0);
gl_FragColor = texture2D(texture, vec2(coord_dest.x, coord_dest_y));

but that's change nothing.

I try : float coord_dest_y = mix(coord_dest.y, 0, vertTexCoord.t);but that's make something really strange, so that's don't work too...

here the full the GLSL code

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

#define PROCESSING_TEXTURE_SHADER

#define PI 3.1415926535897932384626433832795

varying vec4 vertTexCoord;
uniform sampler2D texture;

uniform int mode;

uniform sampler2D vel_texture;
uniform sampler2D dir_texture;

uniform vec2 wh_grid_ratio;
uniform vec2 wh_renderer_ratio;


vec2 cartesian_coord(float angle) {
  float x = cos(angle);
  float y = sin(angle);
  return vec2(x,y);
}


vec2 translate(float fdir, float fvel) {
  //float angle = mix(PI, -PI,fdir);
  float angle = mix(fdir, PI, -PI);
  return cartesian_coord(angle) *fvel ;
}



void main() {
  vec2 ratio = gl_FragCoord.xy *wh_renderer_ratio;
  vec4 vel = texture2D(vel_texture, ratio);
  vec4 dir = texture2D(dir_texture, ratio);

  float direction = dir.x;
  float velocity = vel.x;
  vec2 translation = translate(direction,velocity);

  // mode 0 perfect
  // mode 1 interesting
  // mode 2 bizarre, but fun

  // mode 500 warp image direction
  // mode 501 warp image velocity

  // perfect
  if(mode == 0) {
    vec2 scale = gl_FragCoord.xy *wh_renderer_ratio; 
    vec2 coord_dest = vertTexCoord.st +translation /scale;
    float coord_dest_y = mix(coord_dest.y, vertTexCoord.t, 0);
    // float coord_dest_y = mix(coord_dest.y, 0, vertTexCoord.t);

    gl_FragColor = texture2D(texture, vec2(coord_dest.x, coord_dest_y));
    //  gl_FragColor = texture2D(texture, coord_dest);
  }

   // interesting
  if(mode == 1) {
    vec2 scale = gl_FragCoord.xy *wh_grid_ratio;
    vec2 coord_dest = vertTexCoord.st +translation /scale ;
    gl_FragColor = texture2D(texture, coord_dest);
  }

  // bizarre
  if(mode == 2) {
    vec2 coord_dest = vertTexCoord.st +translation /wh_grid_ratio;
    gl_FragColor = texture2D(texture, coord_dest);
  }


  // velocity
  if(mode == 500 ) {
    vec4 tex_colour = texture2D(vel_texture, vertTexCoord.st);;
    gl_FragColor = tex_colour;
  }
  // direction force field
  if(mode == 501) {
    vec4 tex_colour = texture2D(dir_texture, vertTexCoord.st);;
    gl_FragColor = tex_colour;

  }
}

and the picture result here, to see the cursor error y in the final warping enter image description here

Knupel
  • 323
  • 2
  • 14