Graphics Pipeline: Viewspace & Back face culling

1 view (last 30 days)
I'm attempting to model a simple graphics pipeline - using Matlab at the moment as a modelling tool to get the transformations correct. I appreciate there are software tools that would make this easier - but I'm looking to understand the maths behind it and hence am looking to mostly use simple functions & matrices that I'm learning from a book (very retro!).
I've successfully got through the stages of defining simple objects and converting them into a universal world space - but have come unstuck with the mathematics required to convert an object into view space and the back face culling.
I believe my view space transformation is correct because when I plot the composite vectors they appear correct - but - when I do the back-face culling, it seems to fail to remove the correct triangles. Given that it depends only on two things, the line-of-sight vector and face normals, I can't work out what I'm doing wrong.
When defining the triangles in local definition space, I did it so that all the normals pointed outwards. I've put my results into the image below
My questions are:
- Have I gone wrong, or are my expectations incorrect? - If so where, and how do I fix?
---
## Progress
I've plotted the normal's of all the shapes when in view space. They have all been inverted and now point inwards. Is this a property of the transformation and could it be responsible - or should this have no effect because all the polygons are affected the same?
(Have changed the code to show this)
clc; clear all; close all;
%============Initial verticies & Faces of the shape===========
[s1_vtx,s1_fcs] = Pyramid();
[s2_vtx,s2_fcs] = Cube();
%==============Transform Shape 1 ======================
Tx = 0; Ty = 0; Tz = 0; %Translation vectors for x,y,z axes
Sx = 2; Sy = 2; Sz = 2;%Scaling factors in x,y,z dimensions
Rx = pi/2; Ry = pi/4; Rz = pi/4; %Rotating factors in x,y,z dimensions
transform = scale(Sx,Sy,Sz)*rotate(Rx,0,0)*translate(Tx,Ty,Tz); %Merge transforms together
s1_vtx = transform*vertcat(s1_vtx,(ones(1,length(s1_vtx)))); %Add row of ones to end for multiplication
s1_vtx = s1_vtx(1:3,:); %And remove afterwards
%==============Transform Shape 2 ======================
Tx = 0.5; Ty = 0; Tz = 0.5;
transform = scale(1,2,1)*translate(Tx,Ty,Tz);
s2_vtx = transform*vertcat(s2_vtx,(ones(1,length(s2_vtx))));
s2_vtx = s2_vtx(1:3,:);
%======Create World Space ===========
ws_vtx = horzcat(s1_vtx(1:3,:), s2_vtx(1:3,:)); %remove homogenous column for patching
ws_fcs = horzcat(s1_fcs,(s2_fcs+(length(s1_vtx))));
%======Plot World Space ===========
grid on; hold on;
scatter3(ws_vtx(1,:),ws_vtx(2,:),ws_vtx(3,:)) %Plot all the points
patch('Faces',ws_fcs','Vertices',ws_vtx','Facecolor', 'none');
for i = 1:length(ws_vtx)
str = sprintf('%d',i);
text(ws_vtx(1,i),ws_vtx(2,i),ws_vtx(3,i), str,'FontSize',16, 'Color','r', 'FontWeight','b');
end
points = zeros(3,3); %Contains 1 triangle
for i = 1:length(ws_fcs); %For each triangle
points(:,1:3) = ws_vtx(:,ws_fcs(1:3,i));
U = points(:,2) - points(:,1); %Get two non-parallel vectors
V = points(:,3) - points(:,1);
average = [0,0,0];
for j = 1:length(points)
average(j) = (points(j,1) + points(j,2) + points(j,3))/3;
end
N = cross(U,V)/norm(cross(U,V)); %Normal, normalised to mag 1
scatter3(average(1),average(2),average(3));
plot3([average(1), average(1)+N(1)],[average(2), average(2)+N(2)],[average(3), average(3)+N(3)]);
end
%==================Create view matrix===================
focus = [1.5,0,1.5]; %The point we're looking at
Cx = 3; Cy = -3; Cz = 3; %Position of camera
Vspec = [0;0;1]; %Specified up direction
T = viewMat(focus, [Cx,Cy,Cz],Vspec); %Create viewspace transform matrix
p = norm(focus - [Cx,Cy,Cz]);
U = T(1,1:3); V = T(2,1:3); N = T(3,1:3); %New Up, Right & View direction vectors
%============Plot the camera vectors=================
scatter3(Cx,Cy,Cz,'s') %Plot the camera position
plot3([Cx, Cx+p*N(1)],[Cy, Cy+p*N(2)],[Cz, Cz+p*N(3)]);
plot3([Cx, Cx+V(1)],[Cy, Cy+V(2)],[Cz, Cz+V(3)]);
plot3([Cx, Cx+U(1)],[Cy, Cy+U(2)],[Cz, Cz+U(3)]);
%==================Transform into View Space===================
ws_vtx = T*vertcat(ws_vtx,(ones(1, length(ws_vtx)))); %Transform matrix
ws_vtx = ws_vtx(1:3,:); %Remove homogenous dimension
origin = T*[Cx;Cy;Cz;1]; %Transform origin
Cx = origin(1); Cy = origin(2); Cz = origin(3); %remove homogenous dimension
focus = (T*horzcat(focus,1)')';%Transform focus point
focus = focus(:,1:3);%remove homogenous dimension
%==================Plot View Space=================
figure(); hold on; grid on;
patch('Faces',ws_fcs','Vertices',ws_vtx','Facecolor', 'none');
scatter3(Cx, Cy, Cz, 's');
scatter3(focus(1), focus(2), focus(3), 's');
plot3([Cx, focus(1)],[Cy, focus(2)],[Cz,focus(3)], 'g');
for i = 1:length(ws_vtx)
str = sprintf('%d',i);
text(ws_vtx(1,i),ws_vtx(2,i),ws_vtx(3,i), str,'FontSize',16, 'Color','r', 'FontWeight','b');
end
%================Plot normals of world space==============
for i = 1:length(ws_fcs); %For each triangle
points(:,1:3) = ws_vtx(:,ws_fcs(1:3,i));
U = points(:,2) - points(:,1); %Get two non-parallel vectors
V = points(:,3) - points(:,1);
average = [0,0,0];
for j = 1:length(points)
average(j) = (points(j,1) + points(j,2) + points(j,3))/3;
end
N = cross(U,V)/norm(cross(U,V)); %Normal, normalised to mag 1
scatter3(average(1),average(2),average(3));
plot3([average(1), average(1)+N(1)],[average(2), average(2)+N(2)],[average(3), average(3)+N(3)]);
end

Answers (1)

Mike Garrity
Mike Garrity on 9 Feb 2016
Are you sure your triangle orientations are consistent?
For the calculations you're using for normals and backfaces, they must be. This means that if you apply the right-hand rule to the vertices of each face, then your thumb should be pointing out of the solid.
  2 Comments
David Hood
David Hood on 9 Feb 2016
Is this the same as having the normal of each triangle pointing out of the solid? (as in my picture)...if it is then yes, if it isn't - then I guess I need to go through and reassign the triangles
Mike Garrity
Mike Garrity on 10 Feb 2016
If you're computing those normals from the points in a consistent way, then yes, all the normals pointing out means that the triangles are consistently oriented.
But I asked because I don't see the normals in your picture of the arrow. Only in the picture of the cube. The fact that the triangles are consistently in one model doesn't imply anything about the other model. Have you done the same plot for the arrow?

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!