exact coordinates of gl_PointCoord?

Multi tool use
Multi tool use
The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


exact coordinates of gl_PointCoord?



In a vertex i give pointSize a value bigger than 1. Say 15.
In the fragment i would like choose a point inside that 15x15 square :


vec2 sprite = gl_PointCoord;
if (sprite.s == (9. )/15.0 ) discard ;
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);



But that does not work when Size is not a power of 2.



(if size is 16, so (sprite.s == a/16.) where a is in 1..16 : Perfect !)



is a way to achieve my purpose where size is not of power of 2 ?



edit : i know the solution with a texture of size : PointSize * PointSize


gl_FragColor = texture2D(tex, gl_PointCoord);



but that not fit for dynamic change



edit 26 july :



first I do not understand why it is easier to read in a float texture using webgl2 rather than webgl. For my part I make an ext = gl.getExtension ("OES_texture_float"); and the gl.readpixel uses the same syntax.



Then, it is certain that I did not understand everything but I tried the solution s = 0.25 and s = 0.75 for a correctly centered 2x2 pixel, and that does not seem to work.
On the other hand, the values: 0.5 and 1.0 give me a correct display (see fiddle 1)



(fiddle 1) https://jsfiddle.net/3u26rpf0/274/



In fact, to accurately display any size vertex (say SIZE) I use the following formula:


float size = 13.0;
float nby = floor ((size) /2.0);
float nbx = floor ((size-1.0) /2.0);
//
// <nby> pixels CENTER <nbx> pixels
//
// if size is odd nbx == nby
// if size is even nbx == nby +1

vec2 off = 2. * vec2 (nbx, nby) / canvasSize;
vec2 p = -1. + (2. * (a_position.xy * size) + 1.) / canvasSize + off;

gl_Position vec4 = (p, 0.0,1.0);
gl_PointSize = size;



https://jsfiddle.net/3u26rpf0/275/



in this last fiddle, you can change the size in the vertex, and the display gives precise stacks. However, the strange phenomenon: a continuous vertical bar corresponds well to the value 0.5, (gl_pointCoord.x == 0.5 the middle of the vertex, but the corresponding horizontal bar is discontinuous (gl_PointCoord.y == 0.5)



edit 29 july:



i find the formula :



if pointsize is odd :



pointCoord.s is : (n+0.5)/pointsize where n =0..pointsize-1 .



if pointsize is even :



pointCoord. is : n/pointsize where n=1..pointsize .




1 Answer
1



Checking for exact values with floating point numbers is not generally a good idea. Check for range


sprite.s > ??? && sprite.s < ???



Or better yet consider using a mask texture or something more flexible than a hard coded if statement.



Otherwise in WebGL pixels are referred to by their centers. So, if you draw a 2x2 point on pixel boundary then these should be the .s values for gl_PointCoord.


.s


gl_PointCoord


+-----+-----+
| .25 | .75 |
| | |
+-----+-----+
| .25 | .75 |
| | |
+-----+-----+



If you draw it off a pixel boundary then it depends


++=====++=====++======++
|| || || ||
|| +------+------+ ||
|| | | | ||
++==| | |===++
|| | | | ||
|| +------+------+ ||
|| | | | ||
++==| | |===++
|| | | | ||
|| +------+------+ ||
|| || || ||
++=====++=====++======++



It will still only draw 4 pixels (the 4 that are closest to where the point lies) but it will choose different gl_PointCoords as though it could draw on fractional pixels. If we offset gl_Position so our point is over by .25 pixels it still draws the exact same 4 pixels as when pixel aligned since an offset of .25 is not enough move it from drawing the same 4 pixels we can guess it's going to offset gl_PointCoord by -.25 pixels (in our case that's for a 2x2 point that's an offset of .125 so (.25 - -.125) = .125 and (.75 - .125) = .675.


gl_Position


gl_PointCoord



We can test what WebGL is using by writing them into a floating point texture using WebGL2 (since it's easier to read the float pixels back in WebGL2)




function main() {
const gl = document.createElement("canvas").getContext("webgl2");
if (!gl) {
return alert("need WebGL2");
}
const ext = gl.getExtension("EXT_color_buffer_float");
if (!ext) {
return alert("need EXT_color_buffer_float");
}

const vs = `
uniform vec4 position;
void main() {
gl_PointSize = 2.0;
gl_Position = position;
}
`;

const fs = `
precision mediump float;
void main() {
gl_FragColor = vec4(gl_PointCoord.xy, 0, 1);
}
`;

const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
const width = 2;
const height = 2;

// creates a 2x2 float texture and attaches it to a framebuffer
const fbi = twgl.createFramebufferInfo(gl, [
{ internalFormat: gl.RGBA32F, minMag: gl.NEAREST, },
], width, height);

// binds the framebuffer and set the viewport
twgl.bindFramebufferInfo(gl, fbi);

gl.useProgram(programInfo.program);

test([0, 0, 0, 1]);
test([.25, .25, 0, 1]);

function test(position) {
twgl.setUniforms(programInfo, {position});
gl.drawArrays(gl.POINTS, 0, 1);

const pixels = new Float32Array(width * height * 4);
gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.FLOAT, pixels);

console.log('gl_PointCoord.s at position:', position.join(', '));
for (y = 0; y < height; ++y) {
const s = ;
for (x = 0; x < width; ++x) {
s.push(pixels[(y * height + x) * 4]);
}
console.log(`y${y}:`, s.join(', '));
}
}
}
main();


<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>



The formula for what gl_PointCoord will be is in the spec section 3.3


gl_PointCoord



gl_PointCoord formula



so following that a point drawn .25 pixels off of a 0 pixel boundary for a 2 pixel width point


drawing a 2x2 at .25,.25 (slightly off center)
// first pixel

// this value is constant for all pixels. It is the unmodified
// **WINDOW** coordinate of the **vertex** (not the pixel)
xw = 1.25

// this is the integer pixel coordinate
xf = 0

// gl_PointSize
size = 2

s = 1 / 2 + (xf + 1 / 2 - xw) / size
s = .5 + (0 + .5 - 1.25) / 2
s = .5 + (-.75) / 2
s = .5 + (-.375)
s = .125



which is the value I get from running the sample above.





ok thanks. I gave an answer in an edit (how else to post a long answer?)
– Philippe Oceangermanique
2 days ago





"Checking for exact values with floating point numbers is not generally a good idea". You are right !
– Philippe Oceangermanique
18 hours ago






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

dOTC,Ic,C6WLj2 z0NWU,AUHvZqwPNW3w5Im,Ey7PEGnMf6vGzNVm7wRTJ8qr4KZzAeF0PJk5
7,byU3Bpd,UkC8,0d2DSVB9l 0Q4WAR4D6woOaVXjS,gI Rw f03PcpQUb,EDu3EP9yqomZzuS4Is Y2w3GWiASvGERrqkE

Popular posts from this blog

Makefile test if variable is not empty

Visual Studio Code: How to configure includePath for better IntelliSense results

Will Oldham