2017-09-29 41 views
0

我写了一个小程序来简单解释我的问题,我尝试改变图像的像素位置,其中纹理元素x是方向,另一个表示速度。最终目标是使用我的CPU数据,在那里计算NAVIER-STROKE流体来移动GLSL中的像素。 CPU代码在Processing java库中。 我试着去看看我的代码中有什么bug,但我不明白像素转换是如何工作的。 在第一个我转换我的方向在颜色值从0到255在CPU中,并在GPU转换这一个向量方向,并乘以这个速度和规模这一个在1x1,但这是行不通的。 ..对不起,如果我的解释不是很可靠,但英文不是很流利。移动具有纹理方向和纹理速度的像素/ GLSL

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

enter image description here

回答

1

纹理格式是GL_RGBA8,这意味着每个颜色通道被存储到一个字节中,其是一个不可或缺的数据e在从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; 
1

THX的帮助,现在我知道在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 ; 

结果是底部图像

对不起,我张贴单张图片,因为我无法发布超过一张图片以及我的初学者声望:) enter image description here

1

我修正了整个窗口显示的显示错误,但现在它是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; 

    } 
} 

,这里的画面效果,看在最终变形中光标错误y enter image description here