New 3D renderer in Cogwheel
Monday, 10th August 2009
I have written a new 3D-compatible renderer for Cogwheel. It holds two textures, one for each eye, and uses one of a number of different effect file techniques to mix the two views.
Based on the interlacing work from the previous entry, the first technique is one that uses interleaved rows. I'm not really sure if there's a good way to convert texture coordinates into device coordinates, so am passing in the viewport height as a parameter and hoping that floating point errors don't trip me up (they haven't, yet).
float4 RowInterleavedPixelShader(VertexPositionTexture input) : COLOR0 { float row = input.Texture.y * ViewportHeight * 0.5f; if (abs(round(row) - row) < 0.1f) { return tex2D(LeftEyeSampler, input.Texture); } else { return tex2D(RightEyeSampler, input.Texture); } }
Alternate pixel centres may also pose a problem in the future. If anyone had any recommendations, suggestions or warnings on the way I'm detecting the evenness or oddness of a particular "scanline" then I'd appreciate hearing them!
I have also added two other interleaving modes; one in columns and another in a chequerboard pattern. I included these two as I've seen that some 3D LCD panels use a column interleaving pattern (I suppose that with a lenticular lens in front of such a panel you may not even need 3D glasses) and apparently Sharp have displays that use the chequerboard pattern.
I have also taken advantage of pixel shaders to create colour and monochrome anaglyphs (previously calculated in software), though neither look as good as the above full-colour modes for shutter glasses or similar hardware.
There are a few issues I need to sort out first before I can release this; for example, there's no way to set whether the first row/column/pixel is for the left or right eye. More problematic is the removal of support for non power-of-two textures; the Master System's 256×192 display is fine, but the Game Gear's 160×144 display gets rounded up to 192 pixels wide (and yes, I know that's not a power of two) on my video card. I also mean to give Promit's SlimTune profiler a look to see if I can optimise some of the less efficient pieces of my code. The C# version of emu2413 is probably a good candidate, being a "dumb" translation from the original macro-heavy C.