我正试图为网站上的图像创建一个rgb偏移效果。我有基本的功能,但问题是通道是抵消了uv的纹理。因此,如果图像大小不同,则每个图像的偏移量在视觉上并不相同。
这是我的碎片着色器。
uniform sampler2D texture;
varying vec2 vUv; // vertex uv
void main() {
vec2 uv = vUv;
float red = texture2D(texture, vec2(uv.x, uv.y - .1)).r;
float green = texture2D(texture, uv).g;
float blue = texture2D(texture, vec2(uv.x, uv.y + .1)).b;
float alpha = texture2D(texture, uv).a;
gl_FragColor = vec4(vec3(red, green, blue), alpha);
}以及它呈现到页面上的方式。

我将如何在不需要传递一个统一的值的情况下,对uv偏移量进行标准化?
发布于 2019-08-28 04:40:07
传递更多的信息,比如偏移量,这是正常的。
uniform float offset1;
uniform float offset2;
uniform sampler2D texture;
varying vec2 vUv; // vertex uv
void main() {
vec2 uv = vUv;
float red = texture2D(texture, vec2(uv.x, uv.y + offset1)).r;
float green = texture2D(texture, uv).g;
float blue = texture2D(texture, vec2(uv.x, uv.y + offset2)).b;
float alpha = texture2D(texture, uv).a;
gl_FragColor = vec4(vec3(red, green, blue), alpha);
}然后,您可以在JavaScript中调整这一点。例如
const uniforms = {
offset1: { value: 0 },
offset2: { value: 0 },
...
};
...
uniforms.offset1.value = 2 / textureHeight;
uniforms.offset2.value = -2 / textureHeight;如果是我,我会做得更像这样
uniform vec2 channelOffsets[4];
uniform vec4 channelMult[4];
uniform sampler2D texture;
varying vec2 vUv; // vertex uv
void main() {
vec2 uv = vUv;
vec4 channel0 = texture2D(texture, uv + channelOffset[0]);
vec4 channel1 = texture2D(texture, uv + channelOffset[1]);
vec4 channel2 = texture2D(texture, uv + channelOffset[2]);
vec4 channel3 = texture2D(texture, uv + channelOffset[3]);
gl_FragColor =
channelMult[0] * channel0 +
channelMult[1] * channel1 +
channelMult[2] * channel2 +
channelMult[3] * channel3 ;
}并设置它们
const uniforms = {
channelOffsets: { value: [
new THREE.Vector2(),
new THREE.Vector2(),
new THREE.Vector2(),
new THREE.Vector2(),
]},
channelMults: { value: [
new THREE.Vector4(1, 0, 0, 0),
new THREE.Vector4(0, 1, 0, 0),
new THREE.Vector4(0, 0, 1, 0),
new THREE.Vector4(0, 0, 0, 1),
]},
....
}
...
uniforms.channelOffsets.value[0].y = -2 / textureHeight;
uniforms.channelOffsets.value[2].y = 2 / textureHeight;一个不太硬编码的例子。我甚至可以使用纹理矩阵代替允许旋转和缩放每个通道的偏移,并将它们与允许交换通道的矩阵组合起来。
发布于 2019-08-27 16:02:19
如果要使用WebGL 2.0上下文(参见如何使用WebGL2),则可以使用textureSize获取纹理的大小。例如:
#version 300 es
uniform sampler2D tex;
in vec2 vUv;
out vec4 color;
void main() {
vec2 uv = vUv;
vec2 size = vec2(textureSize(tex, 0));
float pixel = 10.0;
float offset = pixel / size.y;
float red = texture(tex, vec2(uv.x, uv.y - offset)).r;
float green = texture(tex, uv).g;
float blue = texture(tex, vec2(uv.x, uv.y + offset)).b;
float alpha = texture(tex, uv).a;
color = vec4(red, green, blue, alpha);
}注意,您必须更改纹理取样器制服的名称
发布于 2019-08-27 17:29:38
如果你需要知道你在屏幕空间(不是3D世界空间)上的哪个像素,你可以使用gl_FragCoord。例如,在1080 p的显示器中,gl_FragCoord.x从左边的0开始,在屏幕的右边增加到1920。gl_FragCoord.y的范围将比0,1080短一点。您可以在分段着色器中提取这些坐标,如下所示:
vec2 coord = gl_FragCoord.xy;这样你就可以知道你在屏幕空间的哪个像素,而不必穿另一件制服。有关更多细节,请参见此处:
https://stackoverflow.com/questions/57676918
复制相似问题