我写了一个小程序来解释我的问题,我尝试用一个纹理改变图像的像素位置,其中分量x是方向,另一个代表速度。最终目标是使用来自CPU的数据来计算NAVIER-STROKE流体来移动GLSL中的像素。 CPU代码在Processing java库中。 我试着在我的代码中找不到有缺陷的东西,但我不明白像素转换是如何工作的。 在第一个中,我在CPU中将值颜色的方向从0转换为255,然后在GPU中将这个方向转换为矢量方向,然后将此值乘以速度并将其与1x1中的比例相乘,但是这样做了#&# 39;工作......对不起,如果我的解释不是真的很明白,但英语不是很流利。
处理:
#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
var gradientView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 35))
let gradientLayer:CAGradientLayer = CAGradientLayer()
gradientLayer.frame.size = self.gradientView.frame.size
gradientLayer.colors =
[UIColor.white.cgColor,UIColor.red.withAlphaComponent(1).cgColor]
//Use diffrent colors
gradientView.layer.addSublayer(gradientLayer)
答案 0 :(得分: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;
答案 1 :(得分:1)
请求帮助,现在我知道GLSL中图片的图片大小:) [0,1]
,但这不能正常工作,我使用渲染大小或必须经线的图片,所以在我的想法中,vec2 imageTexSize
为img.width
,img.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 ;
结果是底部图像
答案 2 :(得分: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