如何获得给定像素在世界坐标中的颜色? [英] How to get the color of a given pixel in world coordinates?
本文介绍了如何获得给定像素在世界坐标中的颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我使用的是戈多的碎片着色器。我可以获得当前像素的世界坐标,如下所示:
vec3 pixel_world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
假设我将Pixel_world_pos.y增加10,我想知道该像素是什么颜色。我怎么才能弄清楚这一点呢?
我知道信息存储在UV中,但我使用的是世界坐标,而不是UV坐标.
推荐答案
让我们仔细看看这行:
vec3 pixel_world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
这里,您使用VERTEX
,它将位于视图空间中。用w
坐标上的1.0
将其增加为vec4
。然后使用CAMERA_MATRIX
进行转换。
CAMERA_MATRIX
将vec4
从视图空间带到世界空间(即CAMERA_MATRIX
是逆视图矩阵)。然后从其中提取vec3
,丢弃w
。
好的,下面假设您这样修改y
坐标:
vec3 pixel_world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
pixel_world_pos.y = pixel_world_pos.y + 10.0;
您想知道它在视图空间的什么位置。Well…我们做我们做过的事情,但情况正好相反。
我们做的最后一件事是丢弃w
。我们需要向后添加w
:
vec3 pixel_world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
pixel_world_pos.y = pixel_world_pos.y + 10.0;
vec4 tmp = vec4(pixel_world_pos, 1.0);
这是在假定CAMERA_MATRIX
是3D仿射变换的情况下工作的。
您之前做的事情是使用CAMERA_MATRIX
转换向量。要撤消此操作,我们需要用CAMERA_MATRIX
(也称为视图矩阵)。戈多将其提供为INV_CAMERA_MATRIX
。因此,我们可以通过以下方式进行转换:
vec3 pixel_world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
pixel_world_pos.y = pixel_world_pos.y + 10.0;
vec4 tmp = INV_CAMERA_MATRIX * vec4(pixel_world_pos, 1.0);
你做的第一件事就是增加向量。因此,我们现在放弃w
:
vec3 pixel_world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
pixel_world_pos.y = pixel_world_pos.y + 10.0;
vec3 pixel_view_pos = (INV_CAMERA_MATRIX * vec4(pixel_world_pos, 1.0)).xyz;
就这样了。
哦,等等,您想读取像素。所以我们需要紫外线。下一步是使用PROJECTION_MATRIX
。
vec3 pixel_world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
pixel_world_pos.y = pixel_world_pos.y + 10.0;
mat4 WORLD_TO_CLIP_MATRIX = PROJECTION_MATRIX * INV_CAMERA_MATRIX;
这里我将视图矩阵(INV_CAMERA_MATRIX
)与投影矩阵(PROJECTION_MATRIX
)组合在一起,这样我们就可以直接从世界空间转换到剪辑空间。也就是说,INV_CAMERA_MATRIX
将我们从世界空间带到视图空间,而PROJECTION_MATRIX
将我们从视图空间带到剪辑空间。在我们进一步讨论之前,我们需要处理PROJECTION_MATRIX
保持投影变换(令人惊讶!)这一事实,它不是仿射变换。因此,我们不应该添加和删除w
,而是执行以下操作:
vec3 pixel_world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
pixel_world_pos.y = pixel_world_pos.y + 10.0;
mat4 WORLD_TO_CLIP_MATRIX = PROJECTION_MATRIX * INV_CAMERA_MATRIX;
vec4 pixel_clip_pos = WORLD_TO_CLIP_MATRIX * vec4(pixel_world_pos, 1.0);
vec3 pixel_nds_pos = pixel_clip_pos.xyz / pixel_clip_pos.w;
这里的dns
代表标准化的设备空间。我们现在可以放弃z
:
vec3 pixel_world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
pixel_world_pos.y = pixel_world_pos.y + 10.0;
mat4 WORLD_TO_CLIP_MATRIX = PROJECTION_MATRIX * INV_CAMERA_MATRIX;
vec4 pixel_clip_pos = WORLD_TO_CLIP_MATRIX * vec4(pixel_world_pos, 1.0);
vec2 uv = (pixel_clip_pos.xyz / pixel_clip_pos.w).xy * 0.5 + vec2(0.5, 0.5);
但是,结果是,如果我们简单地做(pixel_clip_pos.xyz / pixel_clip_pos.w).xy
,我们就会得到原点在屏幕中心的坐标。所以我们需要缩放和偏移它们,使它们从左下角的0变为右上角的1。这就是屏蔽UV的工作方式。
顺便说一句,如果您要计算深度,z
我们丢弃的z
会很有用。
我们完成了:
shader_type spatial;
render_mode unshaded;
void fragment()
{
vec3 pixel_world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz;
pixel_world_pos.y = pixel_world_pos.y + 10.0;
mat4 WORLD_TO_CLIP_MATRIX = PROJECTION_MATRIX * INV_CAMERA_MATRIX;
vec4 pixel_clip_pos = WORLD_TO_CLIP_MATRIX * vec4(pixel_world_pos, 1.0);
vec2 uv = (pixel_clip_pos.xyz / pixel_clip_pos.w).xy * 0.5 + vec2(0.5, 0.5);
ALBEDO = texture(SCREEN_TEXTURE, uv).rgb;
}
顺便说一下,您需要注意您计算的uv
可能超出SCREEN_TEXTURE
的边缘。
这篇关于如何获得给定像素在世界坐标中的颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文