2017-09-29 44 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