Issues with Stacking Surfaces/Shaders (Post-Processing)

So basically...
I've been trying to work on a potential method for stacking surfaces in order to pass multiple post-processing shaders, and for some reason I've been having a hard time trying to get it to render. (I've also checked out the [Solved] Shaders: Post Processing, Multiple Passes thread, but for some reason I couldn't find a solution that worked).

Here's the relevant code:

The Create Event:
GML:
/// @desc Basic Setup

//---------------------------------Setup
//-----Disable App Surface Drawing
application_surface_draw_enable(false);            //Stops the application surface from
                                                //drawing automatically.
//-----Setup Surfaces
//Temp Variables
shaViewW = camera_get_view_width(global.cam);    //Gets camera info
shaViewH = camera_get_view_height(global.cam);

shaViewX = camera_get_view_x(global.cam);
shaViewY = camera_get_view_y(global.cam);

//Actual Surfaces
surPassA = surface_create(shaViewW, shaViewH);    //Creates Surfaces
surPassB = surface_create(shaViewW, shaViewH);

//-----Sub Surfaces
surBlur1 = -1;
surBlur2 = -1;
The Draw Event:

GML:
///@desc Ready Surfaces

//---------------------------------Surface Checking
//-----Ready Surfaces        -Checks if surface exists; if not, creates a new surface.

//Main Surfaces
if (!surface_exists(surPassA)) surPassA = surface_create(shaViewW, shaViewH);
if (!surface_exists(surPassB)) surPassB = surface_create(shaViewW, shaViewH);

//Extra Surfaces
if (!surface_exists(surBlur1)) surBlur1 = surface_create(shaViewW, shaViewH);
if (!surface_exists(surBlur2)) surBlur2 = surface_create(shaViewW, shaViewH);
The Draw_GUI_Begin Event

GML:
/// @description Post-Shaders

//---------------------------------Setup DayCycle Shader
#region
//-----Setup Shader
//Set Variables
var tempUCol;
var tempUConSatBrt;
var tempColorMix;
var tempConSatBrtMix;

var tempTimeShader = Sha_DayCycle;

//Set Shader
surface_set_target(surPassA)
shader_set(tempTimeShader);

//Pass Variables
with (Obj_DayManager)
{
    tempColorMix            = colorMix;
    tempConSatBrtMix        = conSatBrtMix;
}

var tempUCol                = shader_get_uniform(tempTimeShader, "uColor");
var tempUConSatBrt            = shader_get_uniform(tempTimeShader, "uConSatBrt");
shader_set_uniform_f_array    (tempUCol, tempColorMix);
shader_set_uniform_f_array    (tempUConSatBrt, tempConSatBrtMix)

//Draw Surface
draw_surface(application_surface, shaViewX, shaViewY);

//Cleanup
shader_reset();
surface_reset_target();

#endregion

//---------------------------------Setup Bloom Shader
#region

//-----Setup Shader
//Set Variables
/*var threshold        = 0;
var range            = 0;
var tempBloomShader = Sha_Bloom;

//Set Shader
surface_set_target(surBlur1)
shader_set(tempBloomShader);

//Pass Variables
tempUBloomThreshold       = shader_get_uniform(tempBloomShader, "bloomThreshold");
tempUBloomRange            = shader_get_uniform(tempBloomShader, "bloomRange");
shader_set_uniform_f(tempUBloomThreshold, threshold);
shader_set_uniform_f(tempUBloomRange, range);

//Draw Surface
draw_surface(surPassA, shaViewX, shaViewY);
surface_reset_target();
surface_set_target(surPassB);
draw_surface(surBlur1, shaViewX, shaViewY);

//Cleanup
shader_reset();
surface_reset_target();*/

//Quick pass since shader isn't finished
surface_set_target(surPassB);
draw_surface(surPassA, shaViewX, shaViewY);
surface_reset_target();

#endregion

//---------------------------------Draw Shadows
#region
//-----Set Shader
surface_set_target(surPassA)

//Set Variables
var tempSurShadow;
var tempOpacity;

//-----Draw Surface
draw_surface(surPassB, shaViewX, shaViewY);        //Drawing shadows by grabbing sprite data and drawing
                                                                               //modified sprites to a new surface, which then gets
with (Obj_Shadows)                                               //added to surPassA.
{
    tempSurShadow    = surShadow;
    tempOpacity        = shadowOpacity;
}
draw_set_alpha(tempOpacity);
draw_surface(tempSurShadow, shaViewX, shaViewY);
draw_set_alpha(1);
surface_reset_target();

#endregion

//---------------------------------Draw Surface
#region
//-----Draw Surfaces
draw_surface(surPassA, shaViewX, shaViewY);     //Draws the surface

//Clean Everything Up
//Might need this later (ignore me)
#endregion
Oh, and I might as well drop the code for the sprite shadows just in case:

The Create Event
GML:
/// @desc Create Surface

//---------------------------------Create Shadow Surface
var screenWidth = MAC_SCREENWIDTH;
var screenHeight = MAC_SCREENHEIGHT;

surShadow = surface_create(screenWidth, screenHeight);
shadowOpacity = -1;
The Draw Event
GML:
//---------------------------------Dynamic Shadows
//-----Change Draw Settings
gpu_set_fog(true, c_black, 0, 1);
if (!surface_exists(surShadow))
{
    event_perform(ev_create, 0);
}
surface_set_target(surShadow);
draw_clear_alpha(c_black, 0);

//-----Set Variables
//Initiate
var shadowPosX;
var shadowPosY;

//Gather Daylight Info
with (Obj_DayManager)
{
    shadowPosX = shadowPosXMix;
    shadowPosY = shadowPosYMix;
    shadowOpacity = shadowOpacityMix;
}

//Gather Room Offset
var swayX;        //The shadow offset
var swayY;        //The Shadow height

switch (global.roomViewPos)
{
    case "North":        //Works
        swayX = -(((room_width / 2) - shadowPosX) / 2) + 0;
        swayY = -(((room_height / 2) - shadowPosY) / 2);
        break;
    case "East":
        swayX = (((room_width / 2) - shadowPosX) / 2) + 270;
        swayY = (((room_height / 2) - shadowPosY) / 2);
        break;
    case "South":        //Works
        swayX = (((room_width / 2) - shadowPosX) / 2) + 0;
        swayY = (((room_height / 2) - shadowPosY) / 2);
        break;
    case "West":
        swayX = -(((room_width / 2) - shadowPosX) / 2) + 270;
        swayY = -(((room_height / 2) - shadowPosY) / 2);
        break;
}

var viewX = camera_get_view_x(view_camera[0]);
var viewY = camera_get_view_y(view_camera[0]);

with (Obj_Par_EntityManager)
{
    //-----Draw Shadow
    draw_sprite_pos(sprite_index, image_index,
    x - (sprite_width / 2) - viewX - swayX, y - viewY - swayY + (z * 2),
    x + (sprite_width / 2) - viewX - swayX, y - viewY - swayY + (z * 2),
    x + (sprite_width / 2) - viewX, y - viewY + (z * 2),
    x - (sprite_width / 2) - viewX, y - viewY + (z * 2),
    1);
}
with (Obj_ShadowMap)
{
    //-----Draw Shadow
    draw_sprite_pos(sprite_index, image_index,
    x - (sprite_width / 2) - viewX - swayX, y - viewY - swayY,
    x + (sprite_width / 2) - viewX - swayX, y - viewY - swayY,
    x + (sprite_width / 2) - viewX, y - viewY,
    x - (sprite_width / 2) - viewX, y - viewY,
    1);
}

//-----Change Draw Settings Back To Default
gpu_set_fog(false, c_white, 0, 0);
surface_reset_target();
Thanks in advance to anyone willing to help!
 

Simon Gust

Member
You may not want to draw non-GUI related things in the draw GUI event. Everything drawn in that event will have it's coordinates set to view x / y base. The surface with the given coordinates will draw off screen.
I suggest drawing it when the application surface is originally drawn, in the post draw event.
Surfaces themselves have a base at x=0 and y=0. Anything drawn on to them should be drawn relative to view x / y instead of room x / y. This counts also when drawing a surface on another surface.

draws off-surface
Code:
draw_surface(application_surface, shaViewX, shaViewY);
done corretly here
Code:
with (Obj_Par_EntityManager)
{
    //-----Draw Shadow
    draw_sprite_pos(sprite_index, image_index,
    x - (sprite_width / 2) - viewX - swayX, y - viewY - swayY + (z * 2),
    x + (sprite_width / 2) - viewX - swayX, y - viewY - swayY + (z * 2),
    x + (sprite_width / 2) - viewX, y - viewY + (z * 2),
    x - (sprite_width / 2) - viewX, y - viewY + (z * 2),
    1);
}
 
So I've moved the Draw GUI code over to the Post Draw Event, and I've tried to adopt the View vs Room x/y thing that you were talking about but I don't think I've fully grasped it, since it still didn't render.
Here's the new Create Event with the changes to the variables containing the coordinates for the surface drawing:
GML:
/// @desc Basic Setup

//---------------------------------Setup
//-----Disable App Surface Drawing
application_surface_draw_enable(false);                //Stops the application surface from
                                                    //drawing automatically.
//-----Setup Surfaces
//Temp Variables
shaViewW = MAC_SCREENWIDTH;                            //Gets Screen Size
shaViewH = MAC_SCREENHEIGHT;

shaViewX = camera_get_view_x(view_camera[0]);
shaViewY = camera_get_view_y(view_camera[0]);

//Actual Surfaces
surPassA = surface_create(shaViewW, shaViewH);        //Creates Surfaces
surPassB = surface_create(shaViewW, shaViewH);

//-----Sub Surfaces
surBlur1 = -1;
surBlur2 = -1;
 
Top