Changing $wp_query->posts_per_page in the template with a new instance of WP_Query doesn't work because the requested page number has already been validated against $wp_query->max_num_pages by WordPress before the template is executed. As the requested page is more than this value for the main query, the 404.php template is served instead, and your code in the home.php template isn't even executed.
The trick is to get $wp_query->max_num_pages to match the true maximum number of pages by manipulating the main query to use your custom arguments, before the main query is performed. $wp_query->posts_per_page and $wp_query->found_posts will then match your results, resulting in a $wp_query->max_num_pages that does too.
The best way, in my opinion, is to edit the main query arguments before the main query gets its posts. For example, you could add the following to your theme's functions.php:
function custom_main_query($query){
if(is_admin()) return;
if(!$query->is_main_query()) return;
if(is_home()) $query->set('posts_per_page', 3);
}
add_action('pre_get_posts', 'custom_main_query');
This will then mean a standard loop will work out the box too:
// Standard loop
while (have_posts()) : the_post();
the_title();
endwhile;
// Navigation links
previous_posts_link('Newer Entries');
next_posts_link('Older Entries');
If you are only manipulating the number of posts per page, it may be better to change the default posts per page by going to Options => Reading in WordPress admin and setting Blog pages show at most to 3 here instead.