J'ai quelques problèmes concernant la marche de traçage/rayons sphère GLSL en utilisant les fonctions SDF:GLSL: Comment calculer une direction de rayon en utilisant la matrice de projection?
Mon programme principal (C++, en utilisant Vulkan) génère un quad écran et fournit le vertex shader avec un par-sommet inPosition
. Le vertex shader a accès à la résolution de la fenêtre, à la matrice de projection et à la matrice de vue. La matrice de projection est générée avec glm::perspective(45.0, 1920/1080, 0.1, 100.0);
.
Dans le vertex shader, j'essaie de calculer un rayon (position et direction en utilisant des coordonnées homogènes) provenant de l'origine à vec4(0.0, 0.0, 0.0, 1.0)
à travers le plan image. Je suis confus où placer le plan de l'image et a choisi vec4(inPosition.xy, -5.0, 1.0)
pour maintenant regarder le long de l'axe z négatif.
Le code suivant représente mon vertex shader:
#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);
}
J'utilise la matrice de projection pour transformer les directions à l'espace mondial et déformer le cube de l'unité à la résolution de la fenêtre. Cependant, dans mon fragment shader, les fonctions SDF et les intersections ne fonctionnent pas correctement. Je peux seulement voir une sphère si je mets les mêmes valeurs pour la distance et le rayon. Voir le fragment shader:
#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);
}
}
Ma question est: Comment j'appliquer la matrice de projection correctement? Et si elle est déjà appliquée correctement, pourquoi suis-je incapable de définir une position/un rayon différent pour la sphère SDF?
Si vous utilisez Vulkan, vous devez le marquer de cette façon au lieu d'utiliser le tag OpenGL. – BDL