Table constraint, number of row taken by a fk key
One way would be to add a column (say project_title_no) that allows only 3 possible values and a unique constraint on (project_id, project_title_no):

ALTER TABLE ProjectTitles
  ADD COLUMN project_title_no smallint not null ;

ALTER TABLE ProjectTitles
  ADD CHECK (project_title_no IN (1,2,3)) ;

ALTER TABLE ProjectTitles
  ADD UNIQUE (project_id, project_title_no) ;


One drawback is that this column is not automatically filled and you have to supply the value, either in your application or by creating suitable insert/update procedures (that check first if for example, for some project there are rows with title_no 1 and 3, and fill the missing 2).

It requires 2 extra bytes* which seems a lot for only 3 values but it's easily modifiable (the requirements change to 10 titles per project? Easy, just change the CHECK constraint.)  

There are no table locking required though or race conditions that come with a trigger solution.