简体   繁体   中英

How to get GLSL 300 es shaders running in PIXI.JS

I need to use functions such as textureSize() in my fragment shader, but they aren't available in GLSL 100, which is what PIXI defaults to. If I try to use them anyway i get an error:

"textureSize'": no matching overloaded function found

If I try to add #version 300 es to the top of my code (as some have recommended) then I get a new error:

'version': #version directive must occur before anything else, except for comments and white space

The "full shader code" preview I am offered which accompanies the error is marked as having extra lines added by PIXI, which I can't remove.

I can't use the function I need in version 100, I can't change the version after the first line, and I can't change the first line.

Okay, So I'm answering my own question so nobody else has to wade through this mess. Here is the solution:

First, you need to change the shader code after PIXI has pre-processed it, but before it is compiled. You do that like this:

let shaderCode = eventShaderCode;
var simpleShader = new PIXI.Filter(eventVertexShaderCode, shaderCode, this.shaderUniforms);
if (!simpleShader.program.fragmentSrc.includes("#version 300 es")) {
    simpleShader.program.vertexSrc = "#version 300 es \n" + simpleShader.program.vertexSrc;
    simpleShader.program.fragmentSrc =
        "#version 300 es \n" + simpleShader.program.fragmentSrc;
}

I put the code inside an if statement because multiple objects in my program use this shader, which can result in adding the #version line multiple times. I'm not 100% sure how this happens, but I think it has something to do with some kind of caching system that PIXI might be employing so it doesn't have to recompile the same shader more than once. In any case: it is important, even if it looks unnecessary.

Next, you need to actually write the vertex and fragment shaders. Even if you are only modifying one, you need to re-write both. For your convenience, I have re-written both of the default shaders in version 3, so you can drop these in and modify them to your hearts content.

Vertex shader:

in vec2 aVertexPosition;

uniform mat3 projectionMatrix;

out vec2 vTextureCoord;

uniform vec4 inputSize;
uniform vec4 outputFrame;

vec4 filterVertexPosition( void )
{
    vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;

    return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);
}

vec2 filterTextureCoord( void )
{
    return aVertexPosition * (outputFrame.zw * inputSize.zw);
}

void main(void)
{
    gl_Position = filterVertexPosition();
    vTextureCoord = filterTextureCoord();
}

Fragment Shader

precision highp float;
uniform sampler2D uSampler;
in vec2 vTextureCoord;
out vec4 color;

void main(){
    color =  texture(uSampler, vTextureCoord);
}

Congrats! You can now use #version 300 es in your PIXI.JS project!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM