OpenGame.exe
OpenGame.exe copied to clipboard
RGSS2/3 Windowskin cleanup
The windowskins for RGSS2/3 use the same layout. RGSS3 uses a tone as well, which I will add later on with a pixel shader. That is not part of this issue.
My progress with the layout is incomplete - there are several errors in positions, and it is missing some things like the tiled background. The selection box is also stretched, rather than constructed smoothly from pieces.
For reference I once made a guide on how the RGSS2/3 Windowskin is composed; http://www.hbgames.org/forums/viewtopic.php?f=48&t=78637
The colour toning and tiling are areas that I expect to be rather annoying.
Tiling can be easily achieved in two ways;
- Creating a new texture that contains just the bottom-left tile image with UV wrapping enabled and having the texture co-ordinates in screen-space
- Calculating the step and rendering enough geometry to cover the entire tiling area
The first option includes an extra texture bind, which can be costly with performance. The second option adds more geometry, most GPUs can cope with a bit more geometry like this, however we're using fixed-function GL.Begin() and GL.End() which adds significant over-head and can cause problems for lower-end hardware, where the extra texture switch of the first option may actually be more better.
I would suggest going for the extra geometry solution.
Colour toning is additive, this can be achieved by drawing an untextured quad with the tone colours as the vertex colour option over the top of the window background with an additive blend for all the positive colours and a subtractive blend for the negative colours.
The draw-back to this is that you will have up to 2 extra passes with an intensive blend operation.
Another solution would be to apply the blending to the windowskin texture when it is loaded, however as RPG Maker supports changing the tone during runtime this has the potential for extremely high video memory consumption and multiple texture binds and uploads (ouch!) for changing tone during run-time.
The additive/subtractive blended geometry would probably be the better option for the colour toning.
Could solve both with a fairly simple frag shader, which is how I was planning to do it. Any reason not to? (Notably, staying on fixed function is not the plan. Just got it started with that because it's the form I'm most comfortable debugging. And as you can imagine, there is a LOT of debugging involved.)
Shaders are always a large step up in hardware requirements and step down in abstraction.
I think if you have glBegin() written somewhere you should be avoiding shaders where possible.
Avoiding shaders is actually something I do for programmable pipeline too; if hardware accelerated blending can achieve the same result then go with that as it means more compatibility and less shader sources to worry about (they can get unruly quickly).
I think you'll get more out of a fixed function solution within a fixed function pipeline, shaders require more thought and management and that is overkill for something as simple as a window skin compositor.
Should also be noted that program binding is more performance intensive than texture binding, so the shader route is going to take a performance hit there.
Seems like these solutions in terms of GPU performance affecting are;
- Geometry
- Texture switches + memory
- Shader switches + program
Actually the more I think about it the more I think additional geometry with hardware blending is the correct solution. Rendering more triangles is much cheaper than switching a shader then running a program and would be less memory intensive and cheaper than switching textures.
Just remember that we do have sprite and viewport hue shift, colors and tones as well as other effects such as flash and then there's image transition effects which are just begging to be a shader. So they are almost inevitable in the long run (especially with transitions because running continuous setpixel scans makes no sense by comparison, even if that is what vanilla does), but nothing wrong with avoiding them in scenarios where that makes sense.
The engine was needlessly complex with color modifiers - but the goal is to emulate it, even in all of its ridiculousness. -_-
Transitions use a grey-scale map, they are better suited to be a depth buffer texture attachment and for the first frame to be drawn without depth testing and the final frame to be drawn with depth testing, sliding along the Z axis to bring it into view, that would be the best performing way to do transitions (again, all done in hardware, top performance).
Colours and tones can be done with stencil testing for sprites with a blended quad drawn over them. View port colours and tones is just a quad blended over the view port.
Hue is the one that makes sense to be done in shaders, the only way to do them in fixed function is with multi-texturing, which increases memory usage. I think using a shader for hue is the easiest and best performing option, but transitions, colours and tones have fixed function solutions which will perform better than shaders.
Particularly the use of depth buffers for transition and stencil buffer for sprite colour and tone, which on modern hardware eliminates the use of the shading pipeline entirely for occluded fragments, those techniques will be a lot faster than shaders.
Good ideas, I will look into those. Just to point out, while the typical usage of transitions is greyscale maps, they do technically support RGB images, and will treat each channel as an additional set of "depth", so to speak. That could still be done with a depth buffer, mapping the RGB channels deeper into the buffer.
If transitions as depth maps were to be used some image processing would be needed on load anyway to get the image from its RGB components into a GL_FLOAT array (I think that's the only way to reliably upload a depth buffer attachment from an offline source).