I am trying to render a raymarched scene in a GLSL fragment shader. I am able to draw the scene successfully when not using a MVP matrix and just marching a ray from a specified camera position in a direction Scene rendered with fixed view, however when I try and change my code to use a model view projection matrix (to allow me to use a proper camera to move around the scene) I simply get a black screen. I'm following the instructions for using the model, view projection matrices with ray marching from here
My vertex shader when not using model view projection
#version 330 core
layout (location = 0) in vec2 position;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
}
My fragment shader when not using model view projection
#version 330 core
#define MAX_VOXELS 128
#define MAX_STEPS 100
#define MAX_DIST 100.
#define SURF_DIST .001
uniform float iTime;
uniform vec2 iResolution;
uniform vec3 camPosition;
uniform vec3 camDirection;
uniform vec3 voxelPositions[MAX_VOXELS];
uniform float voxelSizes[MAX_VOXELS];
uniform int voxelCount;
out vec4 fragColor;
float sdBoundingBox( vec3 p, vec3 b, float e )
{
p = abs(p )-b;
vec3 q = abs(p+e)-e;
return min(min(
length(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),
length(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),
length(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));
}
float GetDist(vec3 point) {
float planeDist = point.y;
float d = 10000.0;
for(int i = 0; i < voxelCount; i++)
{
vec3 voxelSize = vec3(voxelSizes[i],voxelSizes[i],voxelSizes[i]);
float vox = sdBoundingBox(point-voxelPositions[i], voxelSize, 0.015);
d = min(d, vox);
}
return d;
}
float RayMarch(vec3 rayOrigin, vec3 rayDir) {
float dO=0.;
for(int i=0; i<MAX_STEPS; i++) {
vec3 p = rayOrigin + rayDir*dO;
float dS = GetDist(p);
dO += dS;
if(dO>MAX_DIST || dS<SURF_DIST) break;
}
return dO;
}
vec3 GetNormal(vec3 p) {
float d = GetDist(p);
vec2 e = vec2(.001, 0);
vec3 n = d - vec3(
GetDist(p-e.xyy),
GetDist(p-e.yxy),
GetDist(p-e.yyx));
return normalize(n);
}
float GetLight(vec3 p) {
vec3 lightPos = vec3(0, 5, 0);
lightPos.xz += vec2(sin(iTime), cos(iTime))*2.;
vec3 l = normalize(lightPos-p);
vec3 n = GetNormal(p);
float dif = clamp(dot(n, l), 0., 1.);
float d = RayMarch(p+n*SURF_DIST*2., l);
if(d<length(lightPos-p)) dif *= .1;
return dif;
}
void main()
{
vec2 uv = (gl_FragCoord.xy-.5*iResolution.xy)/iResolution.y;
vec3 col = vec3(0);
vec3 rayOrigin = camPosition;
vec3 rayDir = normalize(vec3(uv.x, uv.y, 1));
float d = RayMarch(rayOrigin, rayDir);
vec3 p = rayOrigin + rayDir * d;
float dif = GetLight(p);
col = vec3(dif);
col = pow(col, vec3(.4545)); // gamma correction
fragColor = vec4(col,1.0);
}
However when I try to use a model view projection matrix to transform the scene I get nothing but a blank screen.
Here's how I pass my matrices to the shader:
...
glm::mat4 mvp = camera.GetProjMatrix(width, height) * camera.GetViewMatrix() * octree.getTransform();
auto inverseMatrix = glm::inverse(mvp);
raymarchShader.setMat4("mvp", mvp);
raymarchShader.setMat4("inverseMatrix", inverseMatrix);
My model view projection matrix vertex shader
#version 330 core
layout (location = 0) in vec2 position;
out vec4 near_4;
out vec4 far_4;
uniform mat4 mvp;
uniform mat4 inverseMatrix;
void main() {
gl_Position = mvp * vec4(position, 0.0, 1.0);
vec2 pos = gl_Position.xy/gl_Position.w;
near_4 = inverseMatrix * (vec4(pos, -1.0, 1.0));
far_4 = inverseMatrix * (vec4(pos, 1.0, 1.0));
}
And here's the updated fragment shader
...
in vec4 near_4; //for computing rays in fragment shader
in vec4 far_4;
...
void main()
{
vec2 uv = (gl_FragCoord.xy-.5*iResolution.xy)/iResolution.y;
vec3 col = vec3(0);
vec3 rayOrigin = near_4.xyz/near_4.w;
vec3 far3 = far_4.xyz/far_4.w;
vec3 rayDir = far3- rayOrigin;
rayDir = normalize(rayDir);
float d = RayMarch(rayOrigin, rayDir);
vec3 p = rayOrigin + rayDir * d;
float dif = GetLight(p);
col = vec3(dif);
col = pow(col, vec3(.4545)); // gamma correction
fragColor = vec4(col,1.0);
}
This is the final resultWhat exactly am I doing wrong here? How do I compute ray origin and direction for raymarching using a model view projection matrix?