Glsl gl_PointCoord的精确坐标?

Glsl gl_PointCoord的精确坐标?,glsl,webgl,Glsl,Webgl,在顶点中,我给pointSize一个大于1的值。说15。 在片段中,我想选择15x15正方形内的一个点: vec2 sprite = gl_PointCoord; if (sprite.s == (9. )/15.0 ) discard ; gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); 但当大小不是2的幂时,这不起作用 (如果大小是16,那么(sprite.s==a/16。)其中a在1..16:完美!) 在大小不是2的幂的情况下,是实现我的目标的方法

在顶点中,我给pointSize一个大于1的值。说15。 在片段中,我想选择15x15正方形内的一个点:

vec2 sprite = gl_PointCoord;  
if (sprite.s == (9. )/15.0 ) discard ;  
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
但当大小不是2的幂时,这不起作用

(如果大小是16,那么(sprite.s==a/16。)其中a在1..16:完美!)

在大小不是2的幂的情况下,是实现我的目标的方法吗

编辑:我知道纹理大小为:PointSize*PointSize的解决方案

gl_FragColor = texture2D(tex, gl_PointCoord);
但这不适合动态变化

7月26日编辑:

首先,我不明白为什么在浮动纹理中使用webgl2而不是webgl更容易阅读。就我而言,我做了一个ext=gl.getExtension(“OES_纹理_浮动”);gl.readpixel使用相同的语法

然后,可以肯定的是,我没有完全理解,但我尝试了解决方案s=0.25和s=0.75,以获得一个正确居中的2x2像素,这似乎不起作用。 另一方面,值:0.5和1.0为我提供了正确的显示(参见小提琴1)

(小提琴1)

事实上,为了精确显示任意大小的顶点(例如大小),我使用以下公式:

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;
float size=13.0;
浮子nby=地板((尺寸)/2.0);
浮子nbx=地板((尺寸-1.0)/2.0);
// 
//像素中心像素
//
//如果大小为奇数,则nbx==nby
//如果大小为偶数,则nbx==nby+1
vec2 off=2。*vec2(nbx,nby)/画布尺寸;
vec2p=-1+(2.*(a_position.xy*size)+1./画布尺寸+关闭;
gl_位置向量4=(p,0.0,1.0);
gl_PointSize=大小;

用浮点数检查精确值通常不是一个好主意。检查射程

sprite.s > ??? && sprite.s < ???
如果从像素边界绘制它,则它取决于

++=====++=====++======++
||     ||     ||      ||
||  +------+------+   ||
||  |      |      |   ||
++==|      |      |===++
||  |      |      |   ||
||  +------+------+   ||
||  |      |      |   ||
++==|      |      |===++
||  |      |      |   ||
||  +------+------+   ||
||     ||     ||      ||
++=====++=====++======++
它仍然只会绘制4个像素(最接近点所在位置的4个像素),但它会选择不同的gl_PointCoords,就好像它可以绘制分数像素一样。如果我们偏移了
gl_位置
,那么我们的点超过了.25个像素,它仍然绘制了与像素对齐时完全相同的4个像素,因为偏移.25是不够的,将它从绘制相同的4个像素移动,我们可以猜测它将偏移
gl_点坐标
0.25个像素(在我们的例子中,这是一个2x2点,偏移量为.125,所以(.25---.125)=.125和(.75-.125)=.675

我们可以通过使用WebGL2将它们写入浮点纹理来测试WebGL正在使用什么(因为在WebGL2中读取浮点像素更容易)

函数main(){
const gl=document.createElement(“canvas”).getContext(“webgl2”);
如果(!gl){
返回警报(“需要WebGL2”);
}
常量ext=gl.getExtension(“ext\u color\u buffer\u float”);
如果(!ext){
返回警报(“需要外部颜色缓冲区浮动”);
}
常数vs=`
均匀vec4位置;
void main(){
gl_PointSize=2.0;
gl_位置=位置;
}
`;
常数fs=`
精密中泵浮子;
void main(){
gl_FragColor=vec4(gl_PointCoord.xy,0,1);
}
`;
const programInfo=twgl.createProgramInfo(gl[vs,fs]);
常数宽度=2;
常数高度=2;
//创建2x2浮动纹理并将其附加到帧缓冲区
常量fbi=twgl.createFramebufferInfo(gl[
{internalFormat:gl.RGBA32F,minMag:gl.NEAREST,},
]、宽度、高度);
//绑定帧缓冲区并设置视口
twgl.bindFramebufferInfo(德国劳埃德船级社,联邦调查局);
总账使用程序(programInfo.program);
测试([0,0,0,1]);
测试([25,25,0,1]);
功能测试(位置){
twgl.setUniforms(programInfo,{position});
总图绘制阵列(总图点,0,1);
常量像素=新的浮点数组(宽度*高度*4);
gl.readPixels(0,0,2,2,gl.RGBA,gl.FLOAT,像素);
console.log('gl_PointCoord.s位于位置:',position.join(',);
对于(y=0;y<高度;++y){
常数s=[];
对于(x=0;x

好的,谢谢。我在编辑中给出了一个答案(否则如何发布一个长答案?)“用浮点数检查精确值通常不是一个好主意”.你说得对!我花了很多时间,但我终于理解了你的回答:你如何计算xw?它是
gl_Position.x
转换为窗口坐标。在上面的示例中,我们绘制的是2x2像素的画布。我们将
gl_Position.x
设置为0.25。如果我们将
gl_Position.x
设置为0,那将是画布的中心因此,在窗口坐标中,2x2画布的宽度为1,1。如果画布宽度为10,则
gl_位置.x=0
将为
xw=5
xw
取决于我们的画布大小。
xw=(gl_位置.x/gl_位置.w*.5+.5)*画布宽度
gl u位置.x=0.25
so
(0.25/1*.5+.5)*2
=
(0.125+.5)*2
=
0.625*2
=
1.25
++=====++=====++======++
||     ||     ||      ||
||  +------+------+   ||
||  |      |      |   ||
++==|      |      |===++
||  |      |      |   ||
||  +------+------+   ||
||  |      |      |   ||
++==|      |      |===++
||  |      |      |   ||
||  +------+------+   ||
||     ||     ||      ||
++=====++=====++======++