GMS 2 3D MRT Blending issues

Discussion in 'Programming' started by Binsk, Jan 30, 2018.

  1. Binsk

    Binsk Member

    Jun 22, 2016
    EDIT : This post is Hella old, no longer working on a solution.

    This is probably a stupid topic but my brain is too
    fried to think right now. I'm looking for suggestions to effectively overcome this small problem.

    I have some models with relatively large amounts of materials that thus require several passes to render each model. Because I am using some other graphical effects I need a normal map and depth map to render as well as the regular diffuse map.

    So far I have used MRTs and simply used the regular blend-mode to blend all the results of a model together on my three surfaces. Now, I apply SSAO to the results before pushing it to the screen but some materials in the model shouldn't have SSAO. What I did initially was write my settings into the alpha-channel of my normal buffer which would then be read in the SSAO shader so as to disable SSAO on specific materials.

    Once I started rendering multiple models I started to see a problem. Because of the blend-mode, the alpha channel in my normal buffer would affect the actual writing of my normals if a model was already rendered in that position (for example if a normal was written with the settings equalling 1 before the settings equalling 0, the later would not be added to the buffer because of the alpha-blending). This, in turn, would cause SSAO from models in the rear to show up on top of my foremost models (depending on render order).

    The obvious fix is to either 1) disable alpha blending when rendering my normal buffer or 2) change the blend-mode so it doesn't affect the color.

    The issue is that, because I am using MRTs, I am also rendering my diffuse map at the same time. The diffuse map requires alpha-blending for the materials that are translucent. I needed a way to disable alpha-blending for my normal/depth maps while keep it enabled for my diffuse map, all in the same pass.

    Well, clearly I couldn't find a way to do that with GameMaker's functionality (and am not even sure if that is a GameMaker limitation or a GPU limitation).

    Some options I have considered:
    1) Render each model twice, once for diffuse and once for the rest of the buffer (this is unacceptable as it is a huge waste of processing).
    2) Add another buffer and render my settings to it (this is a large waste of vRAM and it uses up another sampler in my SSAO shader)
    3) Render with (bm_one, bm_zero) and blend diffuse buffer onto different surface between material renders (requires constantly switching shaders and resetting uniforms multiple times a model)

    None of those seem great and I am too brain-dead to think if there is a different way around this. Could someone chime in and maybe give me another take on the problem? Just looking for some ideas. Thanks.

    EDIT: Tried option 3 and it killed the framerate. Tried option 2 and that is what I am going with for the time being. I still don't like any of these options as they are a waste in one way or another (and using an extra sampler / render target is going to come back to bite me later on, I know it).

    I'm still looking for better methods if you have any ideas.
    Last edited: Feb 11, 2019
  2. Kaliam

    Kaliam Member

    Jan 21, 2017
    This stupid idea could work, just bypass GM's blending entirely.
    You could pass in the surface your targeting as a sampler, draw everything with a basic blend mode so it just draws whatever you output from the shader, and then do the blending yourself in the fragment shader.
    It should work with a slight performance hit, but it would take up a lot of your sampler indexes, especially since you are using MRT and need to blend to different surface targets.
    Binsk likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice