2017-09-29 11 views
0

J'écris un petit programme pour expliquer simplement mon problème, j'essaie de changer la position de pixel de l'image avec une texture où le composant x est la direction, et où l'autre représente la vitesse. L'objectif final est d'utiliser mes données du CPU où sont calculés un fluide NAVIER-STROKE pour déplacer le pixel dans GLSL. Le code de la CPU est dans la bibliothèque Java de traitement. J'essaie de comprendre ce qui est buggé dans mon code, mais je ne comprends pas comment fonctionne la traduction de pixels. dans le premier je transforme ma direction en couleur de valeur de 0 à 255 dans la CPU et après dans le GPU transforme celui-ci en direction vectorielle, et multiplie celui-ci par la vélocité et l'échelle celle-ci en 1x1 mais ça ne marche pas. .. désolé si mon explication n'est pas vraiment compréhensible, mais l'anglais n'est pas vraiment fluide.Déplacer le pixel avec la direction de texture et la vitesse de texture/GLSL

link to the sketch

traitement:

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

Répondre

1

Le format de texture est GL_RGBA8, cela signifie que chaque canal de couleur est stocké dans un octet, qui est un tyo de données intégrales Cependant, lorsque vous lisez des textes de l'échantillonneur de textures, vous obtenez une valeur en virgule flottante comprise entre 0,0 et 1,0. (Voir glTexImage2D - GL_RGBA).

Dans le fragment shader, vous devez mapper le canal de couleur (en [0, 1]), que vous avez lu depuis l'échantillonneur de texture, sur la plage allant de -PI à PI. Pour cela, vous pouvez utiliser la fonction GLSL mix, qui effectue une interpolation linéaire entre les 2 valeurs:

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; 
} 

Les coordonnées de texture sont dans la plage [0, 1]. Vous devez transformer le translation en coordonnées de texture.Pour cela, vous devez connaître la taille de votre 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; 
1

Thx pour l'aide, maintenant je connais la taille de l'image de l'image en GLSL :) [0,1], mais c'est ne fonctionnent pas prévu, j'utilise la la taille de rendu ou l'image du doit être la chaîne, donc dans mon idée est la vec2 imageTexSizeimg.width et img.height est passé de traitement pour imageTexSize

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

le résultat est l'image du haut

et lorsque je tente ce code

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

le résultat est l'image du milieu

et quand j'essaie celui

vec2 coord_dest = vertTexCoord.st +translation/wh_ratio ; 

le résultat est l'image du bas

Désolé je poste une seule image parce que je ne peux pas poster plus d'une photo avec ma réputation de débutant :) enter image description here

1

Je corrige le bogue d'affichage pour la fenêtre entière, mais maintenant c'est la coordonnée y qui inverse pour la traduction, c'est bizarre parce que la vitesse et la direction de la texture ne sont pas inversées dans y, l'inverse y est dans l'interprétation. C'est arrivé en mode 3. J'essaie d'inverser coord_dest.y comme ça

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

mais c'est rien changer.

J'essaie: float coord_dest_y = mix(coord_dest.y, 0, vertTexCoord.t); mais c'est faire quelque chose de vraiment étrange, de sorte que ce ne fonctionnent pas trop ...

complet ici le code 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 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; 

    } 
} 

et le résultat de l'image ici, voir l'erreur du curseur y dans la déformation finale enter image description here