• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

3D drawing to surface/outline shaders

W

warius

Guest
I'm having issues trying to draw a 3d object to a surface (in an attempt to make an outline shader).
scr2.png
Context:
In my 3D scene I'm trying to isolate a plant by drawing it to a surface, so that I can use the surface later for an outline shader, exactly like this technique but in 3D:
Although the plant is just a flat plane, I'm planning to use the outline shader for more complex 3D models at a later stage.
I imagine the shader to become similar to the shader discussed here: https://gamedev.stackexchange.com/questions/68401/how-can-i-draw-outlines-around-3d-models

Surface issues:
I save the surface to a file so that I can see what is drawn on it. I expect the file output to contain the plant placed properly inside the projection on its own, but unfortunately the saved surface comes out empty.
I realise that I won't see the surface's contents in the scene as I'm not actually drawing the surface yet, I'm just saving it to a file.

I've tried to follow tips from this thread, which I've tried to translate to my own code: https://forum.yoyogames.com/index.php?threads/solved-3d-surfaces-wont-work.30059/
Apparently to draw properly inside the surface, the projection has to be setup again inside of it, and after the surface target is reset the camera needs to be applied again for objects to be drawn correctly after this object.
I'm having no luck with the implementation however.

Here is the camera setup, which is in the control object:

Create event
GML:
camera = camera_create();
view_enabled = true;
view_set_visible(0, true);
view_set_camera(0, camera);
Draw event:
GML:
//update every frame
mat_view = matrix_build_lookat(x,y,18,x+1,y,18,0,0,1);
mat_proj = matrix_build_projection_perspective_fov(-60,-display_get_width()/display_get_height() ,0.1,20000);

matrix_set(matrix_world, matrix_build_identity() );
camera_set_view_mat(camera, mat_view);
camera_set_proj_mat(camera, mat_proj);
Here is the Draw event of the plant object, where I target the surface:
GML:
//already created, but recreate if destroyed
if !surface_exists(surfo)
   {
   surfo = surface_create(1366,768); //placeholder values
   }
//target the surface
surface_set_target(surfo);


//set the camera projection within the surface
matrix_set(matrix_world, matrix_build_identity() );
camera_set_view_mat(oControl.camera, oControl.mat_view);
camera_set_proj_mat(oControl.camera, oControl.mat_proj);
camera_apply(oControl.camera);

//draw the plant
vertex_submit(model_plant,pr_trianglelist,sprite_get_texture(sPlant,0) );

//for analysis purposes: save surface to file to review results
if keyboard_check_pressed(ord("S"))
   {
    var file;
    file = get_save_filename("screenshot|*.png", "");
    if file != ""
       {
       surface_save(surfo,file);
       }
   }

surface_reset_target();
//reapply the camera settings immediately after resetting the surface
camera_apply(oControl.camera);
Can somebody explain what I'm doing wrong with the surface drawing?

As an aside:
Afaik (fragment) shaders can't actually access fragments other than the current fragment unless the data is looked up in some 2D buffer but I need the actual 3D silhouette to make this shader technique work properly.
Are there approaches to implementing this outline shader in 3D without using surfaces?
 
Top