【问题标题】:Move pixel with texture direction and texture velocity / GLSL使用纹理方向和纹理速度/ GLSL 移动像素
【发布时间】:2017-10-01 17:02:02
【问题描述】:

我写了一个小程序来简单地解释我的问题,我尝试用一​​个纹理来改变图片的像素位置,其中分量 x 是方向,另一个代表速度。最终目标是使用来自 CPU 的数据来计算 NAVIER-STROKE 流体来移动 GLSL 中的像素。 CPU 代码在处理 java 库中。 我试图理解我的代码中有什么错误,但我不明白像素转换是如何工作的。 在第一个中,我在 CPU 中将值颜色的方向从 0 转换为 255,然后在 GPU 中将这个方向转换为矢量方向,并将这个乘以速度并将这个缩放为 1x1,但这不起作用.. . 对不起,如果我的解释不是很不稳定,但英语不是很流利。

link to the sketch

处理:

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

【问题讨论】:

    标签: glsl textures warp


    【解决方案1】:

    纹理格式为GL_RGBA8,这意味着每个颜色通道存储到一个字节中,这是一个整数数据,范围从0到255。
    但是当您从纹理采样器中读取文本时,您将获得一个介于 0.0 到 1.0 之间的浮点值。 (见glTexImage2D - GL_RGBA)。

    在片段着色器中,您必须将从纹理采样器读取的颜色通道(在 [0, 1] 中)映射到从 -PI 到 PI 的范围。为此,您可以使用 GLSL 函数 mix,它在 2 个值之间进行线性插值:

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

    纹理坐标在 [0, 1] 范围内。您必须将translation 转换为纹理坐标。为此,您必须知道图像纹理的大小:

    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;
    

    【讨论】:

      【解决方案2】:

      感谢您的帮助,现在我知道 GLSL 中图片的图片大小 :) [0,1],但这是行不通的,我使用渲染大小或必须扭曲的图片,所以在我的想法vec2 imageTexSizeimg.widthimg.height 是从处理为imageTexSize 传递的

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

      结果是顶部图像

      当我尝试这段代码时

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

      结果是中间图片

      当我尝试这个时

      vec2 coord_dest = vertTexCoord.st +translation / wh_ratio ;
      

      结果是底部图像

      抱歉,我只发布了一张图片,因为我不能以我的初学者声誉发布多张图片 :)

      【讨论】:

        【解决方案3】:

        我修复了全窗口显示的显示错误,但是现在平移的 y 坐标是反向的,这很奇怪,因为纹理速度和方向在 y 中没有反向,反向 y 效果在解释中。这发生在 3 模式上。我尝试像那样反转coord_dest.y

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

        但这并没有改变。

        我尝试:float coord_dest_y = mix(coord_dest.y, 0, vertTexCoord.t);但这确实很奇怪,所以这也行不通...

        这里是完整的 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;
        
          }
        }
        

        和这里的图片结果,看最终warping中的游标误差y enter image description here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-09-28
          • 2015-03-20
          • 1970-01-01
          • 2013-12-09
          • 2018-03-25
          • 1970-01-01
          • 2015-01-22
          相关资源
          最近更新 更多