我有使用SDF函数关于GLSL球体跟踪/光线跟踪一些问题:GLSL:如何使用投影矩阵计算光线方向?
我的主程序(C++,使用福尔康)生成画面四并将该顶点着色器与每顶点inPosition
。顶点着色器可以访问窗口分辨率,投影矩阵和视图矩阵。投影矩阵由glm::perspective(45.0, 1920/1080, 0.1, 100.0);
生成。
在顶点着色器中,我尝试通过图像平面计算从原点vec4(0.0, 0.0, 0.0, 1.0)
来的光线(使用齐次坐标的位置和方向)。我很困惑放置图像平面的位置,现在选择vec4(inPosition.xy, -5.0, 1.0)
来查看负Z轴。
以下代码表示我的顶点着色器:
#version 450
#extension GL_ARB_separate_shader_objects : enable
struct Ray
{
vec4 pos;
vec4 dir;
};
layout(binding = 0) uniform UniformBufferObject {
vec3 res;
mat4 projection;
mat4 view;
} ubo;
layout(location = 0) in vec3 inPosition;
layout(location = 0) out vec3 iResolution;
layout(location = 1) out Ray iRay;
out gl_PerVertex {
vec4 gl_Position;
};
void main() {
fragCoord = vec2(
((inPosition.x+1)/2) * (ubo.res.x-1),
((inPosition.y+1)/2) * (ubo.res.y-1)
);
iResolution = ubo.res;
gl_Position = vec4(inPosition, 1.0);
vec4 direction = inverse(ubo.projection) * vec4(inPosition.xy, -5.0, 1.0);
iRay.dir = direction;
iRay.pos = vec4(direction.xy, 0.0, 1.0);
}
我使用的投影矩阵的方向变换到世界空间和扭曲单位立方体到窗口的分辨率。但是,在我的片段着色器中,SDF函数和交叉点无法正常工作。如果为距离和半径设置相同的值,我只能看到一个球体。看片段着色器:
#version 450
#extension GL_ARB_separate_shader_objects : enable
struct Ray
{
vec4 pos;
vec4 dir;
};
layout(location = 0) in vec3 iResolution;
layout(location = 1) in Ray iRay;
layout(location = 0) out vec4 outColor;
float sdfSphere(vec3 p, float r)
{
return length(p) - r;
}
bool intersect(Ray ray)
{
for(int i = 0; i < 100; i++) {
float hit = sdfSphere((ray.pos.xyz + vec3(0.0, 0.0, -11.0)), 11.0);
ray.pos += hit * ray.dir;
if (hit < 0.001) {
return true;
}
}
return false;
}
void main()
{
bool result = intersect(iRay);
if(result == false) {
outColor = vec4(0.0, 0.0, 0.0, 1.0);
} else {
outColor = vec4(1.0, 0.0, 0.0, 1.0);
}
}
我的问题是:如何正确应用投影矩阵?如果它已经正确应用,为什么我无法为SDF球体设置不同的位置/半径?
如果你使用Vulkan,你应该这样标记而不是使用OpenGL标记。 – BDL