如何在PIXI.JS中运行GLSL 300 ES着色器?
解决PIXI中GLSL 100不支持textureSize()及版本指令冲突的问题
方案1:在GLSL 100中手动传递纹理尺寸(兼容所有PIXI版本)
既然GLSL 100没有textureSize()函数,我们可以直接在JS层把纹理的宽高作为uniform变量传给着色器,完全替代该函数的作用:
- JS层传递uniform:
// 假设已获取目标纹理texture const customShader = PIXI.Shader.from( // 顶点着色器源码(用默认实现即可) `attribute vec2 aVertexPosition; uniform mat3 projectionMatrix; void main() { gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); }`, // 片段着色器源码 `precision mediump float; uniform sampler2D uSampler; uniform vec2 uTextureSize; // 自定义纹理尺寸uniform void main() { // 用uTextureSize替代textureSize(uSampler, 0) vec2 texSize = uTextureSize; // 后续逻辑正常使用texSize即可 gl_FragColor = texture2D(uSampler, gl_FragCoord.xy / texSize); }`, // 传入uniform初始值 { uTextureSize: new PIXI.Point(texture.width, texture.height) } );
- 注意事项:如果后续纹理尺寸发生变化,记得同步更新
uTextureSize的值。
方案2:让PIXI使用GLSL 300 ES(PIXI 7+适用)
PIXI新版本支持指定GLSL版本,框架会自动处理版本指令的位置,避免冲突:
- 创建Shader时指定GLSL版本:
const vertexSrc = `#version 300 es in vec2 aVertexPosition; uniform mat3 projectionMatrix; void main() { gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); }`; const fragmentSrc = `#version 300 es precision mediump float; uniform sampler2D uSampler; out vec4 fragColor; void main() { // 直接使用textureSize()函数 vec2 texSize = textureSize(uSampler, 0); fragColor = texture(uSampler, gl_FragCoord.xy / texSize); }`; // 创建Program时指定GLSL 300版本 const program = new PIXI.Program(vertexSrc, fragmentSrc, { glslVersion: PIXI.Program.GLSL_300 }); const customShader = new PIXI.Shader(program);
- 语法适配:GLSL 300 ES有几个语法变化需要注意:
- 用
in替代attribute,out替代varying - 纹理采样用
texture()替代texture2D() - 片段着色器需用
out vec4 fragColor指定输出颜色,不再使用gl_FragColor
- 用
内容的提问来源于stack exchange,提问作者Sam Spade
相关产品推荐
相关产品推荐

