使用片元着色器实现distortion畸变效果后如何让屏幕内容居中
你遇到的右上角画面异常问题是代码中的三处逻辑错误导致的,修复方案如下:
错误排查
- 强度纹理采样逻辑错误:原代码中
vec4 intensityVec = texture2D(uIntensity, vTextureCoord)*(uTime,0.5);写法不符合GLSL语法规则,vec4与vec2做分量乘法会导致分量不匹配,且你原本的逻辑是要让强度纹理随时间滚动,应该将时间参数传入采样坐标而非和采样结果相乘。 - 变形纹理采样UV错误:构造
mod_texcoord时x分量被写死为0,导致全屏幕像素采样变形纹理的x坐标完全一致,采样坐标超出纹理[0,1]范围后就会出现边缘异常,就是你看到的右上角显示问题。 - 最终采样UV无范围限制:偏移后的UV如果超出[0,1]区间,在纹理CLAMP_TO_EDGE模式下会出现边缘拉伸的异常效果。
修复后代码
/* Render of the screen */ uniform sampler2D uSampler; /* Texture of the distortion*/ uniform sampler2D uDeformation; /* Texture for the intensity */ uniform sampler2D uIntensity; /* The time (u_time) */ uniform float uTime; /* Scale of Deformation */ uniform float uScale; /* Coords of fragment */ varying vec2 vTextureCoord; void main (void) { // 强度纹理采样坐标随时间滚动,0.1系数控制滚动速度可自行调整 vec4 intensityVec = texture2D(uIntensity, vec2(uTime * 0.1, 0.5)); // 变形纹理采样UV保留原始坐标,添加sin偏移实现波动效果 vec2 mod_texcoord = vTextureCoord + vec2(0.0, 0.1 * sin(uTime * 2.0)) + intensityVec.xy * 0.1; // 采样UV钳制在0-1范围避免边缘异常 mod_texcoord = clamp(mod_texcoord, 0.0, 1.0); // 计算屏幕纹理最终采样坐标 vec2 finalUV = vTextureCoord + uScale * texture2D(uDeformation, mod_texcoord).rg; // 最终采样坐标钳制 finalUV = clamp(finalUV, 0.0, 1.0); gl_FragColor = texture2D(uSampler, finalUV); }
效果优化建议
- 如果需要更自然的醉酒晃动感,可以将sin计算和原始UV坐标关联,比如改为
sin(uTime + vTextureCoord.x * 8.0),让不同位置的偏移节奏有差异 - uScale建议取值范围控制在0.01~0.1之间,避免偏移量过大导致画面严重失真
- 如果需要循环滚动的变形效果,可以将uDeformation、uIntensity纹理的包裹模式设置为REPEAT,同时去掉mod_texcoord的clamp限制即可

内容的提问来源于stack exchange,提问作者S3yll
相关产品推荐
相关产品推荐

