Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 如何获得精确的碎片屏幕位置,如顶点着色器中的gl_FragCood?_Opengl_Unity3d_Glsl_Shader_Vertex Shader - Fatal编程技术网

Opengl 如何获得精确的碎片屏幕位置,如顶点着色器中的gl_FragCood?

Opengl 如何获得精确的碎片屏幕位置,如顶点着色器中的gl_FragCood?,opengl,unity3d,glsl,shader,vertex-shader,Opengl,Unity3d,Glsl,Shader,Vertex Shader,我使用投影的gl_位置和屏幕参数进行了一些计算,但在靠近相机的多边形中,位置似乎扭曲了。但是当我使用 vec2 fragmentScreenCoordinates = vec2(gl_FragCoord.x / _ScreenParams.x, gl_FragCoord.y / _ScreenParams.y); …我得到了相当准确的xy结果 漂亮的输出gl_FragCoord.xy坐标: 从投影顶点计算会在所有面上产生插值,我无法使用插值对屏幕对齐纹理进行采样 gl_位置的丑陋插值输出:

我使用投影的gl_位置和屏幕参数进行了一些计算,但在靠近相机的多边形中,位置似乎扭曲了。但是当我使用

vec2 fragmentScreenCoordinates = vec2(gl_FragCoord.x / _ScreenParams.x, gl_FragCoord.y / _ScreenParams.y);
…我得到了相当准确的xy结果

漂亮的输出gl_FragCoord.xy坐标:

从投影顶点计算会在所有面上产生插值,我无法使用插值对屏幕对齐纹理进行采样

gl_位置的丑陋插值输出:

有没有办法在顶点着色器中生成类似gl_FragCoord的值?我真的很想在顶点着色器中计算独立纹理读取、手动深度测试等的纹理坐标


或者我可以在这里使用任何内置的统一值吗?

在顶点着色器中,您可以设置

gl_Position = ...
这必须在剪辑空间中,在透视图划分为标准化设备坐标之前。这是因为OpenGL在4D空间中做了大量的工作,并且是插值所必需的

由于您只需要每个顶点上的值,而不需要插值,因此可以立即进行规格化,甚至可以

这里,viewportCoord相当于您的FragmentScreenCoords,假设视口覆盖了窗口

注意:@derhass指出,如果几何体与w=0平面相交,则此操作将失败。即,可见三角形的顶点位于摄影机后面

[编辑] 注释讨论了使用坐标进行1到1像素的最近邻查找。正如@AndonM.Coleman所说,改变坐标会起作用,但使用最近邻过滤更容易、更快。您还可以使用texelFetch,它完全绕过过滤:

捕捉坐标:

vec2 sampleCoord = (floor(viewportPixelCoord) + 0.5) / textureSize(mySampler);
vec4 colour = texture(mySampler, sampleCoord);
最近邻筛选不确定unity3d中的内容:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //magnification is the important one here
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
使用texelFetch:


在顶点着色器中,设置

gl_Position = ...
这必须在剪辑空间中,在透视图划分为标准化设备坐标之前。这是因为OpenGL在4D空间中做了大量的工作,并且是插值所必需的

由于您只需要每个顶点上的值,而不需要插值,因此可以立即进行规格化,甚至可以

这里,viewportCoord相当于您的FragmentScreenCoords,假设视口覆盖了窗口

注意:@derhass指出,如果几何体与w=0平面相交,则此操作将失败。即,可见三角形的顶点位于摄影机后面

[编辑] 注释讨论了使用坐标进行1到1像素的最近邻查找。正如@AndonM.Coleman所说,改变坐标会起作用,但使用最近邻过滤更容易、更快。您还可以使用texelFetch,它完全绕过过滤:

捕捉坐标:

vec2 sampleCoord = (floor(viewportPixelCoord) + 0.5) / textureSize(mySampler);
vec4 colour = texture(mySampler, sampleCoord);
最近邻筛选不确定unity3d中的内容:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //magnification is the important one here
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
使用texelFetch:


你在使用透视投影吗?如果你这样做,你必须包括透视分割,这意味着除以gl_FragCoord.w。你使用透视投影吗?如果你这样做了,你必须包括透视分割,这意味着除以gl_FragCoord.w。如果我是对的,这些xy坐标与设备像素没有完全对齐,我的意思是这些xy坐标不知何故是像素间的值。因此,它们不适合从视口对齐纹理(如深度贴图)中采样。实际纹理采样可能因几何体而异。在这里将这些值捕捉到实际像素有意义吗?类似于圆到最近的像素位置。@Geri:光栅化就是这样工作的,所以它非常好。按照惯例,碎片都在像素中心采样。但我要指出的是,你不想四舍五入。您要做的是捕捉到最近的像素中心。只需在GLSL中隐式地从浮点转换为整数,而不是四舍五入即可实现这一点,这将为您提供足够的空间,而这正是您需要捕捉到0.5的行为。如果使用viewportCoord值进行纹理查找,实际上,如果使用最近邻过滤,则不必担心这些问题。嘿,使用最近邻听起来非常棒,谢谢!仅当我可以将其设置为系统导出的摄影机深度纹理时。它以某种方式在内部统一管理。希望它能工作,我也可以在那里节省性能。@现在有了你的更新,我真的很困惑。如果需要逐像素着色,则必须使用逐像素着色,否则将使用逐顶点着色并获得线性插值颜色。这是没有办法的。尝试在透视图分割后插值ndc将中断,因为OpenGl将为您提供插值。您可以使用noperspective,但为什么不使用gl_FragCoord呢?此答案中建议的解决方案存在一个普遍问题:它在一般情况下不起作用。如果不考虑需要查看完整原语的剪裁,就不可能获得有意义的NDC坐标,因此
在顶点着色器中不可能执行此操作。当有透视投影和基本体与近平面相交时,问题就会出现,特别是当基本体的至少一个点位于相机前面,而至少另一个点位于相机后面时。如果我是对的,这些xy坐标与设备像素不完全对齐,我的意思是这些xy坐标在某种程度上是像素间的值。因此,它们不适合从视口对齐纹理(如深度贴图)中采样。实际纹理采样可能因几何体而异。在这里将这些值捕捉到实际像素有意义吗?类似于圆到最近的像素位置。@Geri:光栅化就是这样工作的,所以它非常好。按照惯例,碎片都在像素中心采样。但我要指出的是,你不想四舍五入。您要做的是捕捉到最近的像素中心。只需在GLSL中隐式地从浮点转换为整数,而不是四舍五入即可实现这一点,这将为您提供足够的空间,而这正是您需要捕捉到0.5的行为。如果使用viewportCoord值进行纹理查找,实际上,如果使用最近邻过滤,则不必担心这些问题。嘿,使用最近邻听起来非常棒,谢谢!仅当我可以将其设置为系统导出的摄影机深度纹理时。它以某种方式在内部统一管理。希望它能工作,我也可以在那里节省性能。@现在有了你的更新,我真的很困惑。如果需要逐像素着色,则必须使用逐像素着色,否则将使用逐顶点着色并获得线性插值颜色。这是没有办法的。尝试在透视图分割后插值ndc将中断,因为OpenGl将为您提供插值。您可以使用noperspective,但为什么不使用gl_FragCoord呢?此答案中建议的解决方案存在一个普遍问题:它在一般情况下不起作用。如果不考虑需要查看完整基本体的剪裁,就不可能获得有意义的NDC坐标,因此在顶点着色器中是不可能做到的。当有透视投影和与近平面相交的基本体时,问题就会出现,特别是当基本体的至少一个点位于摄影机前面,而至少另一个点位于摄影机后面时。