#Issues With Drawing Lines Using Shader

5 messages · Page 1 of 1 (latest)

fallow nimbus
#

I am trying to write a shader that draws lines. I am doing this by projecting the 3d points into uv coordinates using the camera's viewProjection matrix. I belive this should be the correct way to do this however I am not certain as the projected points appear to be significantly offset from their world space counterparts especially when the camera's target is not (0,0,0) as shown in the video attached.

here is the fragment shader I am using



void main()
{
    // convert pixel width to uv width
    float thicknessUV = inlineWidth / (screenSize.x * 2);
    
    // foreach line to draw
    for (int i = 0; i < inlineSegmentsCount; i++) {
        
        // these are the lines with start and ends that are the same values as drawn
        InlineSegment lineSegment = inlineSegments[i];
        
        vec4 p1 = vec4(lineSegment.start, 1.0);
        vec4 p2 = vec4(lineSegment.end, 1.0);
        
        // Transform p1 to clip space
        vec4 clipSpacePositionP1 = viewProjectionMatrix * p1;
        vec4 clipSpacePositionP2 = viewProjectionMatrix * p2;

        // Divide by w in clip space to get NDC space
        vec3 ndcSpacePositionP1 = clipSpacePositionP1.xyz / clipSpacePositionP1.w;
        vec3 ndcSpacePositionP2 = clipSpacePositionP2.xyz / clipSpacePositionP2.w;
        
        // Transform to screen space
        vec3 projCoordsP1 = ndcSpacePositionP1 * 0.5 + 0.5;
        vec3 projCoordsP2 = ndcSpacePositionP2 * 0.5 + 0.5;
        
        // draw line
        vec2 line = drawLineWithPercentage(projCoordsP1.xy, projCoordsP2.xy, thicknessUV);
        
        // draw circle at each end
        float circle1 = drawCircle(projCoordsP1.xy, 0.003);
        float circle2 = drawCircle(projCoordsP2.xy, 0.003);
        
        if (circle1 > 0.0 || circle2 > 0.0) {
            finalColor = vec4(1,0,0,1);
            return;
        }
        // [...] further doesn't matter as the points drawn by the circles are offset as well.
    }
}
#

this is the function used to get the matrix passed into the shader.

public static unsafe Matrix4x4 GetCameraViewProjectionMatrix(ref Camera3D camera)
    {
        fixed (Camera3D* cameraPtr = &camera)
        {
            // Matrix4x4 transformMatrix = Rlgl.rlGetMatrixTransform();
            // Matrix4x4 modelview = Rlgl.rlGetMatrixModelview();
            Matrix4x4 cameraViewMatrix = Raylib.GetCameraMatrix(camera);
            Matrix4x4 projectionMatrix = Raylib.GetCameraProjectionMatrix(cameraPtr, 1);
            
            return projectionMatrix * cameraViewMatrix;
        }
    }

Video uploaded because its too large for discord: https://streamable.com/dkl5h9

#

the green lines with blue points are the correct position using debug draw

black lines and red points are the projected using the shader and the viewProjectionMatrix

fallow nimbus
#

I fixed this issue. It was to do with the viewProjection matrix

#

the new code I am using is

public static Matrix4x4 GetCameraViewProjectionMatrix(ref Camera3D camera)
    {
        // only orthographic camera is supported
        float aspect = Raylib.GetScreenWidth() / (float)Raylib.GetScreenHeight();
        double top = camera.fovy/2.0;
        double right = top*aspect;

        // Calculate projection matrix from orthographic
        Matrix4x4 matProj = Raymath.MatrixOrtho(-right, right, -top, top, 0.01f, 1000f);
    
        // Calculate view matrix from camera look at (and transpose it)
        Matrix4x4 matView = Raymath.MatrixLookAt(camera.position, camera.target, camera.up);
        
        return matProj * matView;
    }