// pass 1
surface_set_target(SURFACE B);
// draw stuff
surface_reset_target();
// pass 2
shader_set(SHADER);
surface_set_target(SURFACE A);
repeat (6) // repeated 6 times
{
draw_surface(SURFACE B, 0, 0);
surface_copy(SURFACE B, 0, 0, SURFACE A);
}
surface_reset_target();
shader_reset();
// result will be on SURFACE A
surface_set_target(surf_buffer2);
shader_set(sh_pixel);
var vw = camera_get_view_width(view_camera[0])/2;
var vh = camera_get_view_height(view_camera[0])/2;
shader_set_uniform_f(pixel,vw,vh,size,size);
draw_surface_ext(application_surface,0,0,1,1,0,c_white,1);
shader_reset();
surface_reset_target();
surface_set_target(surf_buffer);
shader_set(shd_chromatic);
var tmpDisVis = round((distort/2*400)/1000);
shader_set_uniform_f(cAStr, tmpDisVis);
draw_surface_ext(surf_buffer2,0,0,1,1,0,c_white,1);
shader_reset();
surface_reset_target();
shader_set(shaderLight);
draw_surface_ext(surf_buffer,0,0,1,1,0,c_white,1);
shader_reset();
Just make sure you put the code in the Draw end event so that everything is drawn to the application surface first.I've tried that.
My problem seems to be that my shaders have a line like:
I guess the "gm_BaseTexture" means that the shader will sample what GM has in that sampler 'slot' ?! So I always get the unprocessed application surface in that case.Code:texture2D( gm_BaseTexture , v_vTexcoord)
(I'm pretty new to shaders, I'm trying to combine a pixelation shader with RGB shifting)
Yes, post draw is the correct sub event, but just in case you wanted for something to be unaffected by the shader, you'd have to call it earlier.I think there is an even easier way to do this that is more efficient that creating another shader. Instead of creating another surface simply reference the application surface instead. The application surface IS a surface like the ones you create except its done automatically so it behaves the same as your created surfaces.
Simon might be right about when you should apply your shader effects in a different event...though I think maybe in the post draw event might be the place instead of the Draw End. the Draw end, I believe is still part of the drawing process so if there is any objects with a draw end event its not going to get processed by the shader. The Post Draw events occur AFTER the application surface has been completely drawn
So simply this (I think):
Post Draw Event:
shader_set()
draw_surface(application_surface)
shader_reset()
repeat with how many shader effects you want to use
NOTE: I am not 100% sure about this, would like confirmation from someone else who has more experience with this type of post processing effects
Ah that's true, is the Draw Gui a different surface or does that get drawn last to the application surface? If he didn't want that to run through the shader he could still put it in the post draw event and simply make his own gui drawing after that. But like you said, he would have to do your method if certain elements of the game shouldn't go through that shaderYes, post draw is the correct sub event, but just in case you wanted for something to be unaffected by the shader, you'd have to call it earlier.
with the temporary surface creating / copying I was thinking of shaders that need to run multiple times for the effect to take place.
The GUI has no surface I believe, as the application surface is sent to the backbuffer first before the GUI subevent even begins. I think it just puts everything directly into the backbuffer.Ah that's true, is the Draw Gui a different surface or does that get drawn last to the application surface? If he didn't want that to run through the shader he could still put it in the post draw event and simply make his own gui drawing after that. But like you said, he would have to do your method if certain elements of the game shouldn't go through that shader
///Create Event
application_surface_draw_enable(false);
///Draw GUI
scr_render_Final();
if (!showHUD || !instance_exists(obj_pl_ror)) exit;
scr_render_IngameHuD();
scr_render_debugHUD();
///scr_renderFinal()
surface_set_target(surf_buffer2);
shader_set(sh_pixel);
draw_surface_ext(application_surface,0,0,1,1,0,c_white,1);
shader_reset();
surface_reset_target();
surface_set_target(surf_buffer);
shader_set(shd_chromatic);
draw_surface_ext(surf_buffer2,0,0,1,1,0,c_white,1);
shader_reset();
surface_reset_target();
shader_set(shaderLight);
draw_surface_ext(surf_buffer,0,0,1,1,0,c_white,1);
shader_reset();
Interesting, you might be right then. And I learned a bit more about rendering...its actually the backbuffer that displays the image we see and not the surface itself. I guess the surface could be compared to a stamp. You create the stamp design you want then transfer it onto the paper (back buffer) which is then displayed to the player.The GUI has no surface I believe, as the application surface is sent to the backbuffer first before the GUI subevent even begins. I think it just puts everything directly into the backbuffer.
https://docs.yoyogames.com/source/dadiospice/002_reference/surfaces/the application surface.html
Well, you're only drawing 1 item less and you lose out on sub-pixel-less scaling, having a shader affect the application surface, copying what's currently on screen (screenshots) and some more stuff.Interesting, you might be right then. And I learned a bit more about rendering...its actually the backbuffer that displays the image we see and not the surface itself. I guess the surface could be compared to a stamp. You create the stamp design you want then transfer it onto the paper (back buffer) which is then displayed to the player.
Knowing this (and if my explanation is correct), is there has to be times where its smarter to simply draw straight to the back buffer without going through a surface. I would imagine going directly to the back buffer is more efficient because you are only drawing things once instead of twice
Interesting, so it may not be as beneficial as it may seem then. Changing resolutions would be much more of a pain to do without using the application surface or surfaces in general. Still an interesting studyWell, you're only drawing 1 item less and you lose out on sub-pixel-less scaling, having a shader affect the application surface, copying what's currently on screen (screenshots) and some more stuff.
The manual says that it may be beneficial on older devices. https://docs.yoyogames.com/source/dadiospice/002_reference/surfaces/application_surface_enable.html