• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

FS2004 Boeing 747 Classic

Aaron: I don't know whether this will help, but could I suggest downloading the sd2gau42 documentation from here: Creating C Gauges and reading the section titled 'Understanding how P3D treats Bitmaps and Colours in Gauges'; specifically the sub-section 'This is Where it all Goes Wrong'. I have some suggestions in there on how to defeat the night banding.
Yes, I am aware of this but there are actually 2 different factors when it comes to FS9 and our panel:

I am using GDI+ and not the older MAKE macros, which means that the sim itself never touches our actual bitmaps. Each frame's presenter instead rasterizes the bitmaps with the CPU, but in terms of unconditional compression, it does not happen in the load stage but in the rendering stage.

FS9's panels are limited to 5 bits per color channel, though I noticed while reading the texture's pixel rasterizer that they include dithering, which I didn't include in my render code which can improve the appearance at the cost of noise

C++:
        void ConvertBackToImg(Gdiplus::Bitmap* back, PIMAGE img,
                              int rx, int ry, int rw, int rh)
        {
            if (back == NULL || img == NULL || img->image == NULL)
            { return; }
            const int dimX = (int)back->GetWidth();
            const int dimY = (int)back->GetHeight();
            int x0 = (rx > 0) ? rx : 0;
            int y0 = (ry > 0) ? ry : 0;
            int x1 = rx + rw;
            int y1 = ry + rh;
            if (x1 > dimX) { x1 = dimX; }
            if (y1 > dimY) { y1 = dimY; }
            if (x1 > img->dim.x) { x1 = img->dim.x; }
            if (y1 > img->dim.y) { y1 = img->dim.y; }
            if (x0 >= x1 || y0 >= y1) { return; }
            Gdiplus::BitmapData bd;
            Gdiplus::Rect rc(0, 0, dimX, dimY);
            if (back->LockBits(&rc, Gdiplus::ImageLockModeRead,
                               PixelFormat32bppARGB, &bd) != Gdiplus::Ok)
            { return; }
            for (int y = y0; y < y1; ++y)
            {
                const unsigned int* src = (const unsigned int*)
                    ((char*)bd.Scan0 + y * bd.Stride);
                char* dstRow = img->image + (UINT32)y * img->pitch;
                const unsigned int* bayer = kBayer4[y & 3];
                if (img->format == IMG_15_BIT)
                {
                    unsigned short* dst = (unsigned short*)dstRow;
                    for (int x = x0; x < x1; ++x)
                    {
                        const unsigned int p = src[x];
                        if ((p >> 24) < 128) { dst[x] = 0; continue; }
                        const unsigned int r = (p >> 16) & 0xFF;
                        const unsigned int gg = (p >> 8) & 0xFF;
                        const unsigned int b = p & 0xFF;
                        const unsigned int d = bayer[x & 3];
                        dst[x] = (unsigned short)
                            (0x8000 | (Dither5(r, d) << 10) |
                             (Dither5(gg, d) << 5) | Dither5(b, d));
                    }
                }
                else if (img->format == IMG_32_BIT ||
                         img->format == IMG_32A_BIT)
                {
                    unsigned int* dst = (unsigned int*)dstRow;
                    for (int x = x0; x < x1; ++x)
                    {
                        dst[x] = src[x];
                    }
                }
                else if (img->format == IMG_16_BIT)
                {
                    unsigned short* dst = (unsigned short*)dstRow;
                    for (int x = x0; x < x1; ++x)
                    {
                        const unsigned int p = src[x];
                        if ((p >> 24) < 128) { dst[x] = 0; continue; }
                        const unsigned int r = (p >> 16) & 0xFF;
                        const unsigned int gg = (p >> 8) & 0xFF;
                        const unsigned int b = p & 0xFF;
                        const unsigned int d = bayer[x & 3];
                        unsigned short v = (unsigned short)
                            ((Dither5(r, d) << 11) | (Dither6(gg, d) << 5) |
                             Dither5(b, d));
                        if (v == 0) { v = 0x0821; }   // near-black
                        dst[x] = v;
                    }
                }
            }
            back->UnlockBits(&bd);
        }
 
@DragonflightDesign After applying dithering, the banding doesn't look nearly as terrible.

1793427656360.png


The "noise" solution you presented in sd2gau works as its a more manual form of dithering, but either way, I am much more happy with this result... Thanks for the mention about it.
 
One of the last pieces of the 2D panels is adding some lighting and details. The left is the old panel, the right is the new panel bitmap.

Electrical_PanelOld.jpg
Electrical_Panel.jpg


The new panels comprise of 4 new aspects; panel staining, dust/debris, specular highlights, and ambient occlusion. The latter two are rendered using 3d recreations of the 2d panel projected onto a plane that is the same resolution as the original bitmap.
1793684869674.png
1793684954123.png


The first two consisted of both manual photoshop work and automatic scripting tools. The boundaries for crevices were defined both by the ambient occlusion map and a height map, both generated from the 3D software. These images then feed into heatmap generators to programmatically define exactly where dust, debris, hairs, and small particles should land. Each individual type of dirt is biased towards a specific portion of the panel and some panels receive more dirt than others.

Staining consisted of marking specific parts of the panels and then running a hue/saturation filter over it plus a fractal generator that inverted the operation of the that module's filter. This results in bright and dark spots of the panel, simulating topcoat degradation or UV exposure.

1793685219278.png
1793685236996.png
nookh3.png


These items are then combined and composited to the final image you see above.

Electrical_Panel_Stained.png
1793685583164.png
1793685683288.png
1793685236996.png
 
that is unreal, how did you manage to get all those little details dust parts right? I assume hand drawn?
Yes, though I used a variety of dust brushes in Photoshop and cropping random scraps of paper, egg shells, and bread crumbs. Hair was taken from black and white film damage and I just used line debris as hair.
 
Yes, though I used a variety of dust brushes in Photoshop and cropping random scraps of paper, egg shells, and bread crumbs. Hair was taken from black and white film damage and I just used line debris as hair.
Looks a lot more natural than my method of using a dust brush to unmask photos of garbage dumps.
 
Back
Top