Correct ray calculation

I am using compute shader to raycast a scene. I already had a camera model but it is distorted in the ends - that’s why I wanted to use the monogame lookat and projection matrices for raycasting.

I found this site: How to create correct ray tracing camera. – bmrysz.wordpress.com

but it doesnt turn out right yet.

I create my conventional view and projection matrix (that works correctly for rendering mesh-models) like so:

// ViewMatrix:
	var cameraRotation = Matrix.CreateRotationX(_pitch) * Matrix.CreateRotationY(_yaw);
			var transformedForward = Vector3.Transform(Vector3.Forward, cameraRotation);
			var direction = CameraPosition + transformedForward;

			Matrices["View"] = Matrix.CreateLookAt(CameraPosition, direction, Vector3.Up);

// ProjectionMatrix:
	Matrices["Projection"] = Matrix.CreatePerspectiveFieldOfView(
				FieldOfView, 
				GraphicsDeviceAdapter.GraphicsDevice.Viewport.AspectRatio, 
				0.1f, 
				1000.0f);

//Inverse:
		Matrices["InverseViewProj"] = Matrix.Invert(Matrix.Multiply(Matrices["View"], Matrices["Projection"]));

It works just fine for models but when I use these matrices inside my compute shader the rays are not calculated correctly:

float2 screenCoordinate = float2((float) globalId.x * OneOverScreenWidth, (float) globalId.y * OneOverScreenHeight); // (what this basically does is map the globalId that ranges from 0 to Width/Height of rendertarget to 0 to 1.

    float2 uv = (screenCoordinate * 2.0f) - float2(1, 1);
   
    Ray ray = (Ray) 0;

    float4 screenSpaceFar = float4(uv, 1.0f, 0.0f);
    float4 screenSpaceNear = float4(uv, 0.0f, 0.0f);
	
    float4 far = mul(ViewProjectionInverse, screenSpaceFar); // changing order doesnt change the outcome
    far /= far.w;
    float4 near = mul(ViewProjectionInverse, screenSpaceNear);
    near /= near.w;
    
    ray.Origin = CameraPosition;
    ray.Dir = normalize(far.xyz - near.xyz);
    ray.DirReciprocal = rcp(ray.Dir);

Basically it’s very similar to ViewPort.Unproject but it doesnt turn out right:

How can I create rays that exactly corresponds with the perspective of mesh-rendering?

Thank God, i found the solution: what was required were the homogenous coordinates meaning:

float2 screenCoordinate = float2((float) globalId.x * ScreenWidth, (float) globalId.y * ScreenHeight); 
    float2 uv = (screenCoordinate * 2.0f) - float2(1, 1);
   
    Ray ray = (Ray) 0;
	
    float4 screenSpaceFar = float4(float2(uv.x, -uv.y), 1.0f, 1.0f);
    float4 screenSpaceNear = float4(float2(uv.x, -uv.y), 0.0f, 1.0f);
	
    float4 far = mul(screenSpaceFar, ViewProjectionInverse);
    far /= far.w;
    float4 near = mul(screenSpaceNear, ViewProjectionInverse);
    near /= near.w;
    
    ray.Origin = CameraPosition;
    ray.Dir = normalize(far.xyz - near.xyz);
    ray.DirReciprocal = rcp(ray.Dir);

Now it works fine:


1 Like