Reputation: 1766
How do you get the pixel location and image size inside the fragment shader for the WebGL version of a FabricJS filter? If you just have to pass it in as a uniform is the information available inside the filter or does it need to be passed to the filter as an option?
Upvotes: 2
Views: 351
Reputation: 14741
Ok so, i ll try to navigate in the code and remember, i do not touch that part of code often.
In the base filter class there is a method called createProgram
.
This method is going to return an object that contains a property called uniformLocations
.
This property holds an object that is returned from each filter getUniformLocations
method. This method again returns the object using the gl.getUniformLocation
from the webgl context.
Now fabric has a convention that in the uniforms uStepW
and uStepH
you will have what percentage of the unit is a pixel.
In the webgl context the width and height are 1, a pixel is like uStepH by uStepW, that are tipically float like 0.001231432432
and i think the image is in pixels:
width: 1 / uStepW
height: 1 / uStepH
fabric also uses vTexCoord
varying to indicate the position (i think because is pretty standard in webgl tutorials all over the internet). So the pixel position is likely:
x: vTextCoord.x / uStepW
y: vTextCoord.y / uStepH
You can look at the webgl filter pixelate
in the fabricJS repo to better understand how to access those variables in your own filter.
In that filter the method getUniformLocations
is returning uStepW and uStepH, but that is unnecessary since the basic filter is going to do the same for us.
So those informations are always available and a fabricjs fragment shader that uses them looks like this:
/**
* Fragment source for the Pixelate program
*/
fragmentSource: 'precision highp float;\n' +
'uniform sampler2D uTexture;\n' +
'uniform float uBlocksize;\n' +
'uniform float uStepW;\n' +
'uniform float uStepH;\n' +
'varying vec2 vTexCoord;\n' +
'void main() {\n' +
'float blockW = uBlocksize * uStepW;\n' +
'float blockH = uBlocksize * uStepW;\n' +
'int posX = int(vTexCoord.x / blockW);\n' +
'int posY = int(vTexCoord.y / blockH);\n' +
'float fposX = float(posX);\n' +
'float fposY = float(posY);\n' +
'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n' +
'vec4 color = texture2D(uTexture, squareCoords);\n' +
'gl_FragColor = color;\n' +
'}',
Now, said so, i do not think you need to know those things in a webgl filter, unless you are doing something particular.
This kind of question to me smells of the XY problem, but since i'm not a WEBGL expert at all, i may be wrong. If you are trying to build a filter and you think you need these informations to progress further, you could do better at explaining also what are you trying to build.
Upvotes: 1