[Effect] mode7

  • The renderer is fully premultiplied, meaning the color rgb values are multiplied by their alpha components. For example 50% opacity red is actually (0.5, 0, 0, 0.5), and will still render as full brightness red at 50% opacity instead of a dark "half red" at 50% opacity due to the renderer blend configuration. It's easy to mess up premultiplied alpha in shaders.

    I can't figure out why right now but there seems to be some kind of built in fog calculation which screws up the premultiplied alpha. I don't know why that would need to be in the shader anyway, since if it's linear you can fake it easily with a sprite. If you remove the fog then the alpha blend works correctly.

    Just replace the last few (broken) lines of the shader:

        vec4 color = texture2D(samplerFront, vec2(mod(xx * scale_x, 1.0), mod(yy * scale_y, 1.0)));
        
        //add some fog in the distance
        gl_FragColor = vec4(color.rgb/color.a, color.a*(abs(pz)*15.0));[/code:5se2x7m3]
    
    with this, which skips the fog calculation:
    
    [code:5se2x7m3]gl_FragColor = texture2D(samplerFront, vec2(mod(xx * scale_x, 1.0), mod(yy * scale_y, 1.0)));[/code:5se2x7m3]
    
    Top tip: GPUs aren't good at conditionals. The shader would probably be a lot faster on low-end hardware if the "single_image" conditional were removed. It could be made as two separate shaders instead, each with the mode hard coded on/off. Then you have a blazing fast shader: one texture lookup per fragment, no conditionals, no loops... it should even run well on mobile!
  • Oh, and remove this line at the top - it's a completely redundant texture lookup which isn't referenced anywhere!

    vec4 front = texture2D(samplerFront, vTex);[/code:ftvktn0g]
    
    That should double your rendering throughput 
    
    Also, tagging 

    Aurel

  • Thanks you SO MUCH Ashley, transparencies are BACK in business! : ))

    And the shader seems faster, too!

    The additive blending is still missing, though, but that's so much better already : )))

    I'm investigating right now for the blending, maybe I'm doing something wrong somewhere...

    (but blendings are OK if the mode7 effect is disabled, even with 4 others effects activated)

  • Nope, definitely no luck with the blendings. (Can't wait to have this fixed to record a clean video!)

    I tried:

    • remove all other effects, on the layout and on all layers
    • try forcing own texture on/off
    • check at the fallback blendings

    Argl, so close! Any idea? Could that come from the shader too? I guess this one is on my side, but I don't see where to look for...

  • Have you got a minimal repro to play with?

  • Aurel would you mind uploading the fixed shader file if you manage to get it all sorted? Thanks.

  • Of course!

    I'm working on the minimal CAPX, should we find something, I'll post the shader and the CAPX, so everyone can have it.

    Ashley working on it as we speak!

  • Ashley

    Minimum CAPX available here (6mo): https://www.dropbox.com/s/2y3i4af1ldtze ... .capx?dl=0

    What's inside?

    • a sprite, in additive mode, on a layer.
    • a bright background layer so we can see the addtive effect.

    Result:

    • additive blending works ok if mode7 is desactivated on the sprite layer.
    • additive blending doesn't work if mode7 is activated on the sprite layer.
    • additive blending works if applicated on the full layer, though. But not on sprites.
  • R0J0hound A friend of mine just simplified the shader the way Ashley said, so if you're using only "single_image", it's much faster.

    Once we got this blending issue sorted, are you ok with me posting it here?

    I don't want to be unrespectful with your work.

  • Aurel - it's working correctly. What's happening is:

    1. Layer has effect so is rendering to its own texture

    2. Layer texture starts out transparent black (0,0,0,0)

    3. Additive blended object renders on top of transparent black. This (AFAIK) correctly fills in the alpha, so you end up with opaque black.

    4. Mode7 effect processes on the layer texture, which correctly distorts the black text.

    To fix it you can try setting the layer with the mode7 effect also to 'additive' blend. It will process the mode7 effect, then additively blend the result on to the background (since blend modes come last). This only works if everything on that layer has additive blend, but that's a good idea anyway since it improves rendering performance.

  • Aurel

    Feel free to post it. I haven't had time as of late to mess with it. I'm just glad it could be improved.

  • Ashley Ouch. That means I have to add 2 more layers in every level. That will look like this:

    BEFORE:

    HUD

    Foreground

    Triggers (invisible)

    Ships/Others (mode7 applied)

    Track (mode 7 applied)

    Background

    NOW:

    HUD

    Foreground

    Triggers (invisible)

    Additive layer for FX above the ships (mode7 applied)

    Ships/Others (mode7 applied)

    Additive layer for FX under the ships (mode7 applied)

    Track (mode 7 applied)

    Background

    I'm not afraid of the work for the elements to be sorted on the right layers, but 4 X mode 7 effects... I'm worried about perfs.

    I guess I have no choice, I'll try. This mode 7 effect is optional and can only be selected in the graphic options as "VERY HIGH" (others being "LOW = no shaders/few particles and NORMAL=all shaders but no mode7")

  • Excuse my ignorance, but couldn't you create a highly specific Mode7Additive effect?

    ...I, uh, have literally no idea how shaders work, just thinking aloud.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Shaders are more expensive than simply setting a blend mode, so I don't think a special Mode7Additive effect is going to improve anything.

    If you've made all the improvements to the Mode7 effect I suggested (including separate shaders to remove the conditional), then I think it should be about as fast as normal rendering. The bottleneck is normally the number of texture lookups (normal rendering does one, but a blur might do ~10, requiring 10 times as many texture reads), conditionals (especially if unpredictable, which can make entire groups of cores stall if one mispredict occurs), or loops. Mode7 does one lookup, then some branchless math with no loops. I think in some cases the math is done "for free", because even if it weren't there the core would have spent the same amount of time stalling waiting for the next memory read to come through.

    The only thing to worry about IMO is the fact you have two more layers which will be using their own texture. After the layer renders it then has to copy the canvas-sized texture for that layer to the screen. It's the type of thing that on mobile will hit your fillrate hard and possibly cause poor performance. However if you're targeting desktops/consoles you probably have more fillrate than you could know what to do with (especially on high end desktop graphics cards, you will probably sooner run out of CPU power trying to issue rendering commands than run out of fillrate). So fillrate is probably not a major concern there either.

    So basically I wouldn't worry about it, it's a good way to get the effect working with different blend modes. Something you could do to help reduce the fillrate: if any of the layers are empty - or even if they have content, but it is offscreen - set them invisible. A visible but empty layer using an effect still takes fillrate (just to process a screen of transparent pixels); if it's invisible, it's entirely skipped, saving any rendering cost. So then you only pay the GPU cost when it's necessary, so e.g. if there are no FX under the ships then you don't spend any time at all processing shaders or using fillrate.

    I wonder if the engine could skip layers automatically if they are empty. I might try experimenting with that in the next beta.

  • (layer skip if empty sounds like a very nice idea!)

    Alright, it took me a bit of time, but everything is now up and running : )

    • Mode7 shader simplified
    • 2 more layers for additive blended sprites and particles, only used if mode 7 is activated (set to "invisible" if no mode7)
    • sprites and particles are automaticaly moved to the new layers on created if mode 7 activated.
    • sprites and particles are automaticaly moved back to the regular layers if mode 7 is desactivated during ingame.

    I still have to test this on less powerfull hardware, but it runs ok on my laptop.

    Many, many thanks for your help on this issue Ashley , it made a huge difference.

    I'll record a clean video with "mode7 on/off" to show how cool it looks, and post the shader very soon too : )

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)