Shadertoy转WebGL GLSL:纹理尺寸相关代码转换疑问
Shadertoy转WebGL GLSL:最近邻滤波相关问题解答
1. GLSL中ivec2是什么?
ivec2是GLSL(OpenGL着色语言)中的2分量整数向量类型,专门用于存储两个整数数值,比如纹理的宽高这类整数维度数据。它和浮点向量vec2功能对应,唯一区别是内部元素的类型为整数而非浮点数。
2. GLSL中替代textureSize(iChannel0, 0)的方法
Shadertoy的textureSize(sampler, lod)用于获取指定采样器对应纹理的尺寸,但WebGL 1.0(对应GLSL ES 1.0)没有这个内置函数,需要通过以下方式替代:
- 手动声明一个
uniform变量传递纹理尺寸:在GLSL中添加uniform vec2 mediaSize;,然后在JavaScript代码中获取纹理的实际宽高(比如texture.width和texture.height),通过gl.uniform2f将数值传入这个uniform。 - 如果使用WebGL 2.0(对应GLSL ES 3.0),可以直接使用内置的
textureSize(sampler2D, int lod)函数,用法和Shadertoy完全一致:ivec2 sz = textureSize(media, 0);。
3. 目标代码的转换方式
第一行代码转换
原Shadertoy代码:
ivec2 sz = textureSize(iChannel0, 0);
- WebGL 1.0场景:利用传入的
mediaSizeuniform转换为整数向量:ivec2 sz = ivec2(mediaSize); - WebGL 2.0场景:直接复用内置函数,仅替换采样器名称:
ivec2 sz = textureSize(media, 0);
第二行代码转换
原Shadertoy代码:
uv = (vec2(0.5) + vec2(ivec2(uv * vec2(sz)))) / vec2(sz);
这行是手动最近邻采样的核心逻辑,无需修改代码本身,只要确保sz是正确的纹理整数尺寸即可。完整的WebGL 1.0示例代码片段:
uniform sampler2D media; uniform vec2 mediaSize; void main() { // 计算基础UV坐标(根据实际场景调整,比如视口尺寸不同的话要用gl_FragCoord.xy / vec2(viewWidth, viewHeight)) vec2 uv = gl_FragCoord.xy / mediaSize; ivec2 sz = ivec2(mediaSize); // 手动对齐到纹理像素中心,实现最近邻采样 uv = (vec2(0.5) + vec2(ivec2(uv * vec2(sz)))) / vec2(sz); gl_FragColor = texture2D(media, uv); }
这段代码的逻辑是:将UV坐标转换为像素坐标后取整,偏移0.5到像素中心,再转回到UV范围,确保采样时精准获取单个像素颜色,关闭纹理抗锯齿效果。
内容的提问来源于stack exchange,提问作者NewPal
相关产品推荐
相关产品推荐

