ObjReader Community

Discussion => Post Your Questions & Comments Here => Topic started by: Michael Lobko-Lobanovsky on December 12, 2018, 08:00:00 pm

Title: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 12, 2018, 08:00:00 pm
Patrice,

There's a site called ShaderToy.com that features heaps of raytraced shaders many of which may be used as animated backgrounds in ObjReader.

Some of the shaders are very heavy but some others are very light consuming not more than 8 or 10% GPU on our video cards full screen.

I can make many of them rendered animated in the ObjReader background in place of its current static wallpapers. With time, we can even add a (Scintilla-based) shader editor to OR to be able to edit, recompile, and run in real time our own GLSL shaders, pretty much like ShaderToy does. 8)

See a few examples in the attached zip.

What would you say to that? :D
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 12, 2018, 08:56:18 pm
Quote
What would you say to that?
Indeed, i think that we could already play any of my visual plugins in the backround (altogether with an audio track), but the ultimate effect would be also to play a video loop as long as we can create a transparent background.

Same concept that the one used there (or in MBox64)
http://www.objreader.com/index.php?topic=19.0

I do have already several wmv video loop that we could use for background (see the attached examples).
Note: they are intended to be played in loop mode

Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 12, 2018, 09:08:53 pm
And we could also sync the scene lighting with any audio track, with both intensity and speed rotation.  8)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 12, 2018, 09:19:38 pm
Heh, a shader is just a few lines of code and nothing more. What is a WMF file and a DLL to play it back? Megabytes of code. :)

"Small is beautiful"(c), you know... :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 13, 2018, 01:06:12 am
I had a quick look at Shadertoy, looks very promising !!!
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 19, 2019, 02:02:35 pm
I have registered to www.shadertoy.com, but i am unable to get an API key  :-[
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 19, 2019, 06:43:41 pm
What would you need their API for? It is only needed to create a Shadertoy web player that could be integrated directly in your app similar to an ordinary web-browser control.

In fact, you don't need that. The pixel (a.k.a. fragment) shaders for specific user entries are available on the Shadertoy entry's respective page. Though they are designed for WebGL and customized a little further specifically for the Shadertoy API engine, they are still legible enough to be reversed to plain GLSL usable in OpenGL, and consequently, in ObjReader.

Note that Shadertoy doesn't accept models as vertex shader input. All entries share a common vertex shader that would only draw the shader output quad from VRAM to the on-screen OpenGL (actually, WebGL) viewport. It is equivalent to our common screen quad vertex shader as used now in drawing the post-processed FBO frames. All simulated 3D shapes and entities you're seeing in the Shadertoy player are being drawn exclusively in the entry's fragment shader(s) as seen on the entry page by means of ray-marching technique.

You can modify Shadertoy fragment shader code and recompile it to see the effect of your mods directly in the entry's shader code editor. Those shaders that use only one yellow tab in the code editor ("Image") are suitable for use in ObjReader in 99.5% cases with only minimal fixes to comply with OpenGL, rather than WebGL, syntax and uniform naming convention. More than one tab in the code editor means the shader is multipass and requires several FBOs to be ping-ponged in VRAM before actual on-screen output. Those aren't yet implemented in OR and, after all, such multipass raymarching shaders are wa-a-a-ay too heavy on GPU to be used for low-priority purposes such as animated wallpapers.

My friend, it is much much easier and faster for me to just implement Shadertoy code based animated backgrounds in OR myself than guide you through the GLSL language in which I am still pretty much a newbie. :)

But you can provide a great service to OR by surfing through Snadertoy's entire shader base to select those shaders that look promising from the artistic perspective as OR's animated wallpapers. (be prepared for frequent freezes of your browser as WebGL windows are still very difficult for it to render!) I can then supply you with a simple FBSL demo proggy for each of them where you will have a standalone fragment shader code file to fiddle with its parameters right on your desktop.

See the fragment shader in AG.fs. See simple FBSL BASIC code (without includes) in GLSL_AcidGalaxies.fbs to run a Shadertoy example in a user program. Press Alt+Enter to toggle the full screen mode, Esc to quit.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 19, 2019, 07:05:13 pm
Quote
My friend, it is much much easier and faster for me to just implement Shadertoy code based animated backgrounds in OR myself than guide you through the GLSL language in which I am still pretty much a newbie. :)
Ok, no problem, i shall select the shaders that look promising from the artistic perspective as OR's animated wallpapers
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 19, 2019, 07:08:35 pm
Here is my first shadertoy's list

https://www.shadertoy.com/view/XslGRr  problematic
https://www.shadertoy.com/view/ldXXDj  done
https://www.shadertoy.com/view/4dXGR4  done
https://www.shadertoy.com/view/MdBGzG  done
https://www.shadertoy.com/view/lty3Rt  done
https://www.shadertoy.com/view/XtGGRt  done

Added
https://www.shadertoy.com/view/XsyGWV  done
https://www.shadertoy.com/view/4s2SRt  done
https://www.shadertoy.com/view/ltffzl  done
https://www.shadertoy.com/view/4tdSWr  done
https://www.shadertoy.com/view/wtf3Df  done
https://www.shadertoy.com/view/ll3fz4 needs extra FBO
https://www.shadertoy.com/view/tss3Dr  done
https://www.shadertoy.com/view/XljcD1  done 75% GPU usage @ 15FPS
https://www.shadertoy.com/view/MlKSWm  done
https://www.shadertoy.com/view/ltt3Rl  needs extra FBO
https://www.shadertoy.com/view/4dtSRl  done
https://www.shadertoy.com/view/XtfXDN (just for the fun of it)  :-* done








Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 19, 2019, 08:02:47 pm
Yes, those are cool shaders indeed!

My notes on:

1. Ocean: I'm not sure we will be able to tweak it to display veritable stars in the sky rather than those ugly bits and pieces of I don't know what...

2. Corona: The shader seems to be responsive to the music beat. I have no idea how they transform bass.dll audio multi-bandpass output data into a real-time 2D bitmap to be bound to an OpenGL ordinary texture unit to modulate the pixels being drawn at a particular point in time. So our shader is very likely to be static in what regards star brightness and size. (delete the iChannel1 input by clicking its X button to see what it might look like on our screens)

3. (Any) Terrain: those are usually much heavier than even clouds. I'm not sure we will be able to run any of our decent starship or vehicle models against such backgrounds...

4. All shaders: Shadertoy shaders usually zoom into the scene on its Z axis. It means logically our aircraft, starcraft, or car models should be turned away from us to match the direction of propagation. How we are going to make them pan right or left rather than zoom in, I do not know...
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 19, 2019, 08:44:59 pm
It takes a little time to prepare an FBSL stub to render "texturized" (iChannel0) shaders, but once prepared, other examples will be coming faster.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 19, 2019, 11:09:41 pm
Heck, the clouds turn out to be rather heavy on the GPU and very dependent on the noise texture used in TU0. There's no way to DL the original textures from the site, and the approximate equivalent I got from the net tends to generate moire...

Still I think I may get it working soon. If not, then there are other cloud shaders by Inigo Quilez that don't need tetures for noise generation...
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 20, 2019, 01:59:40 am
OK, putting Clouds aside for the time being (GPU load brought down to ~70% but moire still there), here are a couple toys to play with.

mouse -- orbit where available
Spacebar -- toggle animation
Alt+Enter -- toggle full screen
Esc -- quit app

Use Fraps to monitor the actual FPS rate. The scripts are Windows timer-powered: Pegasus at ~15 msec interval = ~60 FPS settings, Auroras at ~30 msec = ~30 FPS, Main Sequence Star at ~15 msec = ~60 FPS.

Pegasus Galaxy yields up to 100% GPU usage in full screen when at max closeups and after the screen goes black in the end. Change #define SCREEN_EFFECT 1 or 0 at the top of shader code to change the intro effect.

Auroras yields up to 75% GPU usage when in full screen.

Main Sequence Star yields only up to 25% GPU usage when in full screen.

Mouse control is a bit lousy where available but passable for test purposes. ;)

More examples will follow later.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 20, 2019, 09:51:17 am
Thank you very much!

I have updated the list.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 21, 2019, 12:58:40 am
So, I spent almost the whole afternoon and evening studying this awesome Canyon shader. It uses 4 texture units simultaneously; 3 to create and smooth out the terrain surface, and the 4th texture, to colorize the rocks.

iChannel2 hosts the same notorious noise texture that falters in my port of the clouds shader. I found an old github repo with a port of Shadertoy web control to iOS. It contains most of the texture assets from Shadertoy but unfortunately, not the offending noise texture. Instead, in hosts another one of the same size that doesn't fit in well in either the clouds or canyon shader.

The shader coefficients are all tailored for specific textures and cannot accept substitutes. Yet I managed to create a rough approximation of the missing noise texture for the canyon shader and also to fix bad tileablility of the other three ones using Photoshop. My substitute texture, alas, has no effect in the clouds shader.

Note also that Shadertoy flips textures while loading, which makes its coordinate system in the shader flipped with respect to what we have in our renderers. Shadertoy iChannels have a VFlip checkbox to "flip" their textures too, so that when ticked, the textures are actually brought back to normal while the coordinate system stays topsy-turvy.

When loaded, the ersatz noise texture I created, as well as the other textures, still differ a little from the originals (perhaps in their gammas or alpha premultiplication or something else) so that I can't produce the exact flying rocks, arches and balconies like in the original canyon shader. But still the overall result is stunning, and surprisingly, not so extra heavy as not to be usable for our purposes.

The zip contains 2 variants. Canonical mimics the original shader but without flying rocks and more moire. RollerCoaster has textures rotated 180o rather than flipped upside down and is absolutely nauseating during its first 7 or 8 minutes of watching. But it has even less moire than the original.

Demo controls are as usual except that mouse, even though nominally used, is inoperative in the shader for some obscure reason. My GPU usage is on the order of 60 to 80% full screen at a 30 msec/FPS setting. 60 FPS load the GPU up to 100%.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 21, 2019, 09:46:05 am
- Canonical
Is gorgeous, except when we get too close from the ground.

- RollerCoaster
Same as above, but my preference goes to canonical.

Thank you very much for your hard work, much appreciated !

Here are a few other glsl web sites:
http://glslsandbox.com/
https://www.vertexshaderart.com/
https://shaderfrog.com/

And more about OpenGL shaders there:
https://github.com/radixzz/awesome-glsl
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 22, 2019, 11:34:50 am
Thanks for the links, my friend! :)

Well, so far the Caribbean Pirates shader seems the absolute best candidate for becoming an animated background.

It is completely if-less and very, very fast. My GPU typical usage stays as low as only 5 to 7% at 60 FPS full-screen! :o :D

My mods:Enjoy! 8)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 22, 2019, 12:11:18 pm
Very good, thank you !

Do you think that would requires much changes into OR, to add background animations.
And what would be the mtl syntax.
#anim shaderfile

or just the existing
#wallpaper shaderfile.shd
with the shader extension.

PS: I also thought of using PNG animations, like in my eye candie RedHawk project.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 22, 2019, 01:48:18 pm
Always at your service, my friend! :D

No, there aren't going to be many changes; just a few simple manipulations: I think your animated PNGs won't need many changes either except creating separate textures for each PNG frame and sync'ing their change with our main timer in a controlled fashion to achieve the expected animation speed. I think you can do it even without my assistance. You can even reuse the existing background display list.  :)

Regarding the #meta, I believe we can reuse the existing #wallpaper for your animated PNGs but add an extra parameter ani preceding the PNG file name OR even have no special parameter at all if you can sense automagically if a PNG is animated or not.

Animated shader files should IMHO have canonical .fs extensions (they lack a common vertex shader part and therefore shouldn't be called .glsl files), preserve their attribution blurbs, and be put in the common \Resource folder together with the associated textures. Shader recompilation and texture loading can be done in a separate worker thread (OpenGL is a multithreaded framework, after all) so as not to stall the current display activity. I think they would require some separate #meta to enumerate all the associated texture assets.


(I'm currently working on your favorite Oblivion 166 drone and will come back when ready or failed :D)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 22, 2019, 02:31:14 pm
Yes, i can detect automatically if a png file is an animation or not.

Here is a couple of animations i was thinking about
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 22, 2019, 05:59:55 pm
They're looking cool but are they going to be as attractive when resized? ::) The wallpapers should be ideally hires 1980x1050 to avoid magnification at all...

OK here comes your favorite nursery beanbag. ;D

The shader appears quite fast at 30FPS. My GPU load is from 30% to 75% full screen, depending on the visible size of the drone. 60FPS load my GPU to 100% like the Shadertoy original in the browser.

What I did was as follows:Overall, the demo is not so impressive as the original due to the lack of voice synthesis. I wish I knew exactly how they handle sound synthesis and music. Perhaps some day I'll be able to understand enough of ObjectiveC illegible syntax to mimic it in OR.

Enjoy! :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 22, 2019, 06:53:55 pm
My friend, you did a tremendous work with it, even if it is not really suitable to use with the existing oblivion models (clouds, or marching landscape, would be better)

Congratulations !

As you know i have some experience with Bass.dll audio, this is something i can think about once we have glsl/fs in OR.
We probably can do the same than with my existing OpenGL plugins.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 22, 2019, 07:32:20 pm
I'm glad you like it, my friend! :)

What concerns bass.dll (not sound synthesis but just playback of music etc.), I saw their music sound shaders and I think I understand how the thing actually works under the hood.

Modern bass.dll is able to output in real time an array of up to 1024 audio samples of current music, each in its very narrow frequency band pretty much the same as an analog band-pass filter does. Each sample carries its own volume level and thus the array may be used for fine simulation of a spectrum analyzer.

The set of array samples should constitute the X axis of a 1024x1024 px large 2D bitmap. The Y axis should represent a proportionately scaled volume level of the loudest sample, i.e. the max allowable volume, in the band-pass filter bands. Such a BMP "snapshot" should be taken 30 or 60 times per second (as the CPU/GPU/bass.dll audio buffer permit), converted into an OpenGL 2D texture, and bound to some iChannelX sampler like an ordinary 2D texture would. The texture is then sampled by the graphics shader to modulate its other parameters, etc.

Actually, the number of band samples in the bitmap may be much lower if we aren't going to simulate a full-blown spectrum analyzer. E.g. there may be only 4 sample bands in it, say, some high frequency band, one high-mid, one low-mid, and one mid-bass. And only those 4 samples are going to be used for graphics shader modulation. Given there are 256 gradations of volume level in a sample, the 4 samples can be packed a 1x1 px large 32-bit BMP/texture. BMP creation, BMP-to-texture conversion, and sampling of such a tiny "texture" can run lightning fast and easy for the GPU.

Or you can just take a combined volume output of bass.dll and create a 1x1 px large 8-bit 256-level grayscale texture from it to modulate you graphics to the overall music beat.

BTW video capture is done in a similar way but the number of samples depends on the exact current video frame size, and samples are taken and converted to BMPs at the exact current video frame frequency. There are lots of video shaders on Shadertoy that implement such technique.

Now, the question. Do you think you can provide me with a working scheme to create such BMPs on the fly based on bass.dll's band-pass output as I described above? I can then step in and add texture creation and manipulation code for us to be able to modulate our 2D and 3D display in OR with the sweet sounds of music we like. :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 22, 2019, 09:23:00 pm
This is what i am using in MBox64   8)

Code: [Select]
const void* BassChannelGetWimData() {
    static float fft[256];
    memset(&fft[0], 0, sizeof(float)* 256);
    DWORD hChannel = gP.channelrec;
    if (gB.channel) { hChannel = gB.channel; }
    if (hChannel) { long nRet = BASS_ChannelGetData(hChannel, &fft[0], 1024); }
    return &fft[0];
}

void ColorInit() {
    WCHAR zResource[MAX_PATH];
    Path_Combine(zResource, EXEresource(), L"palette.png");
    long bmW = 0, bmH = 0;
    HBITMAP hBitmap = ZI_CreateBitmapFromFile(zResource, bmW, bmH);
    if (bmW > 33) {
        BITMAP bm; GetObject(hBitmap, sizeof(bm), &bm);
        BYTE* pBits = (BYTE*) bm.bmBits;
        for (long P = 0; P < 34; ++P) {
            gColor[P] = skARGB(pBits[3], pBits[2], pBits[1], pBits[0]);
            pBits += 4;
        }
    } else {
        gColor[0]  = 0;
        gColor[1]  = skARGB(255, 3,95,250);
        gColor[2]  = skARGB(255, 3,97,250);
        gColor[3]  = skARGB(255, 4,101,250);
        gColor[4]  = skARGB(255, 4,104,250);
        gColor[5]  = skARGB(255, 4,108,250);
        gColor[6]  = skARGB(255, 4,112,249);
        gColor[7]  = skARGB(255, 5,116,249);
        gColor[8]  = skARGB(255, 5,121,249);
        gColor[9]  = skARGB(255, 6,126,249);
        gColor[10] = skARGB(255, 6,130,249);
        gColor[11] = skARGB(255, 6,135,249);
        gColor[12] = skARGB(255, 7,139,249);
        gColor[13] = skARGB(255, 7,143,248);
        gColor[14] = skARGB(255, 7,147,248);
        gColor[15] = skARGB(255, 8,150,248);
        gColor[16] = skARGB(255, 8,154,248);
        gColor[17] = skARGB(255, 8,155,248);
        gColor[18] = skARGB(255, 11,158,248);
        gColor[19] = skARGB(255, 17,162,248);
        gColor[20] = skARGB(255, 24,166,249);
        gColor[21] = skARGB(255, 32,171,249);
        gColor[22] = skARGB(255, 41,176,249);
        gColor[23] = skARGB(255, 50,183,250);
        gColor[24] = skARGB(255, 59,189,250);
        gColor[25] = skARGB(255, 70,195,250);
        gColor[26] = skARGB(255, 80,201,251);
        gColor[27] = skARGB(255, 91,207,251);
        gColor[28] = skARGB(255, 100,213,252);
        gColor[29] = skARGB(255, 109,219,252);
        gColor[30] = skARGB(255, 118,224,252);
        gColor[31] = skARGB(255, 126,229,252);
        gColor[32] = skARGB(255, 133,233,253);
        gColor[33] = skARGB(255, 136,237,253);
    }
    DeleteObject(hBitmap);
}

long LevelColor(IN long nParam) {
    long nInt = min((long) (sqrt(nParam) * 8), 33);
    if (nInt < 1) { nInt = 1; }
    return gColor[nInt];
}

const int BBP_RENDER      = 1;       // Render the scene.
const int BBP_CREATE      = 2;       // Retrieve Title, Name, Version, Render mode.
const int BBP_INIT        = 3;       // Init the OpenGL.
const int BBP_SIZE        = 4;       // The size of the control has changed.
const int BBP_KEYBOARD    = 5;       // All keyborad message.
const int BBP_MOUSE       = 6;       // All mouse messages.
const int BBP_DESTROY     = 7;       // Free Up resources.

const int BBP_GDIPLUS     = 0;       // GDImage GDIPLUS compatible mode.
const int BBP_OPENGL      = 1;       // OpenGL mode.
const int BBP_DIRECTX     = 2;       // DirectX mode (for future extension).

const int BBP_SUCCESS     = 0;
const int BBP_ERROR       = -1;

struct BBPLUGIN {
    UINT msg;                   // The plugin's message (see above constant list).
    HWND parent;                // The parent window handle.
    HDC dc;                     // The parent window DC (while in play mode).
    HGLRC rc;                   // The parent OpenGL RC (while in play mode).
    WORD lpeak;                 // The left audio channel peak value (while in play mode).
    WORD rpeak;                 // The right audio channel peak value (while in play mode).
    char title[32];             // Plugin's name or title.
    char author[64];            // Plugin's author name.
    DWORD version;              // LOWRD major, HIWRD minor.
    long renderto;              // BBP_GDIPLUS, BBP_OPENGL, BBP_DIRECTX.
    long backargb;              // Default ARGB color background.
    float* fftdata;             // dword pointer to the FFT() as single array.
    WORD fftsize;               // Size of the FFT array.

    UINT winmsg;                // True Windows message.
    WPARAM wparam;              // wParam
    LPARAM lparam;              // lParam

    short* wimdata;             // dword pointer to the wave MM_WIM_DATA.
    QWORD medialength;          // Media length.
    QWORD mediapos;             // Media pos.

    char reserved[50];          // Reserved for future extension.
} ;                             // Structure size = 256

WORD SolvePeak(IN WORD nValue, IN WORD nTotal) {
    WORD nRet = 0;
    if (nTotal) { nRet = (nValue * 100) / nTotal; }
    return nRet;
}

FARPROC BBP_ProcHandle(IN FARPROC hProc, IN long RW) {
    static FARPROC WasHproc;
    if (RW) { WasHproc = hProc; }
    return WasHproc;
}

long BBP_Plugin(OUT BBPLUGIN &BBP) {
    long nRet = BBP_ERROR;
    if (IsWindow(gP.hGL)) {
        HGLRC glRC = (HGLRC) (ZI_GetProperty(gP.hGL, ZI_GLRC));
        if (glRC) {
            long_proc (BBPLUGIN*);
            zProc hProc = (zProc) BBP_ProcHandle(0, 0);
            if (hProc) { nRet = hProc(&BBP); }
        }
    }
    return nRet;
}

//long BBProc (OUT BBPLUGIN &BBP);
void BBP_Detached(IN HWND hWnd, OUT HMODULE &hLib) {
    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
    if (hLib) {
        BBP.msg = BBP_DESTROY;
        BBP.parent = hWnd;
        BBP_Plugin(BBP);
        //BBProc(BBP);

        // use brute force to delete any existing texture
        long Tmax = 64;
        long* DT = new long[Tmax]; memset(DT, 0, Tmax);
        for (long K = 0; K < Tmax; K++) { DT[K] = K; }
        glDeleteTextures(Tmax, (GLuint*)&DT[0]);
        delete[] DT;

        BBP_ProcHandle(0, 1); FreeLibrary(hLib); hLib = 0;
    }
}

WCHAR* BBP_ActivePlugin(IN WCHAR* sPluginName, IN long RW) {
    static WCHAR sWasPluginName[MAX_PATH];
    if (RW) { wcscopy(sWasPluginName, sPluginName); }
    return sWasPluginName;
}

void BBP_Reset() {
    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
    BBP.msg = BBP_CREATE;
    BBP_Plugin(BBP);

    WCHAR title[32]; ClearMemory(title, sizeof(title));
    WCHAR author[64]; ClearMemory(author, sizeof(author));
    MultiByteToWideChar(CP_ACP, 0, (char*)BBP.title, lstrlenA(BBP.title), title, 32);
    MultiByteToWideChar(CP_ACP, 0, (char*)BBP.author, lstrlenA(BBP.author), author, 64);
    wcscopy(gB.plugintitle, title); Add_Str(gB.plugintitle, L" by "); Add_Str(gB.plugintitle, author);

    //BBProc(BBP);
    if (BBP.renderto == BBP_OPENGL) {

        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHT0);
        glDisable(GL_LIGHT1);
        glDisable(GL_LIGHT2);
        glDisable(GL_LIGHT3);
        glDisable(GL_LIGHT4);
        glDisable(GL_LIGHT5);
        glDisable(GL_LIGHT6);
        glDisable(GL_LIGHT7);
        glDisable(GL_LIGHTING);
        glDisable(GL_COLOR_MATERIAL);
        glDisable(GL_ALPHA_TEST);
        glDisable(GL_NORMALIZE);

        glDisable(GL_LINE_SMOOTH);

        glGetError();

    }
}

// Load/unload plugin DLL to/from memory
long BBP_LoadPlugin(IN HWND hWnd, IN WCHAR* zPlugin) {
    static WCHAR zLastPlugin[MAX_PATH] = { 0 };
    static HMODULE hLib;
    long nDone = BBP_ERROR;
    long nLen = lstrlen(zPlugin);
    if ((nLen) && (_wcsicmp(zPlugin, zLastPlugin) != 0)) {
        if (FileExist(zPlugin)) {
            BBP_Detached(hWnd, hLib);
            hLib = LoadLibrary(zPlugin);
            if (hLib) {
                FARPROC hProc = GetProcAddress(hLib, "BBProc");
                if (hProc) {
                    BBP_ProcHandle(hProc, 1);
                    wcscopy(zLastPlugin, zPlugin);
                    BBP_ActivePlugin(zLastPlugin, 1);
                    // Reset plugin to default
                    BBP_Reset();
                    nDone = BBP_SUCCESS;
                }
            }
        }
    } else if (nLen == 0) {
        BBP_Detached(hWnd, hLib);
    }
    return nDone;
}

void ResizeOpenGL() {
    if (gP.pluginloaded) {
        if (IsWindow(gP.hGL)) {
            BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
            BBP.msg          = BBP_SIZE;
            BBP.parent       = gP.hGL;
            BBP_Plugin(BBP);
            //BBProc(BBP);
        }
    }
}

void RenderOpenGL(IN DWORD nLevel, IN short* pInt) {

    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));

    HDC glDC = (HDC) (ZI_GetProperty(gP.hGL, ZI_GLDC));
    HGLRC glRC = (HGLRC) (ZI_GetProperty(gP.hGL, ZI_GLRC));
    if (glRC) {

        BBP.msg          = BBP_RENDER;
        BBP.parent       = gP.hGL;
        BBP.dc           = glDC;
        BBP.rc           = glRC;
        BBP.lpeak        = SolvePeak(LOWORD(nLevel), 128);
        BBP.rpeak        = SolvePeak(HIWORD(nLevel), 128);
        BBP.backargb     = 0;
        BBP.fftdata      = (float*) BassChannelGetData();
        BBP.fftsize      = 256;
        BBP.medialength  = gB.medialength;
        BBP.mediapos     = gB.mediapos;
        BBP.wimdata      = pInt;

        BBP_Plugin(BBP);
        //BBProc(BBP);

        // Refresh display
        SwapBuffers(glDC);

        InvalidateRect(gP.hGL, NULL, 0);
        UpdateWindow(gP.hGL);
    }
    ReleaseDC(gP.hGL, glDC);
}
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 22, 2019, 10:04:10 pm
OK Patrice, not so fast -- one step at a time.

From what I can see in the code, I'm now practically interested only in BassChannelGetWimData():

1. What is 1024 in BASS_ChannelGetData(hChannel, &fft[0], 1024)? Is it 1024 bytes of data or 1024 band-pass samples?

2. If those are bytes, then does it mean you're getting only 256 floating-point volume value samples for a max 256-band filter?

3. If yes, then is it the max number of bands you can get from bass.dll at any one time?

4. Can you get only 4, 8, 16, etc. volume value samples at frequencies of your own choice?

Please answer each of the questions. My following questions and wishes will depend on the fullness of your answers.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 22, 2019, 11:36:49 pm
First, you must understand that Bass.dll is build upon the Windows waveform audio API.

Have a look at MSDN there for the MM_WIM_DATA message
https://docs.microsoft.com/en-us/windows/desktop/multimedia/mm-wim-data

Tomorrow, I shall try to find an application i wrote long ago, that was using directly the core audio API.

Added:
I think to remember that its name was audiocap ;)
https://forum.pcsoft.fr/en-US/pcsoft.us.windev/7156-audio-capture-demo/read.awp
http://www.jose.it-berater.org/smfforum/index.php?topic=1504.msg4734#msg4734
The oscilloscope should do what you are looking for.

I shall send you the PowerBASIC DLL source code, once i could remember where i saved it  ???
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 12:03:57 am
Thank you, Patrice.

I am able to build it all by myself -- bit by bit -- from ground up reading up on modern bass.dll user interface and API. I used to develop audio grabbing and filtering SW too, using my FBSL and older versions of bass.dll and other audio processing libraries, quite some time ago. Granted, it wasn't as beautifully presentable as your media players and video plugins and stuff, but it was usable all right and it did its job.

But that means I'll have to put shaders and OR aside.

I was hoping I could use your skills and knowledge to get answers to my questions quicker so as not to stall my other activities. I was also hoping you could implement the simpler GDI (not GPI+/GDImage -- that's unnecessary and actually detrimental) part of work without my interference but following my advice on what we need in OR rather than what you have in your players and visualizers.

I was wrong.

No big deal. I remove this question from the agenda until I'm through with your (still far from exhaustive) shader list.



P.S. If you're willing to help me out, give me a workable example code for any of you linear (spectrum analyzer-style) visualizers if you have one, based on bass.dll. Not just a plugin abortion with public bells and whistles, but the core engine with the routines to set up bass.dll to read in an audio file, fill its audio buffers, adjust buffer size based on the file sample rate, get a copy of audio buffer chunks in a required format, and the most important of all, split the buffer spectrum at a given point in time into an array of samples taken at given frequencies within the spectrum to control how high up each frequency column in the spectrum analyzer should go at this particular point in time:

(https://store-images.s-microsoft.com/image/apps.41308.9007199266250928.d5b9155b-da3e-4c70-a8aa-76d4a172d111.dc1b1289-cd6f-4057-9324-b5d243bdd0a7?mode=scale&q=90&h=300&w=300)

This array of frequency samples is the core of structured data to create a 2D bitmap ("bitmap" means a "two dimensional array of structured data bits", not a picture or photo or drawing or painting) that can be converted/"loaded" into an OpenGL texture to be usable in an ordinary texture unit even though this "texture" is not an "image" in the classical sense of both words.

P.P.S.
Quote
The oscilloscope should do what you are looking for.

Are you mocking me or what? Do you think I can learn a single bit of useful information from a zip that contains nothing but PR blurbs and a bunch of binary files?

Are you also going to suggest I should buy and study Windev just to scratch up a trivial WinAPI/GDI script to get me a handful of meaningful data bits from an audio file to create a grayscale BMP?! :-[
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 02:46:05 am
Two Oblivion HUDs added below. Both run at 30FPS and have an optional background texture added. You may use any PNG that's named target.png or delete/rename the texture altogether to have a plain black background like on Shadertoy. No other adjustments needed.

HUD proper runs for me at 15% GPU usage full screen, and Radar, at up to 30%.

Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 23, 2019, 08:08:02 am
Quote
Are you mocking me or what? Do you think I can learn a single bit of useful information from a zip that contains nothing but PR blurbs and a bunch of binary files?

I asked you to give me some time to find the source code, audiocap is easy to understand because it is based directly onto the native wavefront API.

See the attached complete PowerBASIC source code , provided without bells and whistles.

The native API calls are within  AudioCap32.inc
the important Wim data is stored in @pWaveHdr.lpData (pointer to the waveform buffer, WAVEHDR PTR).
The buffer size relies on how you have used WaveInOpen, in the example "Stereo 44100 16-bit" and the DeviceToUse (stereomix or microphone).

The waveform buffer is decoded and rendered into DrawWave using a gain within 1-3, because sometime the signal could be very flat.
In BassBox i am using sqr to enhance it.

I am limiting myself to a color range of 32 values, generaly the lowest one being blue, and the higher bright red (see levelColr).

DrawWave is the section where you must build your bitmap to match your preference and create the texture, but this could also be used to change the size of the OpenGL components and their colors.

With Bass.dll BASS_DATA_FFT512, returns 256 floating point value, that is the same to what i am using with the core API.
You can use it like this
Code: [Select]
FUNCTION BassChannelGetData () AS DWORD
    DIM fft(255) AS STATIC SINGLE
    LOCAL nRet AS LONG
    RESET fft()
    IF gnAudioPause = %FALSE THEN
       IF gnAudioChannel THEN
          nRet = BASS_ChannelGetData(gnAudioChannel, VARPTR(fft(0)), %BASS_DATA_FFT512)
       END IF
    END IF
    FUNCTION = VARPTR(fft(0))
END FUNCTION
further details explained there:
http://www.un4seen.com/doc/#bass/BASS_ChannelGetData.html

The main advantage of Bass.dll over the core API, is that it is able to use most of the popular audio format.
But the only thing understood by the API is wavefront, this works like the different graphic formats ultimatly converted to bitmap.


Quote
But that means I'll have to put shaders and OR aside.
Please no, one step after another...
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 23, 2019, 08:17:19 am
The two Oblivion HUDs, are absolutly perfect !!!

I am thrilled to see them runing in OR  8)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 09:19:34 am
Quote
But that means I'll have to put shaders and OR aside.
Please no, one step after another...

 :D :D :D :D :D :D :D :D

OK friends will be friends, won't they? :)

Two more shaders coming:

1. 2D Clouds run for me at 30% GPU usage when at 30FPS, and at 40%, when at 60FPS, both full screen (I am not interested in other sizes as full screen is the worst case).

2. Heartfelt is a gorgeous piece of art when run with music, and almost made me cry on my keyboard. For me, the shader yields only up to 20% GPU usage at 30FPS, and up to 35%, at 60FPS. Be sure to use the mouse and HAS_HEART define as described in the HF.fs shader file to control the time lapse and/or rain amount.

Enjoy and thanks a million for the zip! :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 23, 2019, 09:47:01 am
Thank you very much, they are perfect, and yes Heartfelt is gorgeous!
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 23, 2019, 09:53:48 am
When playing live, i prefer to use an audio record channel rather than a specific audio file, but both are working the same to render the OpenGL scene.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 10:28:44 am
Sometimes there's no needed URL available on the net any more, and you can only listen to it if you have a hardcopy.

There's one very nice cartoon shader on Shadertoy that I want to replicate with a matching piece of idiotic but absolutely viral music that modulates the graphics display in a very attractive manner. I cannot tear the audio file out of Shadertoy but probably you could help me catch and record it streaming while it plays there (https://www.shadertoy.com/view/XsBXWt)?

The funny thing is it sounds like Russian stuff but I'm not fully sure due to a heavy vocoder effect... ;D
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 10:48:56 am
Two more simple shaders below. :)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 11:23:16 am
And the last one for the time being. :)

Up to 35% GPU usage at both 30 and 60 FPS.

Use your mouse to rotate the fire.

(We can probably add a textured background too if you want. Just tell me if you do.)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 11:51:26 am
And this one can only run at 15FPS eating up to 75% GPU. :-\

Use LMB to zoom (Y movement) and rotate (X movement) the scene.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 23, 2019, 02:31:31 pm
Thank you for the new converted models, especially Fire that is one of my favorite.

Quote
There's one very nice cartoon shader on Shadertoy that I want to replicate with a matching piece of idiotic but absolutely viral music that modulates the graphics display in a very attractive manner. I cannot tear the audio file out of Shadertoy but probably you could help me catch and record it streaming while it plays there?
You can grab the music yourself with AudioCap while playing the shader, then convert the resulting WAV file into OGG (with Audacity).

BTW, i have a bunch of formal Amiga soundtrackers that we could use in OR, they are very small compared to other audio formats.

As a matter of example listen at the attached TheModel.mod (75 Kb) with MBox64

Note: I have to mow the lawn... :(
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 04:35:25 pm
Thank you for the new converted models, especially Fire that is one of my favorite.

You're welcome! But those are not straight-forward clear and concise plain old solid models. Those sines and cosines, fracts and smoothsteps are something far more ephemeral and unfriendly to the user. ;)

You can grab the music yourself with AudioCap while playing the shader, then convert the resulting WAV file into OGG (with Audacity).

Unfortunately, your AudioCap3 fails to either capture or monitor anything on my W7 box.

In the Capture to Wave mode, it records an empty file and there's nothing but a straight line with a running marker in the "oscilliscope" window.  ???

Moreover, it simply quits when I try to re-select the Monitoring only option. :(

And last but not least, it crashes wildly when I click the Change destination button. >:(

That means I'm unable to experiment with your WINMM code in my dev environment and also that we shouldn't rely on it in ObjReader either. ::)
_____________________________________

That said, can you still spare me 3 minutes of your time once mowing is over, and capture that .WAV file for me from the beginning to the end, please?
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 23, 2019, 04:56:40 pm
Does that one works any better by you?

Anyway i shall grab the audio with it for you.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 05:08:29 pm
This one is better in the sense of not quitting or crashing unexpectedly. Yet its display stays flat and capture.wav is empty like before. :(

Re. .MOD: yes it looks very small but isn't it just another MIDI format rather than an audio file? .MIDs are not large at all either...
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 23, 2019, 05:19:59 pm
Do you have a multiplex audio card?
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 23, 2019, 05:33:05 pm
Here is the capture.mp3, very far to be perfect, but this is the best i could do.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 05:48:33 pm
I have three profiles:

1. Usual on-board Intel HD Audio connected to Speakers; (p/b and matching rec)

2. nVidia HD Audio connectable to nVidia HDMI Output on my GTX1060 (p/b but currently unplugged)

3. E-MU E-DSP HD Audio Processor (WDM) connected to S/PDIF and HDMI inputs/outputs on its own card (p/b and matching rec)

selectable from the system Sound dialog.

All are in full working order and audible when some sound runs on my box but neither one is detectable by your AudioCap as a source of wave signal. :(

(Thanks for the capture! Any quality will do for initial experimentation. :) )
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 23, 2019, 05:58:47 pm
You can try to record with Audacity to see if it works better with your audio config.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 23, 2019, 06:07:53 pm
Yes, I somehow overlooked that possibility. I rarely use my PCs for recording or playback activities these days. I have more than 300 kg of reel-to-reel, cassette and CD audio recorders and players, vinyl LP turntables, amplifiers, speaker cabinets, mixers and other related stuff for that at my disposal. ;D
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 25, 2019, 07:54:44 am
Wake up, my friend! :D

It's time to enjoy a night flight to ... Mars! :D

I tweaked the shader to work with one buffer and noise texture. It is heavy, but I limited its FPS to 20 so it won't use more than 50% of my GPU at full screen.

Use your mouse to look around as you fly. :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 25, 2019, 10:03:23 am
Thank you, thank you, thank you!

That one, was first on my list for our starship models.

Bravo mon ami !
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 27, 2019, 01:56:03 pm
Here are some more shader toys for you to play with. :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 27, 2019, 02:27:48 pm
I don't think that these are suitable with the existing models, however thanks anyway !

Do you have already translated the FBSL code to work in OR ?
(i would like to select those that better fit with the existing 3D collection)

http://glslsandbox.com/e#54329.0  done
http://glslsandbox.com/e#54000.2  done
http://glslsandbox.com/e#54001.2  done
http://glslsandbox.com/e#53999.2  done
http://glslsandbox.com/e#53836.0  done
http://glslsandbox.com/e#53816.2  done
http://glslsandbox.com/e#53666.0  done
http://glslsandbox.com/e#52820.0  done
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 27, 2019, 07:50:54 pm
I'm still in the process of doing it. I'm also cleaning the sources of some deprecated and unused stuff.

I think we're in need of another editor panel for our shaders. The problem is there may be two shaders working concurrently now: a design or fancy mode shader and a PP shader, and yet more than one PP shader will be allowed to run concurrently in the future. Thus, the tool window option has become insufficient because OR doesn't know exactly which shader we're going to fine-tune when pressing the Ctrl button.

So, we need a panel to the right of the splitter that would host a scrollable list of sections with controls for each shader in the system like what we have in discrete popup tool windows now. It could be your homework for the immediate future once you get my mods for merging.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 27, 2019, 10:32:53 pm
Re. new shaders:

No problem, my friend, though those sources are definitely not so rich, and the shaders, not so sophisticated.

Catch the first batch below: :)


(BTW what can you say about your GPU usage figures in full screen? Are they comparable to mine?)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 28, 2019, 01:08:19 am
... and here's the second batch. :)

Note that in Tori, mouse drag controls light flare position rather than viewing angle. The control is however lame and inaccurate.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 28, 2019, 10:23:39 am
Voronoi 32%GPU 60FPS
Sirenian Dawn 49%GPU 21FPS
BlueSpace 35%GPU 60FPS
Tori 43%GPU 60FPS
RedHot 45%GPU 32FPS
PurpleSpace 34%GPU 60FPS
Moebius 20%GPU 60FPS

I am using the task manager for the GPU%, and FRAPS version 3.5.99 build 15618 for FPS.

Note: FBSL is a 32-bit application, we may get different results in 64-bit (hopefully better).
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on May 28, 2019, 01:25:25 pm
Thank you for the feedback!

Overall, our readings are pretty close, plus or minus. The GPU load is generated by shaders entirely within the GPU alone by its internal microcode regardless of CPU bitness. So, I don't think it will depend noticeably on whether the parent app is 32 or 64 bits, interpreted or natively compiled. The number of parallel processors in the GPU, video data bus width/throughput, and VRAM technology are more important factors that may differ from chip to chip, especially between different generations.

OTOH the other GPU brands like ATi or Intel may yield a yet much more significant spread due to more fundamental differences in their GPU architecture and instruction sets.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on May 28, 2019, 02:27:36 pm
With nVIDIA the 64-bit OpenGL drivers are faster than 32-bit.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 11, 2019, 05:38:59 pm
A few more from my back burner

https://www.shadertoy.com/view/4tlSzl (done)
https://www.shadertoy.com/view/4lcGWr
https://www.shadertoy.com/view/4s3SRN
https://www.shadertoy.com/view/XdBSWd
https://www.shadertoy.com/view/4tc3zf (done)
https://www.shadertoy.com/view/MllfDX
https://www.shadertoy.com/view/4ljyRc
https://www.shadertoy.com/view/ls3BDH (bassbox plugin)
https://www.shadertoy.com/view/MtGfzV (bassbox plugin)
https://www.shadertoy.com/view/XlsBDj (bassbox plugin)
https://www.shadertoy.com/view/ldycRK (bassbox plugin)
https://www.shadertoy.com/view/MdSXDh (bassbox plugin)
https://www.shadertoy.com/view/XtSGRV (bassbox plugin)
https://www.shadertoy.com/view/XlBXRh (bassbox plugin)
https://www.shadertoy.com/view/MsKBDG (for the fun)

Some are good candidates to become BassBox plugins ;)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 11, 2019, 06:24:49 pm
I have already done the Oblivion shader, regretfully without the synthesized sound. Yet the sound can be recorded as a stream.

The shader is nice to watch as a nano-movie but I can hardly imagine any model displayed against such a background. ;)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 11, 2019, 06:29:22 pm
Re. Graffiti: we can't play video in a shader. So, the rainy background is feasible while Van Damme isn't.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 11, 2019, 09:05:16 pm
Yes, some are just a source of inspiration that i have saved to create new BB plugins.

And a few are good candidates for OR, as the one used with Haldin.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 12, 2019, 05:59:04 am
Good morning, my friend,

Here are a few animated backgrounds to your morning coffee. :)

Just put the files in the \Animated resources folder.


P.S. Haldin looks very good for spaceship flies-by.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 12, 2019, 10:34:48 am
Thank you my friend!

I shall probably make a little change to OR, to be able to use @ to load a .fs file from a specific folder (just like for static wallpaper).

I would like to convert some of the glsl code to plain OpenGL to turn them into BB plugins.

Do you think this is feasible without using shaders?
I would like to start first with a simple one, like
https://www.shadertoy.com/view/ls3BDH

Added:
#wallpaper @shadertoy.fs
is working, i shall post the sync files in a couple of hours (have to go outside first)

Sync
Here is the sync.zip file, search for: // PAT: 12-12-2019
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 12, 2019, 02:48:22 pm
Re. plugins, I'm afraid it's infeasible except in a very few simplest cases. Shaders work several hundred times faster than immediate OpenGL in both maths and graphics. Besides, you'll have to recreate the entire framework of GLSL language in C to mimic its heavily overloaded maths for 2-, 3- and 4-dimensional vectors and matrices, interpolation, texture access, etc.

For all intents and purposes, it will be more practical to add to the BB three functions to load, compile and link shaders, and a dedicated render procedure to output them to the existing OpenGL window without VBOs or post-processing.

Re: mods, thanks for the zip, I'll merge them tonight.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 13, 2019, 01:48:27 pm
To download the default shadertoy textures
https://shadertoyunofficial.wordpress.com/

I did try to convert shadertoy scripts to .fs, but i failed miserably, i have no real clue on what to do to make them work in OR  :-[

Added

I was able to make this one work (combustible.fs)

Code: [Select]
/*
    Combustible Voronoi Layers
--------------------------

    The effect itself is nothing new or exciting, just some moving 3D Voronoi layering.
    However, the fire palette might prove useful to some.

*/

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)


// This is my favorite fire palette. It's trimmed down for shader usage, and is based on an
// article I read at Hugo Elias's site years ago. I'm sure most old people, like me, have
// visited his site at one time or another:
//
// http://freespace.virgin.net/hugo.elias/models/m_ffire.htm
//
vec3 firePalette(float i){

    float T = 1400. + 1300.*i; // Temperature range (in Kelvin).
    vec3 L = vec3(7.4, 5.6, 4.4); // Red, green, blue wavelengths (in hundreds of nanometers).
    L = pow(L,vec3(5.0)) * (exp(1.43876719683e5/(T*L))-1.0);
    return 1.0-exp(-5e8/L); // Exposure level. Set to "50." For "70," change the "5" to a "7," etc.
}

/*
vec3 firePalette(float i){

    float T = 1400. + 1300.*i; // Temperature range (in Kelvin).
    // Hardcode red, green and blue wavelengths (in hundreds of nanometers).
    vec3 L = (exp(vec3(19442.7999572, 25692.271372, 32699.2544734)/T)-1.0);
    // Exposure level. Set to "50" For "70," change the ".5" to a ".7," etc.
    return 1.0-exp(-vec3(22532.6051122, 90788.296915, 303184.239775)*2.*.5/L);
}
*/

// Hash function. This particular one probably doesn't disperse things quite as nicely as some
// of the others around, but it's compact, and seems to work.
//
vec3 hash33(vec3 p){
   
    float n = sin(dot(p, vec3(7, 157, 113)));   
    return fract(vec3(2097152, 262144, 32768)*n);
}

// 3D Voronoi: Obviously, this is just a rehash of IQ's original.
//
float voronoi(vec3 p){

vec3 b, r, g = floor(p);
p = fract(p); // "p -= g;" works on some GPUs, but not all, for some annoying reason.

// Maximum value: I think outliers could get as high as "3," the squared diagonal length
// of the unit cube, with the mid point being "0.75." Is that right? Either way, for this
// example, the maximum is set to one, which would cover a good part of the range, whilst
// dispensing with the need to clamp the final result.
float d = 1.;
     
    // I've unrolled one of the loops. GPU architecture is a mystery to me, but I'm aware
    // they're not fond of nesting, branching, etc. My laptop GPU seems to hate everything,
    // including multiple loops. If it were a person, we wouldn't hang out.
for(int j = -1; j <= 1; j++) {
    for(int i = -1; i <= 1; i++) {
   
    b = vec3(i, j, -1);
    r = b - p + hash33(g+b);
    d = min(d, dot(r,r));
   
    b.z = 0.0;
    r = b - p + hash33(g+b);
    d = min(d, dot(r,r));
   
    b.z = 1.;
    r = b - p + hash33(g+b);
    d = min(d, dot(r,r));
   
    }
}

return d; // Range: [0, 1]
}

// Standard fBm function with some time dialation to give a parallax
// kind of effect. In other words, the position and time frequencies
// are changed at different rates from layer to layer.
//
float noiseLayers(in vec3 p) {

    // Normally, you'd just add a time vector to "p," and be done with
    // it. However, in this instance, time is added seperately so that
    // its frequency can be changed at a different rate. "p.z" is thrown
    // in there just to distort things a little more.
    vec3 t = vec3(0., 0., p.z+iTime*1.5);

    const int iter = 5; // Just five layers is enough.
    float tot = 0., sum = 0., amp = 1.; // Total, sum, amplitude.

    for (int i = 0; i < iter; i++) {
        tot += voronoi(p + t) * amp; // Add the layer to the total.
        p *= 2.0; // Position multiplied by two.
        t *= 1.5; // Time multiplied by less than two.
        sum += amp; // Sum of amplitudes.
        amp *= 0.5; // Decrease successive layer amplitude, as normal.
    }
   
    return tot/sum; // Range: [0, 1].
}

void main()
{
    // Screen coordinates.
vec2 uv = (gl_FragCoord.xy - iResolution.xy*0.5) / iResolution.y;

// Shifting the central position around, just a little, to simulate a
// moving camera, albeit a pretty lame one.
uv += vec2(sin(iTime*0.5)*0.25, cos(iTime*0.5)*0.125);

    // Constructing the unit ray.
vec3 rd = normalize(vec3(uv.x, uv.y, 3.1415926535898/8.));

    // Rotating the ray about the XY plane, to simulate a rolling camera.
float cs = cos(iTime*0.25), si = sin(iTime*0.25);
    // Apparently "r *= rM" can break in some older browsers.
rd.xy = rd.xy*mat2(cs, -si, si, cs);

// Passing a unit ray multiple into the Voronoi layer function, which
// is nothing more than an fBm setup with some time dialation.
float c = noiseLayers(rd*2.);

// Optional: Adding a bit of random noise for a subtle dust effect.
c = max(c + dot(hash33(rd)*2.-1., vec3(0.015)), 0.);

    // Coloring:
   
    // Nebula.
    c *= sqrt(c)*1.5; // Contrast.
    vec3 col = firePalette(c); // Palettization.
    //col = mix(col, col.zyx*0.1+c*0.9, clamp((1.+rd.x+rd.y)*0.45, 0., 1.)); // Color dispersion.
    col = mix(col, col.zyx*0.15+c*0.85, min(pow(dot(rd.xy, rd.xy)*1.2, 1.5), 1.)); // Color dispersion.
    col = pow(col, vec3(1.5));
   
    // The fire palette on its own. Perhaps a little too much fire color.
    //c = pow(c*1.33, 1.5);
    //vec3 col =  firePalette(c);
   
    // Black and white, just to keep the art students happy. :)
//c *= c*1.5;
//vec3 col = vec3(c);

// Done.
gl_FragColor = vec4(sqrt(clamp(col, 0., 1.)), 1.);
}
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 13, 2019, 02:56:28 pm
Didn't I send you this one?! :o

The \Resource\Animated subfolder should also contain this README.TXT:

!!! SHADER FILES MUST BE SAVED AS PLAIN ASCII TEXT !!!

0. Each shader should explicitly declare at least 4 uniforms:

-- uniform vec4  iDate: year/month/day/time in seconds as floats (year/month/day not implemented for the time being)
-- uniform vec3  iMouse: mouse coords as floats are current on-screen x and y if LMB down, and z = 1.0f if LMB down; otherwise all 0.0f
-- uniform vec2  iResolution: current viewport x and y sizes in pixels as floats
-- uniform float iTime: (in seconds w/ decimal fractions) system time, or time since session start, or time since app start.

Those uniforms may be used or not used in the shader code as needed.

1. Additional uniforms as needed for a specific shader:

-- uniform sampler2D filename_ext|mip_filename_ext|nomip_filename_ext: for as many textures as the shader needs.
   mip_ prefix (optional) means the respective texture should be mipmapped; nomip_ means no mipmapping is allowed.
   Prefixes, if any, are removed automatically, and underscores, replaced with dots to load the respective textures.
   Consequently, all occurrences of iChannel0 to iChannel3 sampler names throughout the code should be replaced with
   those new sampler names.

2. Shader resources (textures, etc.) should be stored in the same folder as the shader.

3. Shaders should contain attribution blurbs wherever available to respect the original author's copyright.

4. The mainImage(...) sub should be re-declared as void main(void) with arguments omitted.

5. All fragCoord and fragColor built-in variables should be renamed gl_FragCoord and gl_FragColor, respectively, throughout the shader code.


This is a full guide on how to convert ShaderToy ONE-BUFFER shaders for use in ObjReader. (one-buffer means those that run in one render pass and occupy exactly one code tab on their site; multiple code tabs require more than one FBO whereas OR has only one FBO and one render pass ATM)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 13, 2019, 03:04:40 pm
Quote
Didn't I send you this one?!
NO, you didn't send me any of those listed there:
http://www.objreader.com/index.php?topic=197.msg5718#msg5718

I shall look at an example using textures, to see what to do.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 13, 2019, 03:13:00 pm
Please re-read the above README.TXT file carefully. It contains all the information you need on how to fix the code of ST shaders for use in OR. :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 13, 2019, 03:32:29 pm
I have re-read the text, but i can't get this one to work

postcard.fs:

// Postcard by nimitz (twitter: @stormoid)
// https://www.shadertoy.com/view/XdBSWd
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// Contact the author for other licensing options

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

uniform sampler2D texture_png; // texture to load

/*
   Implementation of: http://iquilezles.org/www/articles/dynclouds/dynclouds.htm
   
   Added some raymarched mountains and normal mapped water to complete the scene.

   One thing I did differently is modyfying the scale of the fbm based on the distance
   from the shaded clouds allowing for a much less "planar" look to the cloud layer. 
*/

//Compare with simple clouds
//#define BASIC_CLOUDS

#define time iTime*2.
#define FAR 420.

//------------------------------------------------------------------
//----------------------Utility functions---------------------------
//------------------------------------------------------------------
vec3 rotx(vec3 p, float a){
    float s = sin(a), c = cos(a);
    return vec3(p.x, c*p.y - s*p.z, s*p.y + c*p.z);
}
vec3 roty(vec3 p, float a){
    float s = sin(a), c = cos(a);
    return vec3(c*p.x + s*p.z, p.y, -s*p.x + c*p.z);
}
float nmzHash(vec2 q)
{
    uvec2 p = uvec2(ivec2(q));
    p = p*uvec2(374761393U,22695477U) + p.yx;
    p.x = p.x*(p.y^(p.x>>15U));
    return float(p.x^(p.x >> 16U))*(1.0/float(0xffffffffU));
}
float noise(in vec2 p) {
    vec2 ip = floor(p);
    vec2 fp = fract(p);
   vec2 u = fp*fp*(3.0-2.0*fp);
    return -1.0+2.0*mix( mix( nmzHash( ip + vec2(0.0,0.0) ), nmzHash( ip + vec2(1.0,0.0) ), u.x),
                mix(nmzHash( ip + vec2(0.0,1.0) ), nmzHash( ip + vec2(1.0,1.0)), u.x), u.y);
}
//------------------------------------------------------------------
//---------------------------Terrain--------------------------------
//------------------------------------------------------------------
float terrain(in vec2 p)
{
    p*= 0.035;
    float rz = 0.;
    float m = 1.;
    float z = 1.;
    for(int i=0; i<=2; i++)
    {
        rz += (sin(noise(p/m)*1.7)*0.5+0.5)*z;
        m *= -0.25;
        z *= .2;
    }
    rz=exp2(rz-1.5);
    rz -= sin(p.y*.2+sin(p.x*.45));
    return rz*20.-14.;
}

float tmap(in vec3 p){ return p.y-terrain(p.zx);}
//Using "cheap AA" from eiffie (https://www.shadertoy.com/view/XsSXDt)
vec3 tmarch(in vec3 ro, in vec3 rd, in float d)
{
   float precis = 0.01;
    float h=precis*2.0;
    float hm = 100., dhm = 0.;
    for( int i=0; i<15; i++ )
    {   
        d += h = tmap(ro+rd*d)*1.5;
        if (h < hm)
        {
            hm = h;
            dhm = d;
        }
        if( abs(h)<precis||d>FAR ) break;
    }
   return vec3(d, hm, dhm);
}


vec3 normal( in vec3 pos, float t )
{
   float e = 0.001*t;
    vec2  eps = vec2(e,0.0);
    float h = terrain(pos.xz);
    return normalize(vec3( terrain(pos.xz-eps.xy)-h, e, terrain(pos.xz-eps.yx)-h ));
}

float plane( in vec3 ro, in vec3 rd, vec3 c, vec3 u, vec3 v )
{
   vec3 q = ro - c;
   vec3 n = cross(u,v);
    return -dot(n,q)/dot(rd,n);
}
//------------------------------------------------------------------
//-------------------------2d Clouds--------------------------------
//------------------------------------------------------------------
vec3 lgt = normalize(vec3(-1.0,0.1,.0));
vec3 hor = vec3(0);

float nz(in vec2 p){return texture(texture_png, p*.01).x;}
mat2 m2 = mat2( 0.80,  0.60, -0.60,  0.80 );
float fbm(in vec2 p, in float d)
{   
   d = smoothstep(0.,100.,d);
    p *= .3/(d+0.2);
    float z=2.;
   float rz = 0.;
    p  -= time*0.02;
   for (float i= 1.;i <=5.;i++ )
   {
      rz+= (sin(nz(p)*6.5)*0.5+0.5)*1.25/z;
      z *= 2.1;
      p *= 2.15;
        p += time*0.027;
        p *= m2;
   }
    return pow(abs(rz),2.-d);
}

vec4 clouds(in vec3 ro, in vec3 rd, in bool wtr)
{   
   
    //Base sky coloring is from iq's "Canyon" (https://www.shadertoy.com/view/MdBGzG)
    float sun = clamp(dot(lgt,rd),0.0,1.0 );
    hor = mix( 1.*vec3(0.70,1.0,1.0), vec3(1.3,0.55,0.15), 0.25+0.75*sun );
    vec3 col = mix( vec3(0.5,0.75,1.), hor, exp(-(4.+ 2.*(1.-sun))*max(0.0,rd.y-0.05)) );
    col *= 0.4;
   
    if (!wtr)
    {
        col += 0.8*vec3(1.0,0.8,0.7)*pow(sun,512.0);
        col += 0.2*vec3(1.0,0.4,0.2)*pow(sun,32.0);
    }
    else
    {
        col += 1.5*vec3(1.0,0.8,0.7)*pow(sun,512.0);
        col += 0.3*vec3(1.0,0.4,0.2)*pow(sun,32.0);
    }
    col += 0.1*vec3(1.0,0.4,0.2)*pow(sun,4.0);
   
   float pt = (90.0-ro.y)/rd.y;
    vec3 bpos = ro + pt*rd;
    float dist = sqrt(distance(ro,bpos));
    float s2p = distance(bpos,lgt*100.);
   
    const float cls = 0.002;
    float bz = fbm(bpos.xz*cls,dist);
    float tot = bz;
    const float stm = .0;
    const float stx = 1.15;
    tot = smoothstep(stm,stx,tot);
    float ds = 2.;
    for (float i=0.;i<=3.;i++)
    {

        vec3 pp = bpos + ds*lgt;
        float v = fbm(pp.xz*cls,dist);
        v = smoothstep(stm,stx,v);
        tot += v;
        #ifndef BASIC_CLOUDS
        ds *= .14*dist;
        #endif
    }

    col = mix(col,vec3(.5,0.5,0.55)*0.2,pow(bz,1.5));
    tot = smoothstep(-7.5,-0.,1.-tot);
    vec3 sccol = mix(vec3(0.11,0.1,0.2),vec3(.2,0.,0.1),smoothstep(0.,900.,s2p));
    col = mix(col,sccol,1.-tot)*1.6;
    vec3 sncol = mix(vec3(1.4,0.3,0.),vec3(1.5,.65,0.),smoothstep(0.,1200.,s2p));
    float sd = pow(sun,10.)+.7;
    col += sncol*bz*bz*bz*tot*tot*tot*sd;
   
    if (wtr) col = mix(col,vec3(0.5,0.7,1.)*0.3,0.4); //make the water blue-er
    return vec4(col,tot);
}
//------------------------------------------------------------------
//-------------------------------Extras-----------------------------
//------------------------------------------------------------------
float bnoise(in vec2 p)
{
    float d = sin(p.x*1.5+sin(p.y*.2))*0.1;
    return d += texture(texture_png,p.xy*0.01+time*0.001).x*0.04;
}

vec3 bump(in vec2 p, in vec3 n, in float t)
{
    vec2 e = vec2(40.,0)/(t*t);
    float n0 = bnoise(p);
    vec3 d = vec3(bnoise(p+e.xy)-n0,2., bnoise(p+e.yx)-n0)/e.x;
    n = normalize(n-d);
    return n;
}
//------------------------------------------------------------------
//------------------------------------------------------------------
void main()
{   
    vec2 bp = gl_FragCoord.xy/iResolution.xy*2.-1.;

    vec2 p  = bp;
   p.x*=iResolution.x/iResolution.y;
   vec2 mo = iMouse.xy / iResolution.xy-.5;
    mo = (mo==vec2(-.5))?mo=vec2(-0.4,-0.15):mo;
   mo.x *= iResolution.x/iResolution.y;
   vec3 ro = vec3(140.,0.,100.);
    vec3 rd = normalize(vec3(p,-2.7));
    rd = rotx(rd,0.15+mo.y*0.4);rd = roty(rd,1.5+mo.x*0.5);
    vec3 brd = rd;
    vec3 col = vec3(0);
      
   float pln = plane(ro, rd, vec3(0.,-4.,0), vec3(1.,0.,0.), vec3(0.0,.0,1.0));
    vec3 ppos = ro + rd*pln;
    bool wtr = false;
    vec3 bm = vec3(0);
    if (pln < 500. && pln > 0.)
    {
        vec3 n = vec3(0,1,0);
        float d= distance(ro,ppos);
        n = bump(ppos.xz,n,d);
        bm = n;
        rd = reflect(rd,n);
        wtr = true;
    }
    vec4 clo = clouds(ro, rd, wtr);
    col = clo.rgb;
   
    vec3 rz = tmarch(ro,brd,350.);
    float px = 3.5/iResolution.y;
    if (rz.x < FAR && (rz.x < pln || pln < 0.))
    {
        vec3 pos = ro + brd*rz.x;
        float dst = distance(pos, ro);
        vec3 nor = normal(pos,dst);
        float nl = clamp(dot(nor,lgt),0.,1.);
        vec3 mcol = vec3(0.04)+vec3(nl)*0.4*vec3(.5,0.35,0.1);
        mcol = mix(mcol,hor,smoothstep(210.,400.,rz.x-(pos.y+18.)*5.));//fogtains
        col = mix(mcol,col,clamp(rz.y/(px*rz.z),0.,1.));
    }
   
    //smooth water edge
    if (wtr && rz.x > pln)col = mix(col,hor*vec3(0.3,0.4,.6)*0.4,smoothstep(10.,200.,pln));
   
    //post
    col = pow(clamp(col,0.0,1.0), vec3(.9));
    col.g *= 0.93;
    //fancy vignetting
    float vgn1 = pow(smoothstep(0.0,.3,(bp.x + 1.)*(bp.y + 1.)*(bp.x - 1.)*(bp.y - 1.)),.5);
    float vgn2 = 1.-pow(dot(vec2(bp.x*.3, bp.y),bp),3.);
    col *= mix(vgn1,vgn2,.4)*.5+0.5;

   gl_FragColor = vec4( col, 1.0 );

}



And does the texture would work with the @ local folder as long it is available inside of it?
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 13, 2019, 03:46:03 pm
I suspect "I can't get this one to work" is a wrong statement. I think you rather crash your OR when trying to compile this shader. My OR fails to compile it invariably and I don't know the reason why GLSL doesn't show any error messages.

Some statement in the shader code may be semantically incorrect at a point where nVidia GLSL and WebGL 2.0 differ.

The bug isn't related to the texture you're using.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 13, 2019, 03:48:11 pm
The texture you sent above is already available in the \Animated subfolder under the name BWNoise.png.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 13, 2019, 07:19:55 pm
Hey Patrice,

I've just noticed that the mip_/nomip_ feature for shader samplers isn't yet implemented in OR. Thus, if you run the tinyclouds.fs background shader, you'll notice that the darker cloud areas seem dithered. That's because the noise texture used in the shader gets mipmapped when loaded while in fact it shouldn't.

So in the tinyclouds.fs shader code, change the two occurrences of colornoise_png to nomip_colornoise_png, and in shaders.h, change the glsl_LoadShaderFromFile() code as follows:

GLuint glsl_LoadShaderFromFile(IN WCHAR* fName) {
    // Mobj_createGlTextureFromFileEX OUT parms
    BYTE* lpArray = NULL;
    long X = 0, Y = 0;

    BKSHADER* cs = &gP.tCurAniBkgndShader;
    WCHAR wTmp[MAX_PATH] = { 0 };
    GLuint program = 0, vertShader = 0, fragShader = 0;
    char* p = NULL;
    char samplerMap[MAX_PATH] = { 0 };
    BOOL bNoMip = FALSE;

    if (wcsstr(fName, L"\\")) { // PAT: 12-12-2019
        wcscopy(wTmp, fName);
    } else {
        Path_Combine(wTmp, EXEresource(), L"Animated\\");
        Add_Str(wTmp, fName);
    }

    FILE* pFile = _wfopen(wTmp, L"r");
    if (!pFile)
        return 0;

    DWORD fSize = FileSize(wTmp);
    char* fs = (char*)calloc(1, fSize + 1);

    fread(fs, 1, fSize, pFile);
    fclose(pFile);

    vertShader = glsl_CompileShader(GL_VERTEX_SHADER, vsReusable, lstrlenA(vsReusable));
    fragShader = glsl_CompileShader(GL_FRAGMENT_SHADER, fs, lstrlenA(fs));
    free(fs);

    if (vertShader && fragShader) {
        program = cs->nShaderID = glsl_LinkShaders(vertShader, fragShader);
        glDeleteShader(vertShader); // this only marks shaders for deletion; they'll be
        glDeleteShader(fragShader); // deleted together with program in resetCurAniShader()
    }

    // Store shader file name
    wcscpy(cs->shFileName, wTmp); // don't know if we need it yet

    // Locate sampler uniforms and create textures
    for (int idx = 0; idx <= 3; idx++) { // up to 4 2D samplers
        if (cs->samplerName[idx][0]) {
            strcpy(samplerMap, cs->samplerName[idx]);
            cs->samplerLoc[idx] = glGetUniformLocation(program, samplerMap); // still name, not map!
            if (strstr(samplerMap, "nomip_")) {
                strcpy(samplerMap, &samplerMap[6]);
                bNoMip = TRUE;
            }
            else if (strstr(samplerMap, "mip_"))
                strcpy(samplerMap, &samplerMap[4]);
            if (p = strstr(samplerMap, "_")) // replace '_' with '.' to get valid map file name
                *p = '.';
            Path_Combine(wTmp, EXEresource(), L"Animated\\");
            Add_Str(wTmp, cswconv(samplerMap));
            if (Mobj_createGlTextureFromFileEX(wTmp, X, Y, lpArray, TEX_REPEAT)) {
                glGenTextures(1, &(cs->samplerMapID[idx]));
                glBindTexture(GL_TEXTURE_2D, cs->samplerMapID[idx]);

                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                if (bNoMip) {
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, X, Y, 0, GL_RGBA, GL_UNSIGNED_BYTE, lpArray);
                }
                else {
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8, X, Y, GL_RGBA, GL_UNSIGNED_BYTE, lpArray);
                }

                glBindTexture(GL_TEXTURE_2D, 0);
                delete[] lpArray; lpArray = NULL;
            }
        }
    }

    // Locate float and vector uniforms (common for all background shaders)
    cs->nTimeLoc = glGetUniformLocation(program, "iTime");
    cs->nResLoc = glGetUniformLocation(program, "iResolution");
    cs->nMouseLoc = glGetUniformLocation(program, "iMouse");
    cs->nDateLoc = glGetUniformLocation(program, "iDate");

    return program;
}


Now if you run this shader, you'll see the darker clouds are crisp and clear and devoid of dither at any main window sizes.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 13, 2019, 07:33:31 pm
tinicloud.fs

The changes have been done, and it runs perfectly well now, thank you!

Perhaps we could just use a blue color for the shader background, rather than black.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 13, 2019, 07:45:14 pm
Perhaps we could just use a blue color for the shader background, rather than black.

I don't quite get you here. Shaders have no background colors in the sense of OpenGL window background color. Every pixel in the viewport is drawn by the shader code in the color calculated as gl_FragColor.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 13, 2019, 07:48:34 pm
See this
https://blog.demofox.org/2017/11/26/dissecting-tiny-clouds/
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 13, 2019, 08:20:07 pm
No Patrice,

Our code reproduces 100% of what you see at the link you posted regarding the sky colors.

But!

The original shader uses the same weird 32-bit noise texture originally used in the canyon shader and not available anywhere on the net for downloading. I went through a lot of PITA to design my own that would work satisfactorily in canyon.fs but it wouldn't fit in tinyclouds.fs. So I used another color noise texture available on the net and tweaked the d parameter a little to make the cloud shapes more or less veritable.

I don't think we can make our shader any better than that, color-wise.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 13, 2019, 08:28:16 pm
By me the sky is black as you can see on this screen shot

Here is the shader i am using:

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
uniform sampler2D nomip_colornoise_png; // texture in TU0

#define T texture(nomip_colornoise_png, (s * p.zw + ceil(s * p.x)) / 2e2).y / (s += s) * 4.0

void main() {
    vec4 p;
    vec4 d = vec4(0.8, 0.0, gl_FragCoord.xy / iResolution.y - 0.7); // MLL: was -0.8
    vec4 c = vec4(0.6, 0.7, d);
    gl_FragColor = c - d.w;

    float f, s;
    for (float t = 2e2 + sin(dot(gl_FragCoord, gl_FragCoord)); --t > 0.0; p = 0.065 * t * d) { // MLL: was =0.05
        p.xz += iTime;
        s = 1.0; // MLL: was 2.0
        f = p.w + 1.0 - T - T - T - T;
       if (f < 0.0)
            gl_FragColor += (gl_FragColor - 1.0 - 0.75 * f * c.zyxw) * f * 0.4; // MLL: added 0.75*
    }
}
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 13, 2019, 09:48:50 pm
It gets dark only if a model is/was loaded. Otherwise, it's originally blue.

This most likely means that some texture unit does not get properly reset/cleared after the model render pass in the previous render frame before the background shader is drawn in the current render frame.

This will need some time to debug. I think I'll be able to do it tomorrow. It's near midnight here now.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 13, 2019, 10:03:15 pm
Quote
It gets dark only if a model is/was loaded. Otherwise, it's originally blue
Absolutly true!

If i start robots2 with the anilight layer, then select tinyclouds, the sky is black, else it is blue  ???
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 03:06:34 am
In fact, we have two shaders whose colors suffer on model loading: TinyClouds.fs and MatrixRadial.fs. I have fixed both of them.

1. TinyClouds.fs: (may not reassign built-in uniforms such as gl_FragColor)

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
uniform sampler2D nomip_colornoise_png; // texture in TU0

#define T texture(nomip_colornoise_png, (s * p.zw + ceil(s * p.x)) / 2e2).y / (s += s) * 4.0

void main() {
    vec4 p;
    vec4 d = vec4(0.8, 0.0, gl_FragCoord.xy / iResolution.y - 0.7); // MLL: was -0.8
    vec4 c = vec4(0.6, 0.7, d);
    vec4 color = c - d.w;

    float f, s;
    for (float t = 2e2 + sin(dot(gl_FragCoord, gl_FragCoord)); --t > 0.0; p = 0.065 * t * d) { // MLL: was =0.05
        p.xz += iTime;
        s = 1.0; // MLL: was 2.0
        f = p.w + 1.0 - T - T - T - T;
        if (f < 0.0)
            color += (color - 1.0 - 0.75 * f * c.zyxw) * f * 0.4; // MLL: added 0.75*
    }
    gl_FragColor = vec4(color.rgb, 1.0);
}


2. MatrixRadial.fs: (gl_FragColor alpha must always be 1.0)

Change the shader's last-but-one line to
  gl_FragColor = vec4((c * (1. - dot(g, g)) * .2 / abs((fract(f) - .5) * 8.)).rgb, 1.);


3. And Patrice, we're having problems with your recent mods. If an animated background shader is running without a model and Animate reset is on (which it usually is), then D&D'ing a model to load into the viewport freezes it at its farthest distance and makes the viewport not responsive to the mouse. To revive it, Close all and clear scene must be clicked.

Can you look into this matter?
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 10:13:00 am
Thank you for the shader fixes, both of them work well now.

About point 3, i do not see the same behavior than you.
The animation is freezed while loading the D&D model (seems normal to me),
and the animation listview becomes unresponsive.

I shall look at this in debug mode to understand what is going on.
And first i have to remember the purpose of "Animate reset" (i almost never use it) ;)

Added:
There is definitly a problem with the listview when using shaders.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 01:44:44 pm
Patrice,

Animate reset is animation (slow motion zoom and rotation) of the model when it is reset to its [0,0] initial position on load or on clicking Reset view. (see AnimateReset video below)

Now watch how it all stalls for me in the latest OR build: (see BrokenModelLoad video below)

0. When in animated backgrounds mode, the listview selection doesn't follow the mouse click on another shader.
1. Neither does the listview remember the animated shader it was running when Reload model is clicked. It simply reverts to the default static background.
2. When an animated background is running, an attempt to drag-and-drop a model into the viewport freezes the model and background at its farthest position in the zoom sequence.
3. If the viewport is clicked at this point in time, the animated background changes to static but the model remains unmovable until Close all and clear scene. Finally, all this havoc ends up in shaders not being able to compile and link at all for some unknown reason... :(
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 01:49:58 pm
Now see how it all worked (listview selection of animated shaders, model D&D and animated zoom on load, and model reload with anibkgnd still staying the same) in my previous build of OR before any of your latest 2.81/2.83 mods were introduced.  ???
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 01:54:13 pm
I guess I'll have to do all the cleanup myself eventually because I don't think you are aware of all the pitfalls and bottlenecks there are in such a sensitive organism as modern ObjReader... :-\
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 01:56:45 pm
Here are a couple of fixes to apply into Main.cpp

Close to the end of gl_LoadModel
near line 1344
        // resetCurAniShader(); // PAT: 12-14-2019 done in parseAniShader
        parseAniShader(gsw_wallpaper);
        if (gl_LoadAniBackgrounds(GetDlgItem(gP.hMain, IDC_LISTBOX), gsw_wallpaper)) {
            gP.tCurAniBkgndShader.nShaderID = glsl_LoadShaderFromFile(gsw_wallpaper); // PAT: 11-25-2019 char to wchar
            if (gP.tCurAniBkgndShader.nShaderID) {
                wcscopy(gsw_shader, gsw_wallpaper);
                rAniStart = GetTickCount64() / 1000.0f;
                StartSync();
                CheckMenuItem(gR.hAniMenu, MENU_ANI_BKGND, MF_CHECKED);
            }
        }


In case MENU_ANI_BKGND
near line 2332
    case MENU_ANI_BKGND: // MLL 06-01-2019: ani backgrounds
        gP.bAniBkgnd = !gP.bAniBkgnd;
        if (gP.bAniBkgnd) {
            dwStyle = MF_CHECKED;
            // resetCurAniShader(); // PAT: 12-14-2019 done in parseAniShader
            if (lstrlen(gsw_shader) == 0) { // PAT: 11-25-2019
                wcscopy(zPath, L"voronoi.fs"); // default
            } else {
                wcscopy(zPath, gsw_shader);
            }
            parseAniShader(zPath); // PAT: 11-25-2019
            if (!gl_LoadAniBackgrounds(GetDlgItem(gP.hMain, IDC_LISTBOX), zPath)) { // PAT: 11-25-2019
                CheckMenuItem(gR.hAniMenu, MENU_ANI_BKGND, MF_UNCHECKED);
                EnableMenuItem(gR.hAniMenu, MENU_ANI_BKGND, MF_GRAYED);
                break;
            }
            gP.tCurAniBkgndShader.nShaderID = glsl_LoadShaderFromFile(zPath); // PAT: 11-25-2019 char to wchar
            rAniStart = GetTickCount64() / 1000.0f;
            StartSync();
        } else {


In case WM_NOTIFY:
near line 3016

            if ((ptNMLV->hdr.code == LVN_ITEMCHANGED) || (ptNMLV->hdr.code == NM_CLICK)) {
                // N.B. Patrice: on LMB down, list box sends both these messages one after another,
                // which means wallpaper is reloaded twice. It's fast and unnoticeable for PNGs but
                // not so in case of shaders. Comparison with static "last-used" buffer will help
                // to avoid unnecessary reloads.
                static WCHAR wasFile[MAX_PATH];
                ListView_GetItemText(hCtrl, ListView_GetCurrentLine(hCtrl), 0, &zTxt[0], MAX_PATH);
                if (*zTxt && (lstrcmpi(wasFile, zTxt) != 0)) {
                    StringCchCopy(wasFile, MAX_PATH - 1, zTxt);
                    if (gP.bAniBkgnd) { // MLL 06-01-2019: ani backgrounds
                        if (parseAniShader(zTxt)) {
                            //gP.tCurAniBkgndShader.nShaderID = glsl_LoadShaderFromFile(wcsconv(zTxt));
                            gP.tCurAniBkgndShader.nShaderID = glsl_LoadShaderFromFile(zTxt); // PAT: 11-25-2019 wchar is now the default
                            rAniStart = GetTickCount64() / 1000.0f;
                            StartSync();
                        }
                        WindowRedraw(hCtrl); // PAT: 12-14-2019
                    } else {
                        Path_Combine(gP.mt.FullName, EXEresource(), zTxt);
                        if (ZI_UpdateNamedGLTextureFromFileEx(gP.mt.FullName, gP.mt.Texture, gP.mt.Square) == 0) {
                            Mobj_setWallPaper(gP.mt.FullName);
                            gP.bRedraw = TRUE; // Redraw the OpenGL scene
                        }
                    }
                }
            }


Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 02:01:25 pm
Remember I am using Windows 10.

Also make a quick test with the binary attached to this post, just to make sure we are using exactly the same code.

Because i am unable to reproduce the behavior shown on your video(s) with the binary i am using.

Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 02:16:14 pm
The binaries operate differently for me (I haven't yet added your fixes above). Yours doesn't freeze the listview focus. But it still freezes Animate reset on model load, and it doesn't preserve the current animated background on model load or reload simply resetting it to the default static back02.jpg at all times (except when specified explicitly in the MAT file).
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 02:48:08 pm
Re. Win 10

Strategically:

I know MS is quitting Win 7 support completely this coming February. I'll be moving my GTX1060 and monitors to my Win 10 box making it my main development workstation.

But I stay strongly in favor of backwards compatibility. Our product isn't an AAA computer game, after all, but a rank and file indie hobbyist model viewer despite all its merits among its compatibles.

Therefore, I'll keep the both of my Win 7 boxes (AMD/ATi Radeon and nVidia/GTX550) at ready to be constantly checking OR for backwards compatibility because I know there's gonna be millions of Win 7 fans for many years to come, with or without MS support. And I will not be considering OR builds ready for public release until they are fully functional under, and compatible with, both Win 10 and Win 7. ::)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 02:49:19 pm
Here is another fix that should solve the suzanne behavior shown on your video

void gl_LoadModel(IN WCHAR* pszFilename) {

    BassCloseChannel(); // 10-09-2019 Bass.dll
    ClearMemory(&gB.playaudio, sizeof(gB.playaudio));
    gB.volume = 0.125f; // 10-09-2019 Bass.dll
    gB.loop = 0;        // 10-09-2019 Bass.dll

    if (gP.bObjectLoaded || gP.bAniBkgnd) // PAT: 12-06-2019
        gl_CloseAll();


AND in gl_CloseAll

void gl_CloseAll() { // MLL 12-20-2018: unload model and reset viewport
    RECT vr = { 0 };

    //if (gP.bObjectLoaded) { // PAT: 12-14-2017
        BassCloseChannel();
        ClearMemory(&gP.wModelPath, sizeof(gP.wModelPath));
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 02:55:56 pm
When anything works as expected by me on W10, i just assume it would work the same on Seven, but i have no way to make sure of this, except when my friend check the same code on his computer  ;)

Added:
The Galvanize.fs shader
Code: [Select]
//***************************************************************************************************
//
// Galvanize / Alcatraz
// Jochen "Virgill" Feldkoetter
//
// Intro for Nordlicht demoparty 2014      Shadertoy version
//
//***************************************************************************************************

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

int efx = 0;
int refleco = 0;
int snowo = 0;
vec4 orbitTrap = vec4(0.0);
float blend =0.0;
float d = 0.0;
float m = 0.0;
float kalitime =0.;
float depth = 0.;     
float prec =0.;
const float scene = 35.;


// Rotate
vec3 rotXaxis(vec3 p, float rad)
{
float z2 = cos(rad) * p.z - sin(rad) * p.y;
float y2 = sin(rad) * p.z + cos(rad) * p.y;
p.z = z2;
p.y = y2;
return p;
}

vec3 rotYaxis(vec3 p, float rad)
{
float x2 = cos(rad) * p.x - sin(rad) * p.z;
float z2 = sin(rad) * p.x + cos(rad) * p.z;
p.x = x2;
p.z = z2;
return p;
}

vec3 rotZaxis(vec3 p, float rad)
{
float x2 = cos(rad) * p.x - sin(rad) * p.y;
float y2 = sin(rad) * p.x + cos(rad) * p.y;
p.x = x2;
p.y = y2;
return p;
}


// noise functions
float rand1(vec2 co)
{
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

float rand2(vec2 co)
{
    return fract(cos(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}




// polyomial smooth min (IQ)
float sminPoly( float a, float b, float k )
{
    float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
    return mix( b, a, h ) - k*h*(1.0-h);
}


// exponential smooth min (IQ)
float smin( float a, float b, float k )
{
    float res = exp( -k*a ) + exp( -k*b );
    return -log( res )/k;
}


// length
float length2(vec2 p)
{
  return dot(p, p);
}

// worley effect
float worley(vec2 p)
{
float d = 1.;
for (int xo = -1; xo <= 1; ++xo)
for (int yo = -1; yo <= 1; ++yo)
    {
vec2 tp = floor(p) + vec2(xo, yo);
d = min(d, length2(p - tp - vec2(rand1(tp))));
}
return 3.*exp(-4.*abs(2.*d - 1.));
}

float fworley(vec2 p)
{
return sqrt(sqrt(sqrt(worley(p*32. + 4.3 + iTime*.250) * sqrt(worley(p * 64. + 5.3 + iTime * -.125)) * sqrt(sqrt(worley(p * -128. +7.3))))));
}


// menger
float NewMenger(vec3 z)
{
float Scale = 3.0;
vec3 Offset = vec3(1.0,1.0,1.0);
int Iterations = 6;
int ColorIterations = 3;

    for(int n = 0; n < 6; n++)
{
z.z*=1.+0.2*sin(iTime/4.0)+0.1;
z = abs(z);
if (z.x<z.y){ z.xy = z.yx;}
if (z.x< z.z){ z.xz = z.zx;}
if (z.y<z.z){ z.yz = z.zy;}
z = Scale*z-Offset*(Scale-1.0);
if( z.z<-0.5*Offset.z*(Scale-1.0))  z.z+=Offset.z*(Scale-1.0);

if (n<ColorIterations) orbitTrap = min(orbitTrap, (vec4(abs(z),dot(z,z))));

}
return abs(length(z) ) * pow(Scale, float(-Iterations-1));
}



// mandelbulb (Fractalforums.com)
float Mandelbulb(vec3 p)
{
float Scale = 3.0;
int Iterations = 6;
int ColorIterations = 1;
float parachute=(1.-min(1.8*abs(sin((iTime-5.0)*3.1415/scene)),1.0)); // Fallschirm
parachute = smoothstep(0.0,1.0,parachute)*35.0;
vec3 w = p;
float dr = 1.0+parachute;
float r = 0.;
    for (int i=0; i<6; ++i)
{
    r = length(w);
if (r>4.0) break;
dr*=pow(r, 7.)*8.+1.;
float x = w.x; float x2 = x*x; float x4 = x2*x2;
float y = w.y; float y2 = y*y; float y4 = y2*y2;
float z = w.z; float z2 = z*z; float z4 = z2*z2;
float k3 = x2 + z2;
float k2 = inversesqrt( pow(k3, 7.0) );
float k1 = x4 + y4 + z4 - 6.0*y2*z2 - 6.0*x2*y2 + 2.0*z2*x2;
float k4 = x2 - y2 + z2;
w =  vec3(64.0*x*y*z*(x2-z2)*k4*(x4-6.0*x2*z2+z4)*k1*k2,-16.0*y2*k3*k4*k4 + k1*k1,-8.0*y*k4*(x4*x4 - 28.0*x4*x2*z2 + 70.0*x4*z4 - 28.0*x2*z2*z4 + z4*z4)*k1*k2);
w-=p;
w = rotYaxis(w,sin(iTime*0.14));
w = rotZaxis(w,cos(iTime*0.2));
orbitTrap = min(orbitTrap, abs(vec4(p.x*w.z, p.y*w.x, 0., 0.)));
if (i>=ColorIterations+2) orbitTrap = vec4(0.0);
}
return  .5*log(r)*r/dr;
}

// kalibox (Kali / Fractalforums.com)
float Kalibox(vec3 pos)
{
float Scale = 1.84;
int Iterations = 14;
int ColorIterations = 3;
float MinRad2 = 0.34;
vec3 Trans = vec3(0.076,-1.86,0.036);
vec3 Julia = vec3(-0.66,-1.2+(kalitime/80.),-0.66);
vec4 scale = vec4(Scale, Scale, Scale, abs(Scale)) / MinRad2;
float absScalem1 = abs(Scale - 1.0);
float AbsScaleRaisedTo1mIters = pow(abs(Scale), float(1-Iterations));
    vec4 p = vec4(pos,1), p0 = vec4(Julia,1);
for (int i=0; i<14; i++)
{
p.xyz=abs(p.xyz)+Trans;
float r2 = dot(p.xyz, p.xyz);
p *= clamp(max(MinRad2/r2, MinRad2), 0.0, 1.0);
p = p*scale + p0;
if (i<ColorIterations) orbitTrap = min(orbitTrap, abs(vec4(p.xyz,r2)));
}
return (    (length(p.xyz) - absScalem1) / p.w - AbsScaleRaisedTo1mIters    );
}

// balls and cube
float Balls(vec3 pos)
{
m = length(max(abs(rotYaxis(rotXaxis(pos+vec3(0.0,-0.3,0.0),iTime),iTime*0.3))-vec3(0.35,0.35,0.35),0.0))-0.02;
m = smin (m, length(pos+vec3(0.0,-0.40,1.2+0.5*sin(0.8*iTime+0.0)))-0.4,7.4);
m = smin (m, length(pos+vec3(0.0,-0.40,-1.2-0.5*sin(0.8*iTime+0.4)))-0.4,7.4);
m = smin (m, length(pos+vec3(-1.2-0.5*sin(0.8*iTime+0.8),-0.40,0.0))-0.4,7.4);
m = smin (m, length(pos+vec3(1.2+0.5*sin(0.8*iTime+1.2),-0.40,0.0))-0.4,7.4);
m = smin (m, length(pos+vec3(0.0,-1.6+0.5*-sin(0.8*iTime+1.6),0.0))-0.4,7.4);
//m+= klang1*(0.003*cos(50.*pos.x)+0.003*cos(50.*pos.y)); //distortion
orbitTrap = vec4(length(pos)-0.8*pos.z,length(pos)-0.8*pos.y,length(pos)-0.8*pos.x,0.0)*1.0;
return m;
}

// plane
float sdPlane(in vec3 p)
{
return p.y+(0.025*sin(p.x*10.  +1.4*iTime  ))+(0.025*sin(p.z*12.3*cos(0.4-p.x)+  1.6*iTime  ))-0.05;
}

// cylinder
float sdCylinder( vec3 p, vec3 c )
{
return length(p.xz-c.xy)-c.z;
}


// scene
float map(in vec3 p)
{
orbitTrap = vec4(10.0);
d = sdPlane(p);

if (efx == 0) { // balls and cube
m = Balls(p);
}
if (efx == 1) { // milky menger
m = NewMenger(rotYaxis(rotXaxis(p-vec3(0.0,sin(iTime/0.63)+0.2,0.0),0.15*iTime),0.24*iTime));
}
if (efx == 2) { // mandelbulb
m = Mandelbulb(rotYaxis(rotXaxis(p,iTime*0.1),0.21*iTime));
}
if (efx == 3) { // kalibox
m = Kalibox(rotYaxis(rotXaxis(p,1.50),0.1*iTime));
}
if (efx == 4 || efx == 5) { // tunnel or swirl
vec3 c = vec3(2.0, 8.0, 2.0);
vec3 q = mod(p-vec3(1.0,0.1*iTime,1.0),c)-0.5*c;
float kali = Kalibox(rotYaxis(q,0.04*iTime));
m = max(kali,-sdCylinder(p,vec3(0.0,0.0,0.30+0.1*sin(iTime*0.2))) );
}
d = sminPoly (m, d, 0.04);
    return d;
}


// normal calculation
vec3 calcNormal(in vec3 p)
{
    vec3 e = vec3(0.001, 0.0, 0.0);
    vec3 nor = vec3(map(p + e.xyy) - map(p - e.xyy),  map(p + e.yxy) - map(p - e.yxy),  map(p + e.yyx) - map(p - e.yyx));
    return normalize(nor);
}

// cast
float castRay(in vec3 ro, in vec3 rd, in float maxt)
{
    float precis = prec;
    float h = precis * 2.0;
    float t = depth;

    for(int i = 0; i < 122; i++)
{
        if(abs(h) < precis || t > maxt) break;
        orbitTrap = vec4(10.0);
h = map(ro + rd * t);
        t += h;
}
    return t;
}

// softshadow (IQ)
float softshadow(in vec3 ro, in vec3 rd, in float mint, in float maxt, in float k)
{
    float sh = 1.0;
    float t = mint;
    float h = 0.0;
    for(int i = 0; i < 19; i++)  //23 gut!
{
        if(t > maxt) continue;
orbitTrap = vec4(10.0);
        h = map(ro + rd * t);
        sh = min(sh, k * h / t);
        t += h;
    }
    return sh;
}


// orbit color
vec3 BaseColor = vec3(0.2,0.2,0.2);
vec3 OrbitStrength = vec3(0.8, 0.8, 0.8);
vec4 X = vec4(0.5, 0.6, 0.6, 0.2);
vec4 Y = vec4(1.0, 0.5, 0.1, 0.7);
vec4 Z = vec4(0.8, 0.7, 1.0, 0.3);
vec4 R = vec4(0.7, 0.7, 0.5, 0.1);
vec3 getColor()
{
orbitTrap.w = sqrt(orbitTrap.w);
vec3 orbitColor = X.xyz*X.w*orbitTrap.x + Y.xyz*Y.w*orbitTrap.y + Z.xyz*Z.w*orbitTrap.z + R.xyz*R.w*orbitTrap.w;
vec3 color = mix(BaseColor,3.0*orbitColor,OrbitStrength);
return color;
}

// particles (Andrew Baldwin)
float snow(vec3 direction)
{
float help = 0.0;
const mat3 p = mat3(13.323122,23.5112,21.71123,21.1212,28.7312,11.9312,21.8112,14.7212,61.3934);
vec2 uvx = vec2(direction.x,direction.z)+vec2(1.,iResolution.y/iResolution.x)*gl_FragCoord.xy / iResolution.xy;
float acc = 0.0;
float DEPTH = direction.y*direction.y-0.3;
float WIDTH =0.1;
float SPEED = 0.1;
for (int i=0;i<10;i++)
{
float fi = float(i);
vec2 q = uvx*(1.+fi*DEPTH);
q += vec2(q.y*(WIDTH*mod(fi*7.238917,1.)-WIDTH*.5),SPEED*iTime/(1.+fi*DEPTH*.03));
vec3 n = vec3(floor(q),31.189+fi);
vec3 m = floor(n)*.00001 + fract(n);
vec3 mp = (31415.9+m)/fract(p*m);
vec3 r = fract(mp);
vec2 s = abs(mod(q,1.)-.5+.9*r.xy-.45);
float d = .7*max(s.x-s.y,s.x+s.y)+max(s.x,s.y)-.01;
float edge = .04;
acc += smoothstep(edge,-edge,d)*(r.x/1.0);
help = acc;
}
return help;
}

void main()
{
   
    if (iTime >=0. && iTime <=35. ) {efx=4; refleco=0; snowo=0;}
    if (iTime >35. && iTime <=70. ) {efx=0; refleco=1; snowo=1;}
    if (iTime >70. && iTime <=105.) {efx=1; refleco=0; snowo=1;}
    if (iTime >105.&& iTime <=140.) {efx=3; refleco=0; snowo=1;}
    if (iTime >140.&& iTime <=175.) {efx=2; refleco=0; snowo=1;} 
    if (iTime >175.&& iTime <=210.) {efx=4; refleco=0; snowo=0;}   
    if (iTime >210.&& iTime <=245.) {efx=5; refleco=0; snowo=0;} 

blend=min(2.0*abs(sin((iTime+0.0)*3.1415/scene)),1.0);
    if (iTime >245.) blend = 0.;
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    vec2 p = uv * 2.0 - 1.0;
p.x *= iResolution.x / iResolution.y;
float theta = sin(iTime*0.03) * 3.14 * 2.0;
    float x = 3.0 * cos(theta)+0.007*rand1(gl_FragCoord.xy);
    float z = 3.0 * sin(theta)+0.007*rand2(gl_FragCoord.xy);
vec3 ro; // camera

if (efx==0) {
prec = 0.001;
ro = vec3(x*0.2+1.0, 5.0, z*2.0-3.); // camera balls and cube 
}
if (efx==1) {
prec = 0.002;
ro = vec3(x*1.2, 7.0, z*2.0);  // camera menger
}
if (efx==2) {
prec = 0.002;
ro = vec3(x*1.0, 6.2, z*2.8);  // camera mandelbulb
depth =4.;
}
if (efx==3) {
kalitime = 40.;
prec = 0.002;
ro = vec3(x*1.7, 2.6, 2.0); // camera kalibox
}
if (efx==4) {
//time = iTime -2.5;
prec = 0.002;
kalitime = iTime-15.0;
ro = vec3(0.0, 8.0, 0.0001);    // camera tunnel
}
if (efx==5) {
prec = 0.004;
kalitime = 210.+175.;
ro = vec3(0, 3.8, 0.0001);    // camera swirl
}


vec3 ta = vec3(0.0, 0.25, 0.0);
    vec3 cw = normalize(ta - ro);
    vec3 cp = vec3(0.0, 1.0, 0.0);
    vec3 cu = normalize(cross(cw, cp));
    vec3 cv = normalize(cross(cu, cw));
vec3 rd = normalize(p.x * cu + p.y * cv + 7.5 * cw);

// render:
    vec3 col = vec3(0.0);
    float t = castRay(ro, rd, 12.0);
vec3 pos = ro + rd *t;
vec3 nor = calcNormal(pos);
vec3 lig;
if (efx==4 || efx ==5 )  lig = normalize(vec3(-0.4*sin(iTime*0.15), 1.0, 0.5));
else if (efx==3)   lig = normalize(vec3(-0.1*sin(iTime*0.2), 0.2, 0.4*sin(iTime*0.1)));
else lig = normalize(vec3(-0.4, 0.7, 0.5));
float dif = clamp(dot(lig, nor), 0.0, 1.0);
float spec = pow(clamp(dot(reflect(rd, nor), lig), 0.0, 1.0), 16.0);
float sh;
if (efx == 1 || efx == 5) sh = softshadow(pos, lig, 0.02, 20.0, 7.0);
vec3 color = getColor();
col = ((0.8*dif+ spec) + 0.35*color);
if (efx !=1 && efx != 5) sh = softshadow(pos, lig, 0.02, 20.0, 7.0);
col = col*clamp(sh, 0.0, 1.0);


// reflections:
if (refleco == 1) {
    vec3 col2 = vec3(0.0);
vec3 ro2 = pos-rd/t;
vec3 rd2 = reflect(rd,nor);
    float t2 = castRay(ro2, rd2, 7.0);
vec3 pos2 = vec3(0.0);
if (t2<7.0) {
pos2 = ro2 + rd2* t2;
}
    vec3 nor2 = calcNormal(pos2);
float dif2 = clamp(dot(lig, nor2), 0.0, 1.0);
float spec2 = pow(clamp(dot(reflect(rd2, nor2), lig), 0.0, 1.0), 16.0);
col+= 0.22*vec3(dif2*color+spec2);
}

// postprocessing
float klang1=0.75;
vec2 uv2=-0.3+2.*gl_FragCoord.xy/iResolution.xy;
col-=0.20*(1.-klang1)*rand1(uv2.xy*iTime);
col*=.9+0.20*(1.-klang1)*sin(10.*iTime+uv2.x*iResolution.x);
col*=.9+0.20*(1.-klang1)*sin(10.*iTime+uv2.y*iResolution.y);
float Scr=1.-dot(uv2,uv2)*0.15;
vec2 uv3=gl_FragCoord.xy/iResolution.xy;
float worl = fworley(uv3 * iResolution.xy / 2100.);
worl *= exp(-length2(abs(2.*uv3 - 1.)));
worl *= abs(1.-0.6*dot(2.*uv3-1.,2.*uv3-1.));
if (efx==4) col += vec3(0.4*worl,0.35*worl,0.25*worl);
if (efx==5)  col += vec3(0.2*worl);
float g2 = (blend/2.)+0.39;
float g1 = ((1.-blend)/2.);
if (uv3.y >=g2+0.11) col*=0.0;
if (uv3.y >=g2+0.09) col*=0.4;
if (uv3.y >=g2+0.07) {if (mod(uv3.x-0.06*iTime,0.18)<=0.16) col*=0.5;}
if (uv3.y >=g2+0.05) {if (mod(uv3.x-0.04*iTime,0.12)<=0.10) col*=0.6;}
if (uv3.y >=g2+0.03) {if (mod(uv3.x-0.02*iTime,0.08)<=0.06) col*=0.7;}
if (uv3.y >=g2+0.01) {if (mod(uv3.x-0.01*iTime,0.04)<=0.02) col*=0.8;}
if (uv3.y <=g1+0.10) {if (mod(uv3.x+0.01*iTime,0.04)<=0.02) col*=0.8;}
if (uv3.y <=g1+0.08) {if (mod(uv3.x+0.02*iTime,0.08)<=0.06) col*=0.7;}
if (uv3.y <=g1+0.06) {if (mod(uv3.x+0.04*iTime,0.12)<=0.10) col*=0.6;}
if (uv3.y <=g1+0.04) {if (mod(uv3.x+0.06*iTime,0.18)<=0.16) col*=0.5;}
if (uv3.y <=g1+0.02) col*=0.4;
if (uv3.y <=g1+0.00) col*=0.0;

if (snowo == 1) gl_FragColor = (vec4(col*1.0*Scr-1.6*snow(cv), 1.0)*blend)*vec4(1.0, 0.93, 1.0, 1.0);
else gl_FragColor = vec4(col*1.0*Scr, 1.0)*blend;
}

Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 04:12:16 pm
Your shader is beautiful but very heavy; with Turbo off and under FXAA, my GPU is 75%+ full-screen...

Here's another one from your list:

FractalFlythrough.fs

Code: [Select]
/*
Fractal Flythrough
------------------

Moving a camera through a fractal object. It's a work in progress.

I was looking at one of Dr2's shaders that involved moving a camera through a set of way points (set
out on the XZ plane), and thought it'd be cool to do a similar 3D version. The idea was to create a
repetitive kind of fractal object, give the open space nodes a set random direction, create some
spline points, then run a smooth camera through them. Simple... right? It always seems simple in my
head, but gets progressively harder when I try it in a shader. :)

I've run into that classic up-vector, camera flipping problem... At least, I think that's the problem?
Anyway, I'm hoping the solution is simple, and that someone reading this will be able to point me in
the right direction.

For now, I've set up a set of 16 random looping points that the camera seems reasonably comfortable
with. Just for the record, the general setup works nicely, until the camera loops back on itself in
the YZ plane. I'm guessing that increasing the number of way points may eradicate some of the
    intermittent camera spinning, but I figured I'd leave things alone and treat it as a feature. :)

By the way, I was thankful to have Otavio Good's spline setup in his "Alien Beacon" shader as a
reference. On a side note, that particular shader is one of my all time favorites on this site.

The rendering materials are slightly inspired by the Steampunk genre. Timber, granite, brass, etc.
It needs spinning turbines, gears, rivots, and so forth, but that stuff's expensive. Maybe later.
Tambako Jaguar did a really cool shader in the Steampunk aesthetic. The link is below.

Besides camera path, there's a whole bunch of improvements I'd like to make to this. I've relied on
occlusion to mask the fact that there are no shadows. I'm hoping to free up some cycles, so I can put
them back in. I'd also like to add extra detail, but that also slows things down. As for the comments,
they're very rushed, but I'll tidy those up as well.

References:

Alien Beacon - Otavio Good
https://www.shadertoy.com/view/ld2SzK

    Steampunk Turbine - TambakoJaguar
    https://www.shadertoy.com/view/lsd3zf

    // The main inspiration for this shader.
Mandelmaze in Daylight - dr2
    https://www.shadertoy.com/view/MdVGRc
*/

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
uniform sampler2D metal_jpg;

const float FAR = 50.0; // Far plane.

// Used to identify individual scene objects. In this case, there are only three: The metal framework, the gold
// and the timber.
float objID = 0.; // Wood = 1., Metal = 2., Gold = 3..

// Simple hash function.
float hash( float n ){ return fract(cos(n)*45758.5453); }

// Tri-Planar blending function. Based on an old Nvidia writeup:
// GPU Gems 3 - Ryan Geiss: https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch01.html
vec3 tex3D(sampler2D t, in vec3 p, in vec3 n ){
    n = max(abs(n), 0.001);
    n /= dot(n, vec3(1));
vec3 tx = texture(t, p.yz).xyz;
    vec3 ty = texture(t, p.zx).xyz;
    vec3 tz = texture(t, p.xy).xyz;

    // Textures are stored in sRGB (I think), so you have to convert them to linear space
    // (squaring is a rough approximation) prior to working with them... or something like that. :)
    // Once the final color value is gamma corrected, you should see correct looking colors.
    return (tx*tx*n.x + ty*ty*n.y + tz*tz*n.z);
}

// Common formula for rounded squares, for all intended purposes.
float lengthN(in vec2 p, in float n){ p = pow(abs(p), vec2(n)); return pow(p.x + p.y, 1.0/n); }

// The camera path: There are a few spline setups on Shadertoy, but this one is a slight variation of
// Otavio Good's spline setup in his "Alien Beacon" shader: https://www.shadertoy.com/view/ld2SzK
//
// Spline point markers ("cp" for camera point). The camera visits each point in succession, then loops
// back to the first point, when complete, in order to repeat the process. In case it isn't obvious, each
// point represents an open space juncture in the object that links to the previous and next point.
// Of course, running a camera in a straight line between points wouldn't produce a smooth camera effect,
// so we apply the Catmull-Rom equation to the line segment.
vec3 cp[16];

void setCamPath(){
    // The larger fractal object has nodes in a 4x4x4 grid.
    // The smaller one in a 2x2x2 grid. The following points
    // map a path to various open areas throughout the object.
    const float sl = 2.*.96;
    const float bl = 4.*.96;

    cp[0] = vec3(0, 0, 0);
    cp[1] = vec3(0, 0, bl);
    cp[2] = vec3(sl, 0, bl);
    cp[3] = vec3(sl, 0, sl);
    cp[4] = vec3(sl, sl, sl);
    cp[5] = vec3(-sl, sl, sl);
    cp[6] = vec3(-sl, 0, sl);
    cp[7] = vec3(-sl, 0, 0);

    cp[8] = vec3(0, 0, 0);
    cp[9] = vec3(0, 0, -bl);
    cp[10] = vec3(0, bl, -bl);
    cp[11] = vec3(-sl, bl, -bl);
    cp[12] = vec3(-sl, 0, -bl);
    cp[13] = vec3(-sl, 0, 0);
    cp[14] = vec3(-sl, -sl, 0);
    cp[15] = vec3(0, -sl, 0);

    // Tighening the radius a little, so that the camera doesn't hit the walls.
    // I should probably hardcode this into the above... Done.
    //for(int i=0; i<16; i++) cp[i] *= .96;
}

// Standard Catmull-Rom equation. The equation takes in the line segment end points (p1 and p2), the
// points on either side (p0 and p3), the current fractional distance (t) along the segment, then
// returns the the smooth (cubic interpolated) position. The end result is a smooth transition
// between points... Look up a diagram on the internet. That should make it clearer.
vec3 Catmull(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t){
    return (((-p0 + p1*3. - p2*3. + p3)*t*t*t + (p0*2. - p1*5. + p2*4. - p3)*t*t + (-p0 + p2)*t + p1*2.)*.5);
}

// Camera path. Determine the segment number (segNum), and how far - timewise - we are along it (segTime).
// Feed the segment, the appropriate adjoining segments, and the segment time into the Catmull-Rom
// equation to produce a camera position. The process is pretty simple, once you get the hang of it.
vec3 camPath(float t){
    const int aNum = 16;

    t = fract(t/float(aNum))*float(aNum); // Repeat every 16 time units.

    // Segment number. Range: [0, 15], in this case.
    float segNum = floor(t);
    // Segment portion. Analogous to how far we are alone the individual line segment. Range: [0, 1].
    float segTime = t - segNum;


    if (segNum == 0.) return Catmull(cp[aNum-1], cp[0], cp[1], cp[2], segTime);

    for(int i=1; i<aNum-2; i++){
        if (segNum == float(i)) return Catmull(cp[i-1], cp[i], cp[i+1], cp[i+2], segTime);
    }

    if (segNum == float(aNum-2)) return Catmull(cp[aNum-3], cp[aNum-2], cp[aNum-1], cp[0], segTime);
    if (segNum == float(aNum-1)) return Catmull(cp[aNum-2], cp[aNum-1], cp[0], cp[1], segTime);

    return vec3(0);
}

// Smooth minimum function. There are countless articles, but IQ explains it best here:
// http://iquilezles.org/www/articles/smin/smin.htm
float sminP( float a, float b, float s ){
    float h = clamp( 0.5+0.5*(b-a)/s, 0.0, 1.0 );
    return mix( b, a, h ) - s*h*(1.0-h);
}

// Creating the scene geometry.
//
// There are two intertwined fractal objects. One is a gold and timber lattice, spread out in a 4x4x4
// grid. The second is some metallic tubing spread out over a 2x2x2 grid. Each are created by combining
// repeat objects with various operations. All of it is pretty standard.
//
// The code is a little fused together, in order to save some cycles, but if you're interested in the
// process, I have a "Menger Tunnel" example that's a little easier to decipher.
float map(in vec3 q){

///////////

    // The grey section. I have another Menger example, if you'd like to look into that more closely.
    // Layer one.
  vec3 p = abs(fract(q/4.)*4. - 2.);
  float tube = min(max(p.x, p.y), min(max(p.y, p.z), max(p.x, p.z))) - 4./3. - .015;// + .05;


    // Layer two.
    p = abs(fract(q/2.)*2. - 1.);
  //d = max(d, min(max(p.x, p.y), min(max(p.y, p.z), max(p.x, p.z))) - s/3.);// + .025
  tube = max(tube, sminP(max(p.x, p.y), sminP(max(p.y, p.z), max(p.x, p.z), .05), .05) - 2./3.);// + .025

///////
    // The gold and timber paneling.
    //
    // A bit of paneling, using a combination of repeat objects. We're doing it here in layer two, just
    // to save an extra "fract" call. Very messy, but saves a few cycles... maybe.

    //float panel = sminP(length(p.xy),sminP(length(p.yz),length(p.xz), 0.25), 0.125)-0.45; // EQN 1
    //float panel = sqrt(min(dot(p.xy, p.xy),min(dot(p.yz, p.yz),dot(p.xz, p.xz))))-0.5; // EQN 2
    //float panel = min(max(p.x, p.y),min(max(p.y, p.z),max(p.x, p.z)))-0.5; // EQN 3
    float panel = sminP(max(p.x, p.y),sminP(max(p.y, p.z),max(p.x, p.z), .125), .125)-0.5; // EQN 3

    // Gold strip. Probably not the best way to do this, but it gets the job done.
    // Identifying the gold strip region, then edging it out a little... for whatever reason. :)
    float strip = step(p.x, .75)*step(p.y, .75)*step(p.z, .75);
    panel -= (strip)*.025;

    // Timber bulge. Just another weird variation.
    //float bulge = (max(max(p.x, p.y), p.z) - .55);//length(p)-1.;//
    //panel -= bulge*(1.-step(p.x, .75)*step(p.y, .75)*step(p.z, .75))*bulge*.25;

    // Repeat field entity two, which is just an abstract object repeated every half unit.
    p = abs(fract(q*2.)*.5 - .25);
    float pan2 = min(p.x, min(p.y,p.z))-.05;

    // Combining the two entities above.
    panel = max(abs(panel), abs(pan2)) - .0425;
/////////

    // Layer three. 3D space is divided by three.
    p = abs(fract(q*1.5)/1.5 - 1./3.);
  tube = max(tube, min(max(p.x, p.y), min(max(p.y, p.z), max(p.x, p.z))) - 2./9. + .025); // + .025

    // Layer three. 3D space is divided by two, instead of three, to give some variance.
    p = abs(fract(q*3.)/3. - 1./6.);
  tube = max(tube, min(max(p.x, p.y), min(max(p.y, p.z), max(p.x, p.z))) - 1./9. - .035); //- .025

    // Object ID: Equivalent to: if(tube<panel)objID=2; else objID = 1.; //etc.
    //
    // By the way, if you need to identify multiple objects, you're better off doing it in a seperate pass,
    // after the raymarching function. Having multiple "if" statements in a distance field equation can
    // slow things down considerably.

    //objID = 2. - step(tube, panel) + step(panel, tube)*(strip);
    objID = 1.+ step(tube, panel) + step(panel, tube)*(strip)*2.;
    //objID = 1. + step(panel, tube)*(strip) + step(tube, panel)*2.;

    return min(panel, tube);
}

float trace(in vec3 ro, in vec3 rd){
    float t = 0.0, h;
    for(int i = 0; i < 92; i++){
        h = map(ro+rd*t);
        // Note the "t*b + a" addition. Basically, we're putting less emphasis on accuracy, as
        // "t" increases. It's a cheap trick that works in most situations... Not all, though.
        if(abs(h)<0.001*(t*.25 + 1.) || t>FAR) break; // Alternative: 0.001*max(t*.25, 1.)
        t += h*.8;
    }

    return t;
}


// The reflections are pretty subtle, so not much effort is being put into them. Only eight iterations.
float refTrace(vec3 ro, vec3 rd){
    float t = 0.0;
    for(int i=0; i<16; i++){
        float d = map(ro + rd*t);
        if (d < 0.0025*(t*.25 + 1.) || t>FAR) break;
        t += d;
    }
    return t;
}



/*
// Tetrahedral normal, to save a couple of "map" calls. Courtesy of IQ.
vec3 calcNormal(in vec3 p){

    // Note the slightly increased sampling distance, to alleviate artifacts due to hit point inaccuracies.
    vec2 e = vec2(0.0025, -0.0025);
    return normalize(e.xyy * map(p + e.xyy) + e.yyx * map(p + e.yyx) + e.yxy * map(p + e.yxy) + e.xxx * map(p + e.xxx));
}
*/

// Standard normal function. It's not as fast as the tetrahedral calculation, but more symmetrical. Due to
// the intricacies of this particular scene, it's kind of needed to reduce jagged effects.
vec3 calcNormal(in vec3 p) {
const vec2 e = vec2(0.005, 0);
return normalize(vec3(map(p + e.xyy) - map(p - e.xyy), map(p + e.yxy) - map(p - e.yxy), map(p + e.yyx) - map(p - e.yyx)));
}

// I keep a collection of occlusion routines... OK, that sounded really nerdy. :)
// Anyway, I like this one. I'm assuming it's based on IQ's original.
float calcAO(in vec3 pos, in vec3 nor){
float sca = 2.0, occ = 0.0;
    for( int i=0; i<5; i++ ){
        float hr = 0.01 + float(i)*0.5/4.0;
        float dd = map(nor * hr + pos);
        occ += (hr - dd)*sca;
        sca *= 0.7;
    }
    return clamp( 1.0 - occ, 0.0, 1.0 );
}


// Texture bump mapping. Four tri-planar lookups, or 12 texture lookups in total. I tried to
// make it as concise as possible. Whether that translates to speed, or not, I couldn't say.
vec3 texBump( sampler2D tx, in vec3 p, in vec3 n, float bf){
    const vec2 e = vec2(0.001, 0);

    // Three gradient vectors rolled into a matrix, constructed with offset greyscale texture values.
    mat3 m = mat3( tex3D(tx, p - e.xyy, n), tex3D(tx, p - e.yxy, n), tex3D(tx, p - e.yyx, n));

    vec3 g = vec3(0.299, 0.587, 0.114)*m; // Converting to greyscale.
    g = (g - dot(tex3D(tx,  p , n), vec3(0.299, 0.587, 0.114)) )/e.x; g -= n*dot(n, g);

    return normalize( n + g*bf ); // Bumped normal. "bf" - bump factor.
}


void main(){
// Screen coordinates.
vec2 u = (gl_FragCoord - iResolution.xy*0.5)/iResolution.y;

    float speed = iTime*0.35 + 8.;

    // Initiate the camera path spline points. Kind of wasteful not making this global, but I wanted
    // it self contained... for better or worse. I'm not really sure what the GPU would prefer.
    setCamPath();

// Camera Setup.
    vec3 ro = camPath(speed); // Camera position, doubling as the ray origin.
    vec3 lk = camPath(speed + .5);  // "Look At" position.
    vec3 lp = camPath(speed + .5) + vec3(0, .25, 0); // Light position, somewhere near the moving camera.

    // Using the above to produce the unit ray-direction vector.
    float FOV = 1.57; // FOV - Field of view.
    vec3 fwd = normalize(lk-ro);
    vec3 rgt = normalize(vec3(fwd.z, 0, -fwd.x));
    vec3 up = (cross(fwd, rgt));

        // Unit direction ray.
    vec3 rd = normalize(fwd + FOV*(u.x*rgt + u.y*up));

    // Raymarch the scene.
    float t = trace(ro, rd);

    // Initialize the scene color.
    vec3 col = vec3(0);

    // Scene hit, so color the pixel. Technically, the object should always be hit, so it's tempting to
    // remove this entire branch... but I'll leave it, for now.
    if(t<FAR){
        // This looks a little messy and haphazard, but it's really just some basic lighting, and application
        // of the following material properties: Wood = 1., Metal = 2., Gold = 3..

        float ts = 1.;  // Texture scale.

        // Global object ID. It needs to be saved just after the raymarching equation, since other "map" calls,
        // like normal calculations will give incorrect results. Found that out the hard way. :)
        float saveObjID = objID;

        vec3 pos = ro + rd*t; // Scene postion.
        vec3 nor = calcNormal(pos); // Normal.
        vec3 sNor = nor;

        // Apply some subtle texture bump mapping to the panels and the metal tubing.
        nor = texBump(metal_jpg, pos*ts, nor, 0.002); // + step(saveObjID, 1.5)*0.002

        // Reflected ray. Note that the normal is only half bumped. It's fake, but it helps
        // taking some of the warping effect off of the reflections.
        vec3 ref = reflect(rd, normalize(sNor*.5 + nor*.5));

col = tex3D(metal_jpg, pos*ts, nor); // Texture pixel at the scene postion.

        vec3  li = lp - pos; // Point light.
        float lDist = max(length(li), .001); // Surface to light distance.
        float atten = 1./(1.0 + lDist*0.125 + lDist*lDist*.05); // Light attenuation.
        li /= lDist; // Normalizing the point light vector.

        float occ = calcAO( pos, nor ); // Occlusion.

        float dif = clamp(dot(nor, li), 0.0, 1.0); // Diffuse.
        dif = pow(dif, 4.)*2.;
        float spe = pow(max(dot(reflect(-li, nor), -rd), 0.), 8.); // Object specular.
        float spe2 = spe*spe; // Global specular.

        float refl = .35; // Reflection coefficient. Different for different materials.

        // Reflection color. Mostly fake.
        // Cheap reflection: Not entirely accurate, but the reflections are pretty subtle, so not much
        // effort is being put in.
        float rt = refTrace(pos + ref*0.1, ref); // Raymarch from "sp" in the reflected direction.
        float rSaveObjID = objID; // IDs change with reflection. Learned that the hard way. :)
        vec3 rsp = pos + ref*rt; // Reflected surface hit point.
        vec3 rsn = calcNormal(rsp); // Normal at the reflected surface. Too costly to bump reflections.
        vec3 rCol = tex3D(metal_jpg, rsp*ts, rsn); // Texel at "rsp."
        vec3 rLi = lp-rsp;
        float rlDist = max(length(rLi), 0.001);
        rLi /= rlDist;
        float rDiff = max(dot(rsn, rLi), 0.); // Diffuse light at "rsp."
        rDiff = pow(rDiff, 4.)*2.;
        float rAtten = 1./(1. + rlDist*0.125 + rlDist*rlDist*.05);

        if(rSaveObjID>1.5 && rSaveObjID<2.5){
            rCol = vec3(1)*dot(rCol, vec3(.299, .587, .114))*.7 + rCol*.15;//*.7+.2
            //rDiff *= 1.35;
        }
        if(rSaveObjID>2.5){
             //float rc = dot(rCol, vec3(.299, .587, .114));
             vec3 rFire = pow(vec3(1.5, 1, 1)*rCol, vec3(8, 2, 1.5));//*.5+rc*.5;
             rCol = min(mix(vec3(1.5, .9, .375), vec3(.75, .375, .3), rFire), 2.)*.5 + rCol;
        }

        rCol *= (rDiff + .35)*rAtten; // Reflected color. Not accurate, but close enough.

        // Grey metal inner tubing.
        if(saveObjID>1.5 && saveObjID<2.5){
            // Grey out the limestone wall color.
            col = vec3(1)*dot(col, vec3(.299, .587, .114))*.7 + col*.15;

            refl = .5;
            //dif *= 1.35;
            //spe2 *= 1.35;
        }

        // Gold trimming properties. More effort should probably be put in here.
        // I could just write "saveObjID == 3.," but I get a little paranoid where floats are concerned. :)
        if(saveObjID>2.5){
            // For the screen image, we're interested in the offset height and depth positions. Ie: pOffs.zy.

            // Pixelized dot pattern shade.
            //float c = dot(col, vec3(.299, .587, .114));

            vec3 fire = pow(vec3(1.5, 1, 1)*col, vec3(8, 2, 1.5));//*.5+c*.5;
            col = min(mix(vec3(1, .9, .375), vec3(.75, .375, .3), fire), 2.)*.5 + col;//

            refl = .65;
            //dif *= 1.5;
            //spe2 *= 1.5;
        }


        // Combining everything together to produce the scene color.
        col = col*(dif + .35  + vec3(.35, .45, .5)*spe) + vec3(.7, .9, 1)*spe2 + rCol*refl;
        col *= occ*atten; // Applying occlusion.
    }

    // Applying some very slight fog in the distance. This is technically an inside scene...
    // Or is it underground... Who cares, it's just a shader. :)
    col = mix(min(col, 1.), vec3(0), 1.-exp(-t*t/FAR/FAR*20.));//smoothstep(0., FAR-20., t)
    //col = mix(min(col, 1.), vec3(0), smoothstep(0., FAR-35., t));//smoothstep(0., FAR-20., t)

    // Done.
    gl_FragColor = vec4(sqrt(max(col, 0.)), 1.0);
}
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 04:50:41 pm
Thanks!

Here are a few more

generators.fs
Code: [Select]
// "GENERATORS REDUX" by Kali

// Same fractal as "Ancient Temple" + rotations, improved shading
// (better coloring, AO and  shadows), some lighting effects, and a path for the camera 
// following a liquid metal ball.

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

uniform sampler2D BWNoiseBig_png;

#define ENABLE_HARD_SHADOWS // turn off to enable faster AO soft shadows
//#define ENABLE_VIBRATION
#define ENABLE_POSTPROCESS // Works better on window view rather than full screen


#define RAY_STEPS 70
#define SHADOW_STEPS 50
#define LIGHT_COLOR vec3(.85,.9,1.)
#define AMBIENT_COLOR vec3(.8,.83,1.)
#define FLOOR_COLOR vec3(1.,.7,.9)
#define ENERGY_COLOR vec3(1.,.7,.4)
#define BRIGHTNESS .9
#define GAMMA 1.3
#define SATURATION .85


#define detail .00005
#define t iTime*.25



vec3 lightdir=normalize(vec3(0.5,-0.3,-1.));
vec3 ambdir=normalize(vec3(0.,0.,1.));
const vec3 origin=vec3(0.,3.11,0.);
vec3 energy=vec3(0.01);
#ifdef ENABLE_VIBRATION
float vibration=sin(iTime*60.)*.0013;
#else
float vibration=0.;
#endif
float det=0.0;
vec3 pth1;


mat2 rot(float a) {
return mat2(cos(a),sin(a),-sin(a),cos(a));
}


vec3 path(float ti) {
return vec3(sin(ti),.3-sin(ti*.632)*.3,cos(ti*.5))*.5;
}

float Sphere(vec3 p, vec3 rd, float r){//A RAY TRACED SPHERE
float b = dot( -p, rd );
float inner = b * b - dot( p, p ) + r * r;
if( inner < 0.0 ) return -1.0;
return b - sqrt( inner );
}

vec2 de(vec3 pos) {
float hid=0.;
vec3 tpos=pos;
tpos.xz=abs(.5-mod(tpos.xz,1.));
vec4 p=vec4(tpos,1.);
float y=max(0.,.35-abs(pos.y-3.35))/.35;
for (int i=0; i<7; i++) {//LOWERED THE ITERS
p.xyz = abs(p.xyz)-vec3(-0.02,1.98,-0.02);
p=p*(2.0+vibration*y)/clamp(dot(p.xyz,p.xyz),.4,1.)-vec4(0.5,1.,0.4,0.);
p.xz*=mat2(-0.416,-0.91,0.91,-0.416);
}
float fl=pos.y-3.013;
float fr=(length(max(abs(p.xyz)-vec3(0.1,5.0,0.1),vec3(0.0)))-0.05)/p.w;//RETURN A RRECT
//float fr=length(p.xyz)/p.w;
float d=min(fl,fr);
d=min(d,-pos.y+3.95);
if (abs(d-fl)<.001) hid=1.;
return vec2(d,hid);
}


vec3 normal(vec3 p) {
vec3 e = vec3(0.0,det,0.0);

return normalize(vec3(
de(p+e.yxx).x-de(p-e.yxx).x,
de(p+e.xyx).x-de(p-e.xyx).x,
de(p+e.xxy).x-de(p-e.xxy).x
)
);
}

float shadow(vec3 pos, vec3 sdir) {//THIS ONLY RUNS WHEN WITH HARD SHADOWS
float sh=1.0;
float totdist =2.0*det;
float dist=10.;
float t1=Sphere((pos-.005*sdir)-pth1,-sdir,0.015);
if (t1>0. && t1<.5) {
vec3 sphglowNorm=normalize(pos-t1*sdir-pth1);
sh=1.-pow(max(.0,dot(sphglowNorm,sdir))*1.2,3.);
}
for (int steps=0; steps<SHADOW_STEPS; steps++) {
if (totdist<.6 && dist>detail) {
vec3 p = pos - totdist * sdir;
dist = de(p).x;
sh = min( sh, max(50.*dist/totdist,0.0) );
totdist += max(.01,dist);
}
}

    return clamp(sh,0.1,1.0);
}


float calcAO( const vec3 pos, const vec3 nor ) {
float aodet=detail*40.;
float totao = 0.0;
    float sca = 14.0;
    for( int aoi=0; aoi<5; aoi++ ) {
        float hr = aodet*float(aoi*aoi);
        vec3 aopos =  nor * hr + pos;
        float dd = de( aopos ).x;
        totao += -(dd-hr)*sca;
        sca *= 0.7;
    }
    return clamp( 1.0 - 5.0*totao, 0., 1.0 );
}

float _texture(vec3 p) {
p=abs(.5-fract(p*10.));
vec3 c=vec3(3.);
float es, l=es=0.;
for (int i = 0; i < 10; i++) {
p = abs(p + c) - abs(p - c) - p;
p/= clamp(dot(p, p), .0, 1.);
p = p* -1.5 + c;
if ( mod(float(i), 2.) < 1. ) {
float pl = l;
l = length(p);
es+= exp(-1. / abs(l - pl));
}
}
return es;
}

vec3 light(in vec3 p, in vec3 dir, in vec3 n, in float hid) {//PASSING IN THE NORMAL
#ifdef ENABLE_HARD_SHADOWS
float sh=shadow(p, lightdir);
#else
float sh=calcAO(p,-2.5*lightdir);//USING AO TO MAKE VERY SOFT SHADOWS
#endif
float ao=calcAO(p,n);
float diff=max(0.,dot(lightdir,-n))*sh;
float y=3.35-p.y;
vec3 amb=max(.5,dot(dir,-n))*.5*AMBIENT_COLOR;
if (hid<.5) {
amb+=max(0.2,dot(vec3(0.,1.,0.),-n))*FLOOR_COLOR*pow(max(0.,.2-abs(3.-p.y))/.2,1.5)*2.;
amb+=energy*pow(max(0.,.4-abs(y))/.4,2.)*max(0.2,dot(vec3(0.,-sign(y),0.),-n))*2.;
}
vec3 r = reflect(lightdir,n);
float spec=pow(max(0.,dot(dir,-r))*sh,10.);
vec3 col;
float energysource=pow(max(0.,.04-abs(y))/.04,4.)*2.;
if (hid>1.5) {col=vec3(1.); spec=spec*spec;}
else{
float k=_texture(p)*.23+.2;
k=min(k,1.5-energysource);
col=mix(vec3(k,k*k,k*k*k),vec3(k),.3);
if (abs(hid-1.)<.001) col*=FLOOR_COLOR*1.3;
}
col=col*(amb+diff*LIGHT_COLOR)+spec*LIGHT_COLOR;
if (hid<.5) {
col=max(col,energy*2.*energysource);
}
col*=min(1.,ao+length(energy)*.5*max(0.,.1-abs(y))/.1);
return col;
}

vec3 raymarch(in vec3 from, in vec3 dir)

{
float ey=mod(t*.5,1.);
float glow,eglow,ref,sphdist,totdist=glow=eglow=ref=sphdist=0.;
vec2 d=vec2(1.,0.);
vec3 p, col=vec3(0.);
vec3 origdir=dir,origfrom=from,sphNorm;

//FAKING THE SQUISHY BALL BY MOVING A RAY TRACED BALL
vec3 wob=cos(dir*500.0*length(from-pth1)+(from-pth1)*250.+iTime*10.)*0.0005;
float t1=Sphere(from-pth1+wob,dir,0.015);
float tg=Sphere(from-pth1+wob,dir,0.02);
if(t1>0.){
ref=1.0;from+=t1*dir;sphdist=t1;
sphNorm=normalize(from-pth1+wob);
dir=reflect(dir,sphNorm);
}
else if (tg>0.) {
vec3 sphglowNorm=normalize(from+tg*dir-pth1+wob);
glow+=pow(max(0.,dot(sphglowNorm,-dir)),5.);
};

for (int i=0; i<RAY_STEPS; i++) {
if (d.x>det && totdist<3.0) {
p=from+totdist*dir;
d=de(p);
det=detail*(1.+totdist*60.)*(1.+ref*5.);
totdist+=d.x;
energy=ENERGY_COLOR*(1.5+sin(iTime*20.+p.z*10.))*.25;
if(d.x<0.015)glow+=max(0.,.015-d.x)*exp(-totdist);
if (d.y<.5 && d.x<0.03){//ONLY DOING THE GLOW WHEN IT IS CLOSE ENOUGH
float glw=min(abs(3.35-p.y-ey),abs(3.35-p.y+ey));//2 glows at once
eglow+=max(0.,.03-d.x)/.03*
(pow(max(0.,.05-glw)/.05,5.)
+pow(max(0.,.15-abs(3.35-p.y))/.15,8.))*1.5;
}
}
}
float l=pow(max(0.,dot(normalize(-dir.xz),normalize(lightdir.xz))),2.);
l*=max(0.2,dot(-dir,lightdir));
vec3 backg=.5*(1.2-l)+LIGHT_COLOR*l*.7;
backg*=AMBIENT_COLOR;
if (d.x<=det) {
vec3 norm=normal(p-abs(d.x-det)*dir);//DO THE NORMAL CALC OUTSIDE OF LIGHTING (since we already have the sphere normal)
col=light(p-abs(d.x-det)*dir, dir, norm, d.y)*exp(-.2*totdist*totdist);
col = mix(col, backg, 1.0-exp(-1.*pow(totdist,1.5)));
} else {
col=backg;
}
vec3 lglow=LIGHT_COLOR*pow(l,30.)*.5;
col+=glow*(backg+lglow)*1.3;
col+=pow(eglow,2.)*energy*.015;
col+=lglow*min(1.,totdist*totdist*.3);
if (ref>0.5) {
vec3 sphlight=light(origfrom+sphdist*origdir,origdir,sphNorm,2.);
col=mix(col*.3+sphlight*.7,backg,1.0-exp(-1.*pow(sphdist,1.5)));
}
return col;
}

vec3 move(inout mat2 rotview1,inout mat2 rotview2) {
vec3 go=path(t);
vec3 adv=path(t+.7);
vec3 advec=normalize(adv-go);
float an=atan(advec.x,advec.z);
rotview1=mat2(cos(an),sin(an),-sin(an),cos(an));
  an=advec.y*1.7;
rotview2=mat2(cos(an),sin(an),-sin(an),cos(an));
return go;
}


void main()
{
pth1 = path(t+.3)+origin+vec3(0.,.01,0.);
vec2 uv = gl_FragCoord.xy / iResolution.xy*2.-1.;
vec2 uv2=uv;
#ifdef ENABLE_POSTPROCESS
uv*=1.+pow(length(uv2*uv2*uv2*uv2),4.)*.07;
#endif
uv.y*=iResolution.y/iResolution.x;
vec2 mouse=(iMouse.xy/iResolution.xy-.5)*3.;
if (iMouse.z<1.) mouse=vec2(0.);
mat2 rotview1, rotview2;
vec3 from=origin+move(rotview1,rotview2);
vec3 dir=normalize(vec3(uv*.8,1.));
dir.yz*=rot(mouse.y);
dir.xz*=rot(mouse.x);
dir.yz*=rotview2;
dir.xz*=rotview1;
vec3 color=raymarch(from,dir);
color=clamp(color,vec3(.0),vec3(1.));
color=pow(color,vec3(GAMMA))*BRIGHTNESS;
color=mix(vec3(length(color)),color,SATURATION);
#ifdef ENABLE_POSTPROCESS
vec3 rain=pow(texture(BWNoiseBig_png,uv2+iTime*7.25468).rgb,vec3(1.5));
color=mix(rain,color,clamp(iTime*.5-.5,0.,1.));
color*=1.-pow(length(uv2*uv2*uv2*uv2)*1.1,6.);
uv2.y *= iResolution.y / 360.0;
color.r*=(.5+abs(.5-mod(uv2.y     ,.021)/.021)*.5)*1.5;
color.g*=(.5+abs(.5-mod(uv2.y+.007,.021)/.021)*.5)*1.5;
color.b*=(.5+abs(.5-mod(uv2.y+.014,.021)/.021)*.5)*1.5;
color*=.9+rain*.35;
#endif
gl_FragColor = vec4(color,1.);
}

Simplicity_Galaxy.fs
Code: [Select]
// Created by Reinder Nijhoff 2014
// Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
// @reindernijhoff
//
// https://www.shadertoy.com/view/Xtf3zn
//
// car model is made by Eiffie
// shader 'Shiny Toy': https://www.shadertoy.com/view/ldsGWB

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

#define BUMPMAP
#define MARCHSTEPS 128
#define MARCHSTEPSREFLECTION 48
#define LIGHTINTENSITY 5.

//----------------------------------------------------------------------

const vec3 backgroundColor = vec3(0.2,0.4,0.6) * 0.09;
#define time (iTime + 90.)

//----------------------------------------------------------------------
// noises

float hash( float n ) {
    return fract(sin(n)*687.3123);
}

float noise( in vec2 x ) {
    vec2 p = floor(x);
    vec2 f = fract(x);
    f = f*f*(3.0-2.0*f);
    float n = p.x + p.y*157.0;
    return mix(mix( hash(n+  0.0), hash(n+  1.0),f.x),
               mix( hash(n+157.0), hash(n+158.0),f.x),f.y);
}

const mat2 m2 = mat2( 0.80, -0.60, 0.60, 0.80 );

float fbm( vec2 p ) {
    float f = 0.0;
    f += 0.5000*noise( p ); p = m2*p*2.02;
    f += 0.2500*noise( p ); p = m2*p*2.03;
    f += 0.1250*noise( p ); p = m2*p*2.01;
//    f += 0.0625*noise( p );
   
    return f/0.9375;
}

//----------------------------------------------------------------------
// distance primitives

float udRoundBox( vec3 p, vec3 b, float r ) {
  return length(max(abs(p)-b,0.0))-r;
}

float sdBox( in vec3 p, in vec3 b ) {
    vec3 d = abs(p) - b;
    return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}

float sdSphere( in vec3 p, in float s ) {
    return length(p)-s;
}

float sdCylinder( in vec3 p, in vec2 h ) {
    vec2 d = abs(vec2(length(p.xz),p.y)) - h;
    return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}

//----------------------------------------------------------------------
// distance operators

float opU( float d2, float d1 ) { return min( d1,d2); }
float opS( float d2, float d1 ) { return max(-d1,d2); }
float smin( float a, float b, float k ) { return -log(exp(-k*a)+exp(-k*b))/k; } //from iq

//----------------------------------------------------------------------
// Map functions

// car model is made by Eiffie
// shader 'Shiny Toy': https://www.shadertoy.com/view/ldsGWB

float mapCar(in vec3 p0){
vec3 p=p0+vec3(0.0,1.24,0.0);
float r=length(p.yz);
float d= length(max(vec3(abs(p.x)-0.35,r-1.92,-p.y+1.4),0.0))-0.05;
d=max(d,p.z-1.0);
p=p0+vec3(0.0,-0.22,0.39);
p.xz=abs(p.xz)-vec2(0.5300,0.9600);p.x=abs(p.x);
r=length(p.yz);
d=smin(d,length(max(vec3(p.x-0.08,r-0.25,-p.y-0.08),0.0))-0.04,8.0);
d=max(d,-max(p.x-0.165,r-0.24));
float d2=length(vec2(max(p.x-0.13,0.0),r-0.2))-0.02;
d=min(d,d2);

return d;
}

float dL; // minimal distance to light

float map( const in vec3 p ) {
vec3 pd = p;
    float d;
   
    pd.x = abs( pd.x );
    pd.z *= -sign( p.x );
   
    float ch = hash( floor( (pd.z+18.*time)/40. ) );
    float lh = hash( floor( pd.z/13. ) );
   
    vec3 pdm = vec3( pd.x, pd.y, mod( pd.z, 10.) - 5. );
    dL = sdSphere( vec3(pdm.x-8.1,pdm.y-4.5,pdm.z), 0.1 );
   
    dL = opU( dL, sdBox( vec3(pdm.x-12., pdm.y-9.5-lh,  mod( pd.z, 91.) - 45.5 ), vec3(0.2,4.5, 0.2) ) );
    dL = opU( dL, sdBox( vec3(pdm.x-12., pdm.y-11.5+lh, mod( pd.z, 31.) - 15.5 ), vec3(0.22,5.5, 0.2) ) );
    dL = opU( dL, sdBox( vec3(pdm.x-12., pdm.y-8.5-lh,  mod( pd.z, 41.) - 20.5 ), vec3(0.24,3.5, 0.2) ) );
   
    if( lh > 0.5 ) {
    dL = opU( dL, sdBox( vec3(pdm.x-12.5,pdm.y-2.75-lh,  mod( pd.z, 13.) - 6.5 ), vec3(0.1,0.25, 3.2) ) );
    }
   
    vec3 pm = vec3( mod( pd.x + floor( pd.z * 4. )*0.25, 0.5 ) - 0.25, pd.y, mod( pd.z, 0.25 ) - 0.125 );
d = udRoundBox( pm, vec3( 0.245,0.1, 0.12 ), 0.005 );
   
    d = opS( d, -(p.x+8.) );
    d = opU( d, pd.y );

    vec3 pdc = vec3( pd.x, pd.y, mod( pd.z+18.*time, 40.) - 20. );
   
    // car
    if( ch > 0.75 ) {
        pdc.x += (ch-0.75)*4.;
    dL = opU( dL, sdSphere( vec3( abs(pdc.x-5.)-1.05, pdc.y-0.55, pdc.z ),    0.025 ) );
    dL = opU( dL, sdSphere( vec3( abs(pdc.x-5.)-1.2,  pdc.y-0.65,  pdc.z+6.05 ), 0.025 ) );

        d = opU( d,  mapCar( (pdc-vec3(5.,-0.025,-2.3))*0.45 ) );
  }
   
    d = opU( d, 13.-pd.x );
    d = opU( d, sdCylinder( vec3(pdm.x-8.5, pdm.y, pdm.z), vec2(0.075,4.5)) );
    d = opU( d, dL );
   
return d;
}

//----------------------------------------------------------------------

vec3 calcNormalSimple( in vec3 pos ) {   
    const vec2 e = vec2(1.0,-1.0)*0.005;

    vec3 n = normalize( e.xyy*map( pos + e.xyy ) +
    e.yyx*map( pos + e.yyx )   +
    e.yxy*map( pos + e.yxy )   +
    e.xxx*map( pos + e.xxx )   ); 
    return n;
}

vec3 calcNormal( in vec3 pos ) {
    vec3 n = calcNormalSimple( pos );
    if( pos.y > 0.12 ) return n;

#ifdef BUMPMAP
    vec2 oc = floor( vec2(pos.x+floor( pos.z * 4. )*0.25, pos.z) * vec2( 2., 4. ) );

    if( abs(pos.x)<8. ) {
oc = pos.xz;
    }
   
     vec3 p = pos * 250.;
    vec3 xn = 0.05*vec3(noise(p.xz)-0.5,0.,noise(p.zx)-0.5);
     xn += 0.1*vec3(fbm(oc.xy)-0.5,0.,fbm(oc.yx)-0.5);
   
    n = normalize( xn + n );
#endif
   
    return n;
}

vec3 int1, int2, nor1;
vec4 lint1, lint2;

float intersect( in vec3 ro, in vec3 rd ) {
const float precis = 0.001;
    float h = precis*2.0;
    float t = 0.;
    int1 = int2 = vec3( -500. );
    lint1 = lint2 = vec4( -500. );
    float mld = 100.;
   
for( int i=0; i < MARCHSTEPS; i++ ) {
        h = map( ro+rd*t );
if(dL < mld){
mld=dL;
            lint1.xyz = ro+rd*t;
lint1.w = abs(dL);
}
        if( h < precis ) {
            int1.xyz = ro+rd*t;
            break;
        }
        t += max(h, precis*2.);
    }
   
    if( int1.z < -400. || t > 300.) {
        // check intersection with plane y = -0.1;
        float d = -(ro.y + 0.1)/rd.y;
if( d > 0. ) {
int1.xyz = ro+rd*d;
    } else {
        return -1.;
    }
    }
   
    ro = ro + rd*t;
    nor1 = calcNormal(ro);
    ro += 0.01*nor1;
    rd = reflect( rd, nor1 );
    t = 0.0;
    h = precis*2.0;
    mld = 100.;
   
    for( int i=0; i < MARCHSTEPSREFLECTION; i++ ) {
        h = map( ro+rd*t );
if(dL < mld){
mld=dL;           
            lint2.xyz = ro+rd*t;
lint2.w = abs(dL);
}
        if( h < precis ) {
    int2.xyz = ro+rd*t;
            return 1.;
        }   
        t += max(h, precis*2.);
    }

    return 0.;
}

//----------------------------------------------------------------------
// shade

vec3 shade( in vec3 ro, in vec3 pos, in vec3 nor ) {
    vec3  col = vec3(0.5);
   
    if( abs(pos.x) > 15. || abs(pos.x) < 8. ) col = vec3( 0.02 );
    if( pos.y < 0.01 ) {
        if( abs( int1.x ) < 0.1 ) col = vec3( 0.9 );
        if( abs( abs( int1.x )-7.4 ) < 0.1 ) col = vec3( 0.9 );
    }   
   
    float sh = clamp( dot( nor, normalize( vec3( -0.3, 0.3, -0.5 ) ) ), 0., 1.);
  col *= (sh * backgroundColor); 
 
    if( abs( pos.x ) > 12.9 && pos.y > 9.) { // windows
        float ha = hash(  133.1234*floor( pos.y / 3. ) + floor( (pos.z) / 3. ) );
        if( ha > 0.95) {
            col = ( (ha-0.95)*10.) * vec3( 1., 0.7, 0.4 );
        }
    }
   
col = mix(  backgroundColor, col, exp( min(max(0.1*pos.y,0.25)-0.065*distance(pos, ro),0.) ) );
 
    return col;
}

vec3 getLightColor( in vec3 pos ) {
    vec3 lcol = vec3( 1., .7, .5 );
   
vec3 pd = pos;
    pd.x = abs( pd.x );
    pd.z *= -sign( pos.x );
   
    float ch = hash( floor( (pd.z+18.*time)/40. ) );
    vec3 pdc = vec3( pd.x, pd.y, mod( pd.z+18.*time, 40.) - 20. );

    if( ch > 0.75 ) { // car
        pdc.x += (ch-0.75)*4.;
        if(  sdSphere( vec3( abs(pdc.x-5.)-1.05, pdc.y-0.55, pdc.z ), 0.25) < 2. ) {
            lcol = vec3( 1., 0.05, 0.01 );
        }
    }
    if( pd.y > 2. && abs(pd.x) > 10. && pd.y < 5. ) {
        float fl = floor( pd.z/13. );
        lcol = 0.4*lcol+0.5*vec3( hash( .1562+fl ), hash( .423134+fl ), 0. );
    }
    if(  abs(pd.x) > 10. && pd.y > 5. ) {
        float fl = floor( pd.z/2. );
        lcol = 0.5*lcol+0.5*vec3( hash( .1562+fl ),  hash( .923134+fl ), hash( .423134+fl ) );
    }
   
    return lcol;
}

float randomStart(vec2 co){return 0.8+0.2*hash(dot(co,vec2(123.42,117.853))*412.453);}

//----------------------------------------------------------------------
// main

void main() {   
    vec2 q = gl_FragCoord.xy / iResolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= iResolution.x / iResolution.y;
       
    if (q.y < .12 || q.y >= .88) {
gl_FragColor=vec4(0.,0.,0.,1.);
return;
    } else {
   
        // camera
        float z = time;
        float x = -10.9+1.*sin(time*0.2);
        vec3 ro = vec3(x,  1.3+.3*cos(time*0.26), z-1.);
        vec3 ta = vec3(-8.,1.3+.4*cos(time*0.26), z+4.+cos(time*0.04));

        vec3 ww = normalize( ta - ro );
        vec3 uu = normalize( cross(ww,vec3(0.0,1.0,0.0) ) );
        vec3 vv = normalize( cross(uu,ww));
        vec3 rd = normalize( -p.x*uu + p.y*vv + 2.2*ww );

        vec3 col = backgroundColor;

        // raymarch
        float ints = intersect(ro+randomStart(p)*rd ,rd );
        if(  ints > -0.5 ) {

            // calculate reflectance
            float r = 0.09;             
            if( int1.y > 0.129 ) r = 0.025 * hash(  133.1234*floor( int1.y / 3. ) + floor( int1.z / 3. ) );
            if( abs(int1.x) < 8. ) {
                if( int1.y < 0.01 ) { // road
                    r = 0.007*fbm(int1.xz);
                } else { // car
                    r = 0.02;
                }
            }
            if( abs( int1.x ) < 0.1 ) r *= 4.;
            if( abs( abs( int1.x )-7.4 ) < 0.1 ) r *= 4.;

            r *= 2.;

            col = shade( ro, int1.xyz, nor1 );

            if( ints > 0.5 ) {
                col += r * shade( int1.xyz, int2.xyz, calcNormalSimple(int2.xyz) );
            } 
            if( lint2.w > 0. ) {           
                col += (r*LIGHTINTENSITY*exp(-lint2.w*7.0)) * getLightColor(lint2.xyz);
            }
        }

        // Rain (by Dave Hoskins)
        vec2 st = 256. * ( p* vec2(.5, .01)+vec2(time*.13-q.y*.6, time*.13) );
        float f = noise( st ) * noise( st*0.773) * 1.55;
        f = 0.25+ clamp(pow(abs(f), 13.0) * 13.0, 0.0, q.y*.14);

        if( lint1.w > 0. ) {
            col += (f*LIGHTINTENSITY*exp(-lint1.w*7.0)) * getLightColor(lint1.xyz);
        } 

        col += 0.25*f*(0.2+backgroundColor);

        // post processing
        col = pow( clamp(col,0.0,1.0), vec3(0.4545) );
        col *= 1.2*vec3(1.,0.99,0.95);   
        col = clamp(1.06*col-0.03, 0., 1.); 
        q.y = (q.y-.12)*(1./0.76);
        col *= 0.5 + 0.5*pow( 16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y), 0.1 );

        gl_FragColor = vec4( col, 1.0 );
    }
}

Tokyo.fs
Code: [Select]
// Created by Reinder Nijhoff 2014
// Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
// @reindernijhoff
//
// https://www.shadertoy.com/view/Xtf3zn
//
// car model is made by Eiffie
// shader 'Shiny Toy': https://www.shadertoy.com/view/ldsGWB

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

#define BUMPMAP
#define MARCHSTEPS 128
#define MARCHSTEPSREFLECTION 48
#define LIGHTINTENSITY 5.

//----------------------------------------------------------------------

const vec3 backgroundColor = vec3(0.2,0.4,0.6) * 0.09;
#define time (iTime + 90.)

//----------------------------------------------------------------------
// noises

float hash( float n ) {
    return fract(sin(n)*687.3123);
}

float noise( in vec2 x ) {
    vec2 p = floor(x);
    vec2 f = fract(x);
    f = f*f*(3.0-2.0*f);
    float n = p.x + p.y*157.0;
    return mix(mix( hash(n+  0.0), hash(n+  1.0),f.x),
               mix( hash(n+157.0), hash(n+158.0),f.x),f.y);
}

const mat2 m2 = mat2( 0.80, -0.60, 0.60, 0.80 );

float fbm( vec2 p ) {
    float f = 0.0;
    f += 0.5000*noise( p ); p = m2*p*2.02;
    f += 0.2500*noise( p ); p = m2*p*2.03;
    f += 0.1250*noise( p ); p = m2*p*2.01;
//    f += 0.0625*noise( p );
   
    return f/0.9375;
}

//----------------------------------------------------------------------
// distance primitives

float udRoundBox( vec3 p, vec3 b, float r ) {
  return length(max(abs(p)-b,0.0))-r;
}

float sdBox( in vec3 p, in vec3 b ) {
    vec3 d = abs(p) - b;
    return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}

float sdSphere( in vec3 p, in float s ) {
    return length(p)-s;
}

float sdCylinder( in vec3 p, in vec2 h ) {
    vec2 d = abs(vec2(length(p.xz),p.y)) - h;
    return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}

//----------------------------------------------------------------------
// distance operators

float opU( float d2, float d1 ) { return min( d1,d2); }
float opS( float d2, float d1 ) { return max(-d1,d2); }
float smin( float a, float b, float k ) { return -log(exp(-k*a)+exp(-k*b))/k; } //from iq

//----------------------------------------------------------------------
// Map functions

// car model is made by Eiffie
// shader 'Shiny Toy': https://www.shadertoy.com/view/ldsGWB

float mapCar(in vec3 p0){
vec3 p=p0+vec3(0.0,1.24,0.0);
float r=length(p.yz);
float d= length(max(vec3(abs(p.x)-0.35,r-1.92,-p.y+1.4),0.0))-0.05;
d=max(d,p.z-1.0);
p=p0+vec3(0.0,-0.22,0.39);
p.xz=abs(p.xz)-vec2(0.5300,0.9600);p.x=abs(p.x);
r=length(p.yz);
d=smin(d,length(max(vec3(p.x-0.08,r-0.25,-p.y-0.08),0.0))-0.04,8.0);
d=max(d,-max(p.x-0.165,r-0.24));
float d2=length(vec2(max(p.x-0.13,0.0),r-0.2))-0.02;
d=min(d,d2);

return d;
}

float dL; // minimal distance to light

float map( const in vec3 p ) {
vec3 pd = p;
    float d;
   
    pd.x = abs( pd.x );
    pd.z *= -sign( p.x );
   
    float ch = hash( floor( (pd.z+18.*time)/40. ) );
    float lh = hash( floor( pd.z/13. ) );
   
    vec3 pdm = vec3( pd.x, pd.y, mod( pd.z, 10.) - 5. );
    dL = sdSphere( vec3(pdm.x-8.1,pdm.y-4.5,pdm.z), 0.1 );
   
    dL = opU( dL, sdBox( vec3(pdm.x-12., pdm.y-9.5-lh,  mod( pd.z, 91.) - 45.5 ), vec3(0.2,4.5, 0.2) ) );
    dL = opU( dL, sdBox( vec3(pdm.x-12., pdm.y-11.5+lh, mod( pd.z, 31.) - 15.5 ), vec3(0.22,5.5, 0.2) ) );
    dL = opU( dL, sdBox( vec3(pdm.x-12., pdm.y-8.5-lh,  mod( pd.z, 41.) - 20.5 ), vec3(0.24,3.5, 0.2) ) );
   
    if( lh > 0.5 ) {
    dL = opU( dL, sdBox( vec3(pdm.x-12.5,pdm.y-2.75-lh,  mod( pd.z, 13.) - 6.5 ), vec3(0.1,0.25, 3.2) ) );
    }
   
    vec3 pm = vec3( mod( pd.x + floor( pd.z * 4. )*0.25, 0.5 ) - 0.25, pd.y, mod( pd.z, 0.25 ) - 0.125 );
d = udRoundBox( pm, vec3( 0.245,0.1, 0.12 ), 0.005 );
   
    d = opS( d, -(p.x+8.) );
    d = opU( d, pd.y );

    vec3 pdc = vec3( pd.x, pd.y, mod( pd.z+18.*time, 40.) - 20. );
   
    // car
    if( ch > 0.75 ) {
        pdc.x += (ch-0.75)*4.;
    dL = opU( dL, sdSphere( vec3( abs(pdc.x-5.)-1.05, pdc.y-0.55, pdc.z ),    0.025 ) );
    dL = opU( dL, sdSphere( vec3( abs(pdc.x-5.)-1.2,  pdc.y-0.65,  pdc.z+6.05 ), 0.025 ) );

        d = opU( d,  mapCar( (pdc-vec3(5.,-0.025,-2.3))*0.45 ) );
  }
   
    d = opU( d, 13.-pd.x );
    d = opU( d, sdCylinder( vec3(pdm.x-8.5, pdm.y, pdm.z), vec2(0.075,4.5)) );
    d = opU( d, dL );
   
return d;
}

//----------------------------------------------------------------------

vec3 calcNormalSimple( in vec3 pos ) {   
    const vec2 e = vec2(1.0,-1.0)*0.005;

    vec3 n = normalize( e.xyy*map( pos + e.xyy ) +
    e.yyx*map( pos + e.yyx )   +
    e.yxy*map( pos + e.yxy )   +
    e.xxx*map( pos + e.xxx )   ); 
    return n;
}

vec3 calcNormal( in vec3 pos ) {
    vec3 n = calcNormalSimple( pos );
    if( pos.y > 0.12 ) return n;

#ifdef BUMPMAP
    vec2 oc = floor( vec2(pos.x+floor( pos.z * 4. )*0.25, pos.z) * vec2( 2., 4. ) );

    if( abs(pos.x)<8. ) {
oc = pos.xz;
    }
   
     vec3 p = pos * 250.;
    vec3 xn = 0.05*vec3(noise(p.xz)-0.5,0.,noise(p.zx)-0.5);
     xn += 0.1*vec3(fbm(oc.xy)-0.5,0.,fbm(oc.yx)-0.5);
   
    n = normalize( xn + n );
#endif
   
    return n;
}

vec3 int1, int2, nor1;
vec4 lint1, lint2;

float intersect( in vec3 ro, in vec3 rd ) {
const float precis = 0.001;
    float h = precis*2.0;
    float t = 0.;
    int1 = int2 = vec3( -500. );
    lint1 = lint2 = vec4( -500. );
    float mld = 100.;
   
for( int i=0; i < MARCHSTEPS; i++ ) {
        h = map( ro+rd*t );
if(dL < mld){
mld=dL;
            lint1.xyz = ro+rd*t;
lint1.w = abs(dL);
}
        if( h < precis ) {
            int1.xyz = ro+rd*t;
            break;
        }
        t += max(h, precis*2.);
    }
   
    if( int1.z < -400. || t > 300.) {
        // check intersection with plane y = -0.1;
        float d = -(ro.y + 0.1)/rd.y;
if( d > 0. ) {
int1.xyz = ro+rd*d;
    } else {
        return -1.;
    }
    }
   
    ro = ro + rd*t;
    nor1 = calcNormal(ro);
    ro += 0.01*nor1;
    rd = reflect( rd, nor1 );
    t = 0.0;
    h = precis*2.0;
    mld = 100.;
   
    for( int i=0; i < MARCHSTEPSREFLECTION; i++ ) {
        h = map( ro+rd*t );
if(dL < mld){
mld=dL;           
            lint2.xyz = ro+rd*t;
lint2.w = abs(dL);
}
        if( h < precis ) {
    int2.xyz = ro+rd*t;
            return 1.;
        }   
        t += max(h, precis*2.);
    }

    return 0.;
}

//----------------------------------------------------------------------
// shade

vec3 shade( in vec3 ro, in vec3 pos, in vec3 nor ) {
    vec3  col = vec3(0.5);
   
    if( abs(pos.x) > 15. || abs(pos.x) < 8. ) col = vec3( 0.02 );
    if( pos.y < 0.01 ) {
        if( abs( int1.x ) < 0.1 ) col = vec3( 0.9 );
        if( abs( abs( int1.x )-7.4 ) < 0.1 ) col = vec3( 0.9 );
    }   
   
    float sh = clamp( dot( nor, normalize( vec3( -0.3, 0.3, -0.5 ) ) ), 0., 1.);
  col *= (sh * backgroundColor); 
 
    if( abs( pos.x ) > 12.9 && pos.y > 9.) { // windows
        float ha = hash(  133.1234*floor( pos.y / 3. ) + floor( (pos.z) / 3. ) );
        if( ha > 0.95) {
            col = ( (ha-0.95)*10.) * vec3( 1., 0.7, 0.4 );
        }
    }
   
col = mix(  backgroundColor, col, exp( min(max(0.1*pos.y,0.25)-0.065*distance(pos, ro),0.) ) );
 
    return col;
}

vec3 getLightColor( in vec3 pos ) {
    vec3 lcol = vec3( 1., .7, .5 );
   
vec3 pd = pos;
    pd.x = abs( pd.x );
    pd.z *= -sign( pos.x );
   
    float ch = hash( floor( (pd.z+18.*time)/40. ) );
    vec3 pdc = vec3( pd.x, pd.y, mod( pd.z+18.*time, 40.) - 20. );

    if( ch > 0.75 ) { // car
        pdc.x += (ch-0.75)*4.;
        if(  sdSphere( vec3( abs(pdc.x-5.)-1.05, pdc.y-0.55, pdc.z ), 0.25) < 2. ) {
            lcol = vec3( 1., 0.05, 0.01 );
        }
    }
    if( pd.y > 2. && abs(pd.x) > 10. && pd.y < 5. ) {
        float fl = floor( pd.z/13. );
        lcol = 0.4*lcol+0.5*vec3( hash( .1562+fl ), hash( .423134+fl ), 0. );
    }
    if(  abs(pd.x) > 10. && pd.y > 5. ) {
        float fl = floor( pd.z/2. );
        lcol = 0.5*lcol+0.5*vec3( hash( .1562+fl ),  hash( .923134+fl ), hash( .423134+fl ) );
    }
   
    return lcol;
}

float randomStart(vec2 co){return 0.8+0.2*hash(dot(co,vec2(123.42,117.853))*412.453);}

//----------------------------------------------------------------------
// main

void main() {   
    vec2 q = gl_FragCoord.xy / iResolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= iResolution.x / iResolution.y;
       
    if (q.y < .12 || q.y >= .88) {
gl_FragColor=vec4(0.,0.,0.,1.);
return;
    } else {
   
        // camera
        float z = time;
        float x = -10.9+1.*sin(time*0.2);
        vec3 ro = vec3(x,  1.3+.3*cos(time*0.26), z-1.);
        vec3 ta = vec3(-8.,1.3+.4*cos(time*0.26), z+4.+cos(time*0.04));

        vec3 ww = normalize( ta - ro );
        vec3 uu = normalize( cross(ww,vec3(0.0,1.0,0.0) ) );
        vec3 vv = normalize( cross(uu,ww));
        vec3 rd = normalize( -p.x*uu + p.y*vv + 2.2*ww );

        vec3 col = backgroundColor;

        // raymarch
        float ints = intersect(ro+randomStart(p)*rd ,rd );
        if(  ints > -0.5 ) {

            // calculate reflectance
            float r = 0.09;             
            if( int1.y > 0.129 ) r = 0.025 * hash(  133.1234*floor( int1.y / 3. ) + floor( int1.z / 3. ) );
            if( abs(int1.x) < 8. ) {
                if( int1.y < 0.01 ) { // road
                    r = 0.007*fbm(int1.xz);
                } else { // car
                    r = 0.02;
                }
            }
            if( abs( int1.x ) < 0.1 ) r *= 4.;
            if( abs( abs( int1.x )-7.4 ) < 0.1 ) r *= 4.;

            r *= 2.;

            col = shade( ro, int1.xyz, nor1 );

            if( ints > 0.5 ) {
                col += r * shade( int1.xyz, int2.xyz, calcNormalSimple(int2.xyz) );
            } 
            if( lint2.w > 0. ) {           
                col += (r*LIGHTINTENSITY*exp(-lint2.w*7.0)) * getLightColor(lint2.xyz);
            }
        }

        // Rain (by Dave Hoskins)
        vec2 st = 256. * ( p* vec2(.5, .01)+vec2(time*.13-q.y*.6, time*.13) );
        float f = noise( st ) * noise( st*0.773) * 1.55;
        f = 0.25+ clamp(pow(abs(f), 13.0) * 13.0, 0.0, q.y*.14);

        if( lint1.w > 0. ) {
            col += (f*LIGHTINTENSITY*exp(-lint1.w*7.0)) * getLightColor(lint1.xyz);
        } 

        col += 0.25*f*(0.2+backgroundColor);

        // post processing
        col = pow( clamp(col,0.0,1.0), vec3(0.4545) );
        col *= 1.2*vec3(1.,0.99,0.95);   
        col = clamp(1.06*col-0.03, 0., 1.); 
        q.y = (q.y-.12)*(1./0.76);
        col *= 0.5 + 0.5*pow( 16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y), 0.1 );

        gl_FragColor = vec4( col, 1.0 );
    }
}
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 05:20:07 pm
Thank you, Patrice!

The shaders are beautiful. It's a pity though that you sent me another Tokyo instead of SimplicityGalaxy. ;)

P.S. Have you noticed that cars in that Tokyo are driving on the wrong side of the road? ;) (traffic in Japan is left-sided British-style)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 07:25:07 pm
Here is
Simplicity_Galaxy.fs

Code: [Select]
//CBS
//Parallax scrolling fractal galaxy.
//Inspired by JoshP's Simplicity shader: https://www.shadertoy.com/view/lslGWr

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

uniform sampler2D BWNoise_png;

// http://www.fractalforums.com/new-theories-and-research/very-simple-formula-for-fractal-patterns/
float field(in vec3 p,float s) {
float strength = 7. + .03 * log(1.e-6 + fract(sin(iTime) * 4373.11));
float accum = s/4.;
float prev = 0.;
float tw = 0.;
for (int i = 0; i < 26; ++i) {
float mag = dot(p, p);
p = abs(p) / mag + vec3(-.5, -.4, -1.5);
float w = exp(-float(i) / 7.);
accum += w * exp(-strength * pow(abs(mag - prev), 2.2));
tw += w;
prev = mag;
}
return max(0., 5. * accum / tw - .7);
}

// Less iterations for second layer
float field2(in vec3 p, float s) {
float strength = 7. + .03 * log(1.e-6 + fract(sin(iTime) * 4373.11));
float accum = s/4.;
float prev = 0.;
float tw = 0.;
for (int i = 0; i < 18; ++i) {
float mag = dot(p, p);
p = abs(p) / mag + vec3(-.5, -.4, -1.5);
float w = exp(-float(i) / 7.);
accum += w * exp(-strength * pow(abs(mag - prev), 2.2));
tw += w;
prev = mag;
}
return max(0., 5. * accum / tw - .7);
}

vec3 nrand3( vec2 co )
{
vec3 a = fract( cos( co.x*8.3e-3 + co.y )*vec3(1.3e5, 4.7e5, 2.9e5) );
vec3 b = fract( sin( co.x*0.3e-3 + co.y )*vec3(8.1e5, 1.0e5, 0.1e5) );
vec3 c = mix(a, b, 0.5);
return c;
}


void main() {
    vec2 uv = 2. * gl_FragCoord.xy / iResolution.xy - 1.;
vec2 uvs = uv * iResolution.xy / max(iResolution.x, iResolution.y);
vec3 p = vec3(uvs / 4., 0) + vec3(1., -1.3, 0.);
p += .2 * vec3(sin(iTime / 16.), sin(iTime / 12.),  sin(iTime / 128.));

float freqs[4];
//Sound
freqs[0] = texture( BWNoise_png, vec2( 0.01, 0.25 ) ).x;
freqs[1] = texture( BWNoise_png, vec2( 0.07, 0.25 ) ).x;
freqs[2] = texture( BWNoise_png, vec2( 0.15, 0.25 ) ).x;
freqs[3] = texture( BWNoise_png, vec2( 0.30, 0.25 ) ).x;

float t = field(p,freqs[2]);
float v = (1. - exp((abs(uv.x) - 1.) * 6.)) * (1. - exp((abs(uv.y) - 1.) * 6.));

    //Second Layer
vec3 p2 = vec3(uvs / (4.+sin(iTime*0.11)*0.2+0.2+sin(iTime*0.15)*0.3+0.4), 1.5) + vec3(2., -1.3, -1.);
p2 += 0.25 * vec3(sin(iTime / 16.), sin(iTime / 12.),  sin(iTime / 128.));
float t2 = field2(p2,freqs[3]);
vec4 c2 = mix(.4, 1., v) * vec4(1.3 * t2 * t2 * t2 ,1.8  * t2 * t2 , t2* freqs[0], t2);


//Let's add some stars
//Thanks to http://glsl.heroku.com/e#6904.0
vec2 seed = p.xy * 2.0;
seed = floor(seed * iResolution.x);
vec3 rnd = nrand3( seed );
vec4 starcolor = vec4(pow(rnd.y,40.0));

//Second Layer
vec2 seed2 = p2.xy * 2.0;
seed2 = floor(seed2 * iResolution.x);
vec3 rnd2 = nrand3( seed2 );
starcolor += vec4(pow(rnd2.y,40.0));

gl_FragColor = mix(freqs[3]-.3, 1., v) * vec4(1.5*freqs[2] * t * t* t , 1.2*freqs[1] * t * t, freqs[3]*t, 1.0)+c2+starcolor;
}

Galaxy_Trips.fs
Code: [Select]
//////////////////////////////////////////////////
// Xavier Benech
// Galaxy Trip
// Inspired by "Star Tunnel" shader from P_Malin
// https://www.shadertoy.com/view/MdlXWr
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
//

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

// Increase pass count for a denser effect
#define PASS_COUNT 4

float fBrightness = 2.5;

// Number of angular segments
float fSteps = 121.0;

float fParticleSize = 0.015;
float fParticleLength = 0.5 / 60.0;

// Min and Max star position radius. Min must be present to prevent stars too near camera
float fMinDist = 0.8;
float fMaxDist = 5.0;

float fRepeatMin = 1.0;
float fRepeatMax = 2.0;

// fog density
float fDepthFade = 0.8;

float Random(float x)
{
return fract(sin(x * 123.456) * 23.4567 + sin(x * 345.678) * 45.6789 + sin(x * 456.789) * 56.789);
}

vec3 GetParticleColour( const in vec3 vParticlePos, const in float fParticleSize, const in vec3 vRayDir )
{
vec2 vNormDir = normalize(vRayDir.xy);
float d1 = dot(vParticlePos.xy, vNormDir.xy) / length(vRayDir.xy);
vec3 vClosest2d = vRayDir * d1;

vec3 vClampedPos = vParticlePos;

vClampedPos.z = clamp(vClosest2d.z, vParticlePos.z - fParticleLength, vParticlePos.z + fParticleLength);

float d = dot(vClampedPos, vRayDir);

vec3 vClosestPos = vRayDir * d;

vec3 vDeltaPos = vClampedPos - vClosestPos;

float fClosestDist = length(vDeltaPos) / fParticleSize;
float fShade = clamp(1.0 - fClosestDist, 0.0, 1.0);

if (d<3.0)
{
fClosestDist = max(abs(vDeltaPos.x),abs(vDeltaPos.y)) / fParticleSize;
float f = clamp(1.0 - 0.8*fClosestDist, 0.0, 1.0);
fShade += f*f*f*f;
fShade *= fShade;
}

fShade = fShade * exp2(-d * fDepthFade) * fBrightness;
return vec3(fShade);
}

vec3 GetParticlePos( const in vec3 vRayDir, const in float fZPos, const in float fSeed )
{
float fAngle = atan(vRayDir.x, vRayDir.y);
float fAngleFraction = fract(fAngle / (3.14 * 2.0));

float fSegment = floor(fAngleFraction * fSteps + fSeed) + 0.5 - fSeed;
float fParticleAngle = fSegment / fSteps * (3.14 * 2.0);

float fSegmentPos = fSegment / fSteps;
float fRadius = fMinDist + Random(fSegmentPos + fSeed) * (fMaxDist - fMinDist);

float tunnelZ = vRayDir.z / length(vRayDir.xy / fRadius);

tunnelZ += fZPos;

float fRepeat = fRepeatMin + Random(fSegmentPos + 0.1 + fSeed) * (fRepeatMax - fRepeatMin);

float fParticleZ = (ceil(tunnelZ / fRepeat) - 0.5) * fRepeat - fZPos;

return vec3( sin(fParticleAngle) * fRadius, cos(fParticleAngle) * fRadius, fParticleZ );
}

vec3 Starfield( const in vec3 vRayDir, const in float fZPos, const in float fSeed )
{
vec3 vParticlePos = GetParticlePos(vRayDir, fZPos, fSeed);

return GetParticleColour(vParticlePos, fParticleSize, vRayDir);
}

vec3 RotateX( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle); float c = cos(fAngle);
    return vec3( vPos.x, c * vPos.y + s * vPos.z, -s * vPos.y + c * vPos.z);
}

vec3 RotateY( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle); float c = cos(fAngle);
    return vec3( c * vPos.x + s * vPos.z, vPos.y, -s * vPos.x + c * vPos.z);
}

vec3 RotateZ( const in vec3 vPos, const in float fAngle )
{
    float s = sin(fAngle); float c = cos(fAngle);
    return vec3( c * vPos.x + s * vPos.y, -s * vPos.x + c * vPos.y, vPos.z);
}

// Simplex Noise by IQ
vec2 hash( vec2 p )
{
p = vec2( dot(p,vec2(127.1,311.7)),
  dot(p,vec2(269.5,183.3)) );

return -1.0 + 2.0*fract(sin(p)*43758.5453123);
}

float noise( in vec2 p )
{
    const float K1 = 0.366025404; // (sqrt(3)-1)/2;
    const float K2 = 0.211324865; // (3-sqrt(3))/6;

vec2 i = floor( p + (p.x+p.y)*K1 );

    vec2 a = p - i + (i.x+i.y)*K2;
    vec2 o = (a.x>a.y) ? vec2(1.0,0.0) : vec2(0.0,1.0); //vec2 of = 0.5 + 0.5*vec2(sign(a.x-a.y), sign(a.y-a.x));
    vec2 b = a - o + K2;
vec2 c = a - 1.0 + 2.0*K2;

    vec3 h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 );

vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)));

    return dot( n, vec3(70.0) );

}

const mat2 m = mat2( 0.80,  0.60, -0.60,  0.80 );

float fbm4( in vec2 p )
{
    float f = 0.0;
    f += 0.5000*noise( p ); p = m*p*2.02;
    f += 0.2500*noise( p ); p = m*p*2.03;
    f += 0.1250*noise( p ); p = m*p*2.01;
    f += 0.0625*noise( p );
    return f;
}

float marble(in vec2 p)
{
return cos(p.x+fbm4(p));
}

float dowarp ( in vec2 q, out vec2 a, out vec2 b )
{
float ang=0.;
ang = 1.2345 * sin (33.33); //0.015*iTime);
mat2 m1 = mat2(cos(ang), -sin(ang), sin(ang), cos(ang));
ang = 0.2345 * sin (66.66); //0.021*iTime);
mat2 m2 = mat2(cos(ang), -sin(ang), sin(ang), cos(ang));

a = vec2( marble(m1*q), marble(m2*q+vec2(1.12,0.654)) );

ang = 0.543 * cos (13.33); //0.011*iTime);
m1 = mat2(cos(ang), -sin(ang), sin(ang), cos(ang));
ang = 1.128 * cos (53.33); //0.018*iTime);
m2 = mat2(cos(ang), -sin(ang), sin(ang), cos(ang));

b = vec2( marble( m2*(q + a)), marble( m1*(q + a) ) );

return marble( q + b +vec2(0.32,1.654));
}

// -----------------------------------------------

void main()
{
  vec2 uv = gl_FragCoord.xy / iResolution.xy;
vec2 q = 2.*uv-1.;
q.y *= iResolution.y/iResolution.x;

// camera
vec3 rd = normalize(vec3( q.x, q.y, 1. ));
vec3 euler = vec3(
sin(iTime * 0.2) * 0.625,
cos(iTime * 0.1) * 0.625,
iTime * 0.1 + sin(iTime * 0.3) * 0.5);

if(iMouse.z > 0.0)
{
euler.x = -((iMouse.y / iResolution.y) * 2.0 - 1.0);
euler.y = -((iMouse.x / iResolution.x) * 2.0 - 1.0);
euler.z = 0.0;
}
rd = RotateX(rd, euler.x);
rd = RotateY(rd, euler.y);
rd = RotateZ(rd, euler.z);

// Nebulae Background
float pi = 3.141592654;
q.x = 0.5 + atan(rd.z, rd.x)/(2.*pi);
q.y = 0.5 - asin(rd.y)/pi + 0.512 + 0.001*iTime;
q *= 2.34;

vec2 wa = vec2(0.);
vec2 wb = vec2(0.);
float f = dowarp(q, wa, wb);
f = 0.5+0.5*f;

vec3 col = vec3(f);
float wc = 0.;
wc = f;
col = vec3(wc, wc*wc, wc*wc*wc);
wc = abs(wa.x);
col -= vec3(wc*wc, wc, wc*wc*wc);
wc = abs(wb.x);
col += vec3(wc*wc*wc, wc*wc, wc);
col *= 0.7;
col.x = pow(col.x, 2.18);
col.z = pow(col.z, 1.88);
col = smoothstep(0., 1., col);
col = 0.5 - (1.4*col-0.7)*(1.4*col-0.7);
col = 0.75*sqrt(col);
col *= 1. - 0.5*fbm4(8.*q);
col = clamp(col, 0., 1.);

// StarField
float fShade = 0.0;
float a = 0.2;
float b = 10.0;
float c = 1.0;
float fZPos = 5.0;// + iTime * c + sin(iTime * a) * b;
float fSpeed = 0.; //c + a * b * cos(a * iTime);

fParticleLength = 0.25 * fSpeed / 60.0;

float fSeed = 0.0;

vec3 vResult = vec3(0.);

vec3 red = vec3(0.7,0.4,0.3);
vec3 blue = vec3(0.3,0.4,0.7);
vec3 tint = vec3(0.);
float ti = 1./float(PASS_COUNT-1);
float t = 0.;
for(int i=0; i<PASS_COUNT; i++)
{
tint = mix(red,blue,t);
vResult += 1.1*tint*Starfield(rd, fZPos, fSeed);
t += ti;
fSeed += 1.234;
rd = RotateX(rd, 0.25*euler.x);
}

col += sqrt(vResult);

// Vignetting
vec2 r = -1.0 + 2.0*(uv);
float vb = max(abs(r.x), abs(r.y));
col *= (0.15 + 0.85*(1.0-exp(-(1.0-vb)*30.0)));
gl_FragColor = vec4( col, 1.0 );
}

Time_coordinates.fs
Code: [Select]
// Created by Daniel Burke - burito/2014
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

// Inspiration from Dr Who (2005) S7E13 - The Name of the Doctor

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

vec2 rot(vec2 p, float a)
{
    float c = cos(a);
    float s = sin(a);
    return vec2(p.x*c + p.y*s,
                -p.x*s + p.y*c);
}

float circle(vec2 pos, float radius)
{
    return clamp(((1.0-abs(length(pos)-radius))-0.99)*100.0, 0.0, 1.0);
   
}

float circleFill(vec2 pos, float radius)
{
    return clamp(((1.0-(length(pos)-radius))-0.99)*100.0, 0.0, 1.0);   
}

// Thanks IƱigo Quilez!
float line( in vec2 p, in vec2 a, in vec2 b )
{
    vec2 pa = -p - a;
    vec2 ba = b - a;
    float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
    float d = length( pa - ba*h );
   
    return clamp(((1.0 - d)-0.99)*100.0, 0.0, 1.0);
}

// for posterity, the original evil function
float EvilLine(vec2 pos, vec2 start, vec2 finish)
{
    vec2 delta = finish - start;
    vec2 n = normalize(delta);
    float l = length(delta);
    float d = sign(n.x);
   
    float angle = atan(n.y / n.x);
    vec2 t = rot(-pos - start, angle);
   
    float s = d < 0.0 ? 0.0: d*l;
    float f = d < 0.0 ? d*l : 0.0;
    if(t.x > s || t.x < f)return 0.0;

    return clamp(((1.0 - abs(t.y))-0.99)*100.0, 0.0, 1.0);
}

void main()
{
vec2 uv = gl_FragCoord.xy / iResolution.xy;
    vec2 p = -1.0 + 2.0 * uv;
    p.x *= iResolution.x / iResolution.y;
 
    vec3 colour = vec3(0);
    vec3 white = vec3(1);
   
   
   
    float c = circle(p, 0.2);
    c += circle(p, 0.1);
    c += circle(p, 0.18);
    c += circleFill(p, 0.005);

//    c += circle(p, 1.3);
    c += circle(p, 1.0);
    if(p.x > 0.0)c += circle(p, 0.4);
    if(p.x > 0.0)c += circle(p, 0.42);
    if(p.x < 0.0)c += circle(p, 0.47);
    c += circleFill(p+vec2(0.47, 0.0), 0.02);
    c += circleFill(p+vec2(0.84147*0.47, 0.54030*0.47), 0.02);
    c += circleFill(p+vec2(0.84147*0.47, -0.54030*0.47), 0.02);
    c += circleFill(p+vec2(0.41614*0.47, 0.90929*0.47), 0.02);
    c += circleFill(p+vec2(0.41614*0.47, -0.90929*0.47), 0.02);
   
    float t = iTime;
    float t2 = t * -0.01;
    float t3 = t * 0.03;
   
    vec2 angle1 = vec2(sin(t), cos(t));
    vec2 a = angle1 * 0.7;
   
    t *= 0.5;
    vec2 angle2 = vec2(sin(t), cos(t));
    vec2 b = angle2 * 0.8;
   
    vec2 angle3 = vec2(sin(t2), cos(t2));
    vec2 d = b + angle3* 0.4;

    vec2 angle4 = vec2(sin(t3), cos(t3));
    vec2 e = angle4 * 0.9;

    vec2 angle5 = vec2(sin(t3+4.0), cos(t3+4.0));
    vec2 f = angle5 * 0.8;
   
    vec2 angle6 = vec2(sin(t*-0.1+5.0), cos(t*-0.1+5.0));
    vec2 h = angle6 * 0.8;
   
   

   
   
    float tt = t * 1.4;
   
    float tm = mod(tt, 0.5);
    float tmt = tt - tm;
    if( tm > 0.4) tmt += (tm-0.4)*5.0;
    vec2 tangle1 = vec2(sin(tmt), cos(tmt));

tt *= 0.8;
    tm = mod(tt, 0.6);
    float tmt2 = tt - tm;
    if( tm > 0.2) tmt2 += (tm-0.2)*1.5;
   
    vec2 tangle2 = vec2(sin(tmt2*-4.0), cos(tmt2*-4.0));
   
    vec2 tangle3 = vec2(sin(tmt2), cos(tmt2));
   
    tt = t+3.0;
    tm = mod(tt, 0.2);
    tmt = tt - tm;
    if( tm > 0.1) tmt += (tm-0.1)*2.0;
    vec2 tangle4 = vec2(sin(-tmt), cos(-tmt)); tmt += 0.9;
    vec2 tangle41 = vec2(sin(-tmt), cos(-tmt)); tmt += 0.5;
    vec2 tangle42 = vec2(sin(-tmt), cos(-tmt)); tmt += 0.5;
    vec2 tangle43 = vec2(sin(-tmt), cos(-tmt)); tmt += 0.5;
    vec2 tangle44 = vec2(sin(-tmt), cos(-tmt)); tmt += 0.5;
    vec2 tangle45 = vec2(sin(-tmt), cos(-tmt));

    tt = iTime+0.001;
    tm = mod(tt, 1.0);
    tmt = tt - tm;
    if( tm > 0.9) tmt += (tm-0.9)*10.0;

    vec2 tangle51 = 0.17*vec2(sin(-tmt), cos(-tmt)); tmt += 1.0471975511965976;
    vec2 tangle52 = 0.17*vec2(sin(-tmt), cos(-tmt)); tmt += 1.0471975511965976;
    vec2 tangle53 = 0.17*vec2(sin(-tmt), cos(-tmt));
   
    c += line(p, tangle51, -tangle53);
    c += line(p, tangle52, tangle51);
    c += line(p, tangle53, tangle52);
    c += line(p, -tangle51, tangle53);
    c += line(p, -tangle52, -tangle51);
    c += line(p, -tangle53, -tangle52);

    c += circleFill(p+tangle51, 0.01);
    c += circleFill(p+tangle52, 0.01);
    c += circleFill(p+tangle53, 0.01);
    c += circleFill(p-tangle51, 0.01);
    c += circleFill(p-tangle52, 0.01);
    c += circleFill(p-tangle53, 0.01);
   
   
   
    c += circle(p+a, 0.2);
    c += circle(p+a, 0.14);
    c += circle(p+a, 0.1);
    c += circleFill(p+a, 0.04);
    c += circleFill(p+a+tangle3*0.2, 0.025);   
   
   
    c += circle(p+a, 0.14);


    c += circle(p+b, 0.2);
    c += circle(p+b, 0.03);
    c += circle(p+b, 0.15);
    c += circle(p+b, 0.45);
    c += circleFill(p+b+tangle1*0.05, 0.01);
    c += circleFill(p+b+tangle1*0.09, 0.02);
    c += circleFill(p+b+tangle1*0.15, 0.03);
    c += circle(p+b+tangle1*-0.15, 0.03);
    c += circle(p+b+tangle1*-0.07, 0.015);

    c += circle(p+d, 0.08);


    c += circle(p+e, 0.08);
   

    c += circle(p+f, 0.12);
    c += circle(p+f, 0.10);
    c += circleFill(p+f+tangle2*0.05, 0.01);
    c += circleFill(p+f+tangle2*0.10, 0.01);
    c += circle(p+f-tangle2*0.03, 0.01);
    c += circleFill(p+f+vec2(0.085), 0.005);
    c += circleFill(p+f, 0.005);

   
    vec2 g = tangle4 * 0.16;
    c += circle(p+h, 0.05);
    c += circle(p+h, 0.1);
    c += circle(p+h, 0.17);
    c += circle(p+h, 0.2);
    c += circleFill(p+h+tangle41 *0.16, 0.01);
    c += circleFill(p+h+tangle42 *0.16, 0.01);
    c += circleFill(p+h+tangle43 *0.16, 0.01);
    c += circleFill(p+h+tangle44 *0.16, 0.01);
    c += circleFill(p+h+tangle45 *0.16, 0.01);
    c += circleFill(p+h+angle1 *0.06, 0.02);
    c += circleFill(p+h+tangle43*-0.16, 0.01);
   
   
    c += line(p, vec2(0.0), a);
    c += circleFill(p+b, 0.005);
    c += circleFill(p+d, 0.005);
    c += circleFill(p+e, 0.005);

    c += line(p, b, a);
    c += line(p, d, e);
    c += line(p, b+tangle1*0.15, e);
    c += line(p, e, f+vec2(0.085));

    c += line(p, h+angle1*0.06, f);
    c += line(p, h+tangle43*-0.16, d);
    c += line(p, h+tangle42*0.16, e);
   
   
    // of course I'd write a line function that
    // doesn't handle perfectly vertical lines
    c += line(p, vec2(0.001, -0.5), vec2(0.0001, 0.5));
    c += circleFill(p+vec2(0.001, -0.5), 0.005);
    c += circleFill(p+vec2(0.001, 0.5), 0.005);
   
    c = clamp(c, 0.0, 1.0);
    colour = white * c;
   

    gl_FragColor = vec4(colour, 1.0);
}

Sanctuary2.fs
Code: [Select]
// srtuss, 2018
//
// This began as an elaborate soundshader-experiment. I tried to create very clear-sounding
// instruments and mix them nicely, with a feel of depth and dark atmosphere to it. I added
// visuals based the images this music spawns in my head. Hope you enjoy it. :)
//
// Here is a recording of how the shader sounds, on the computers i created/tested it on:
// http://srtuss.thrill-project.com/art/sanctuary_soundtrack.ogg
//
// Music production with a soundshader: :)
// http://srtuss.thrill-project.com/music/shader.ogg
//

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

uniform sampler2D Stone_jpg;

vec2 rotate(vec2 p, float a)
{
    float co = cos(a), si = sin(a);
    return p * mat2(co, si, -si, co);
}

vec2 scene(vec3 p, bool details)
{
    float v = 1e38;
   
    float wall = 3. - dot(vec2(abs(p.x), p.y), normalize(vec2(1., .3)));
    float floorr = p.y;
    v = min(v, wall);
    float srs = .8;
    float strut = max(wall - .5, abs(fract(p.z * srs) - .5) / srs - .1);
    v = min(v, strut);
    v = min(v, max(strut, floorr) - .1);
   
    v = min(v, max(strut - .1, abs(floorr - 2.) - .5));
   
    float hole = 1.2 - length(p.xz);
    v = min(v, max(floorr, hole));
    v = min(v, max(abs(floorr), abs(hole)) - .2);
   
    vec3 q = p + vec3(0., sin(iTime) * .1 - 1., 0.);
    //float sphere = length(q) - .4;
    float sphere = length(q) - .02; // PAT 12-14-2019
   
    v = min(v, sphere);
   
    return vec2(v, step(sphere, v));
}

vec3 normal(vec3 p)
{
    float c = scene(p, true).x;
    vec2 h = vec2(.005, 0.);
    return normalize(vec3(scene(p + h.xyy, true).x - c, scene(p + h.yxy, true).x - c, scene(p + h.yyx, true).x - c));
}

vec4 trip(vec3 nml, vec3 pos)
{
    vec3 b = abs(nml);
    b = pow(b, vec3(50.));
    b /= dot(b, vec3(1.));
    return texture(Stone_jpg, pos.yz) * b.x + texture(Stone_jpg, pos.xz) * b.y + texture(Stone_jpg, pos.xy) * b.z;
}

float softshadow( in vec3 ro, in vec3 rd, float mint, float k )
{
float res = 1.0;
    float t = mint;
for(int i = 0; i < 32; ++i)
{
float h = scene(ro + rd * t, false).x;
if(h < 0.001)
return 0.0;
res = min(res, k * h / t);
t += h;
}
return res;
}

float amb_occ(vec3 p, float h)
{
float acc = 0.0;
acc += scene(p + vec3(-h, -h, -h), false).x;
acc += scene(p + vec3(-h, -h, +h), false).x;
acc += scene(p + vec3(-h, +h, -h), false).x;
acc += scene(p + vec3(-h, +h, +h), false).x;
acc += scene(p + vec3(+h, -h, -h), false).x;
acc += scene(p + vec3(+h, -h, +h), false).x;
acc += scene(p + vec3(+h, +h, -h), false).x;
acc += scene(p + vec3(+h ,+h, +h), false).x;
return acc / h;
}

void main()
{
    vec2 uv = gl_FragCoord / iResolution.xy;
    uv = uv * 2. - 1.;
    uv.x *= iResolution.x / iResolution.y;

    vec3 rd = normalize(vec3(uv, 1.66));
    vec3 ro = vec3(0., 1., -2.);
    float tilt = sin(iTime * .1 + 1.5) * .2 + .2;
    ro.yz = rotate(ro.yz, tilt);
    rd.yz = rotate(rd.yz, tilt);
   
    ro.xz = rotate(ro.xz, sin(iTime * .1) * .5);
    rd.xz = rotate(rd.xz, sin(iTime * .1) * .5);
   
    float d = 0.;
    for(int i = 0; i < 60; ++i)
    {
        d += scene(ro + rd * d, false).x;
    }
   
    vec3 hit = ro + rd * d;
    vec3 nml = normal(hit);
   
    vec3 lpos1 = vec3(0.5, 2., 4.);
   
    float mtl = scene(hit, false).y;
    vec3 diffMap = vec3(0.);
    if(mtl < .5)
    {
        float k = .001;
        diffMap = trip(nml, hit * 1.111).xyz;
        vec3 diffMap2 = trip(nml, hit * 1.111 + vec3(.005)).xyz;
        nml = normalize(nml + (diffMap.x - diffMap2.x) * .7);
    }
    else
    {
        vec3 mov = hit + vec3(0., sin(iTime) * .1 - 1., 0.);
        //nml = normalize(nml + sin(hit * 200.) * .03);
       
        float k = .001;
        diffMap = trip(nml, mov * 1.111).xyz;
        vec3 diffMap2 = trip(nml, mov * 1.111 + vec3(.005)).xyz;
        nml = normalize(nml + (diffMap.x - diffMap2.x) * .7);
    }
   
vec3 col = vec3(0.);// * exp(length(hit.xy - vec2(0., 1.)) * -1.) * exp(d * -.3);
   
    for(int i = 0; i < 2; ++i)
    {
        vec3 light = i == 1 ? lpos1 : vec3(cos(iTime * .4), 2., sin(iTime) + 1.);
        vec3 vLight = light - hit;
        vec3 lcol = i == 1 ? vec3(1, 1., .7) : vec3(.3, .7, 1.);
        float lfade = exp(length(vLight) * -1.3);
        vec3 diff = max(dot(nml, normalize(vLight)), 0.) * lfade * lcol;
        vec3 ref = reflect(rd, nml);
        float spec = pow(max(0., dot(normalize(vLight), ref)), 32.);

        vec3 ccol = vec3(1.);
        ccol *= pow(diffMap, vec3(2.));

        ccol *= diff;
        ccol += vec3(.4) * spec * lfade;
       
        col += ccol;
    }
   
    col *= smoothstep(-5., 1., amb_occ(hit, .15));
   
    //col = nml * .5 + .5;
   
    col += exp((7. - dot(rd, lpos1 - ro)) * -6.);// * softshadow(ro, normalize(lpos1 - ro), .1, 128.);
   
    float pt = iTime * .2;
    for(int i = 0; i < 20; ++i)
    {
        float pd = 2.;
        hit = ro + rd * pd;
        float h = float(i);
        if(d > pd)
        {
            col += exp(length(hit.xy - vec2(sin(h) * .4 + sin(pt + h) * .1, cos(pt + h) * .1 + fract(pt * .1 + cos(h)))) * -400.) * .05 * (1.1 + sin(h * 10.));
        }
    }
   
    col = sqrt(col);
    col *= 2.9;
   
    gl_FragColor = vec4(col,1.0);
}
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 08:08:26 pm
I have translated this one
https://www.shadertoy.com/view/ll3fz4

however the colors do not match the original  :(

I've_seen.fs
Code: [Select]
// Author: ocb
// Title: I've seen...

/***********************************************************************
Evolution based on Hope shader:  https://www.shadertoy.com/view/MllfDX
Still playing around with grids, (intersecting - overlaping...) to manage
lots of objects in order to generate all kind of cities.
Three intersecting grids generate variable size voxels which contains
cylinder (pipe), or sphere (little dome) or squared building.
One overlaping grid to generate big dome.

Using Shane's functions (the famous "Old nVidia tutorial) to create the decrepit
surface of the building.

Use mouse to look around

Sorry for thr unreadable code.
************************************************************************/

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

uniform sampler2D Metal_jpg;
uniform sampler2D Moss_jpg;
uniform sampler2D Cloth_jpg;
uniform sampler2D Organic_jpg;

#define PI 3.141592653589793
#define PIdiv2 1.57079632679489
#define TwoPI 6.283185307179586
#define INFINI 1000000.
#define MAXSTEP 127
#define TOP_SURFACE 2.81

/*************  GRID ****************************************************/
#define A .13
#define B .41
#define C .47

#define G2 .02
#define GS .003

/*************  Object **************************************************/
#define GND 0
#define SKY 1
#define CYL 2
#define SPH 3
#define SIDE 4
#define SPHBIS 5

#define DUST vec3(1.,.9,.7)



#define moonCtr vec3(.10644925908247,.266123147706175,.958043331742229)
#define moonShad vec3(-0.435448415412873,0.224265278324226,0.87183126948543)
#define moonRefl vec3(0.524134547566281, 0.21940212059613, 0.822888622794975)

#define starLight vec3(0.814613079962557,0.203653269990639,-0.543075386641705)

int hitObj = SKY;
float hitScale = 1.;
bool WINDOW = false;
bool SIDEWIN = false;

float Hsh(in float v) {
    return fract(sin(v) * 437585.);
}


float Hsh2(in vec2 st) {
    return fract(sin(dot(st,vec2(12.9898,8.233))) * 43758.5453123);
}


float sphereImpact(in vec3 pos, in vec3 ray, in vec3 O, in float R, inout vec3 norm ){
    float d=0., t = INFINI;
    vec3 a = O - pos;
    float b = dot(a, ray);
   
    if (b >= 0.){ // check if object in frontside first (not behind screen)
        float c = dot(a,a) - R*R;
    d = b*b - c;
    if (d >= 0.){
        float sd = sqrt(d);
            t = b - sd;
            norm = normalize(pos + t*ray - O);
        }
    }
   
    return t;
}

float cylinderImpact(in vec2 pos,in vec2 ray, in vec2 O, in float R, inout vec2 norm){
    float t=INFINI;
    vec2 d = pos - O;
    float a = dot(ray,ray);
    float b = dot(d, ray);
    float c = dot(d,d) - R*R;
    float discr = b*b - a*c;
    if (discr >= 0.){
        t = (-b - sqrt(discr))/a;
        if (t < 0.001) t = (-b + sqrt(discr))/a;
        if (t < 0.001) t=INFINI;

        norm = normalize(pos + t*ray - O);
    }
return t;
}


vec4 voxInfo(in vec2 xz){
vec2 dtp = fract(xz*A)/A;
    vec2 dtq = fract((xz)*B)/B;
    vec2 dtr = fract((xz)*C)/C;
    vec2 dm1 = min(min(dtp,dtq),dtr);
   
    dtp = 1./A-dtp;
    dtq = 1./B-dtq;
    dtr = 1./C-dtr;
    vec2 dm2 = min(min(dtp,dtq),dtr);

    vec2 size = dm1+dm2;
    vec2 ctr = xz+.5*(dm2-dm1);
   
    return vec4(ctr,size);
   
}

vec4 voxInfoBis(in vec2 xz){
    vec2 size = vec2(1./G2);
    vec2 ctr = (floor(xz*G2)+.5)*size;
    return vec4(ctr,size);
   
}

vec4 getNextPlan(in vec2 xz, in vec2 v){
    vec2 s = sign(v);
    vec2 d = step(0.,s);
vec2 dtp = (d-fract(xz*A))/A/v;
    vec2 dtq = (d-fract((xz)*B))/B/v;
    vec2 dtr = (d-fract((xz)*C))/C/v;

    vec2 dmin = min(min(dtp,dtq),dtr);
    float tmin = min(dmin.x, dmin.y);
   
    s *= -step(dmin,vec2(tmin));
   
    return vec4(s.x,0.,s.y,tmin);
}

vec4 getNextPlanBis(in vec2 xz, in vec2 v){
    vec2 s = sign(v);
    vec2 d = step(0.,s);
vec2 dtp = (d-fract(xz*G2))/G2/v;
   
    float tmin = min(dtp.x, dtp.y);
   
    s *= -step(tmin,vec2(tmin));
   
    return vec4(s.x,0.,s.y,tmin);
}


float gndFactor(in vec2 p) // use for cam anti-collision
{
vec2 f = 1.5-3.*abs(fract(p.xy*G2)-.5);
    f=smoothstep(.9,1.8,f);
    return 1.5*(f.x+f.y);   
}

float map(in vec2 xz)
{   
    vec2 p = floor(xz*A)/A;
    vec2 q = floor((xz)*B)/B;
    vec2 r = floor((xz)*C)/C;
   
    vec2 f = 1.5-abs(fract(p*G2)-.5)-abs(fract(q*G2)-.5)-abs(fract(r*G2)-.5);
    f=smoothstep(.9,1.8,f);
    float c = 1.5*(f.x+f.y);
   
    float Hp = c*Hsh2(p), Hq = c*Hsh2(q), Hr = c*Hsh2(r);
    float Pp = step(.6,Hp), Pq = step(.6,Hq), Pr = step(.5,Hr);
   
    float tex = 1.*Hp*Pp + .5*Hq*Pq +.3*Hr*Pr;  
    hitScale = Pp + 2.5*Pq + 5.*Pr;
   
    return tex;
}


vec4 trace(in vec3 pos, in vec3 ray, inout vec4 flam)
{
    float dh = 0.;
    float t = 0.;
   
    if(pos.y > TOP_SURFACE){ // navigating directly to the top surface (perfos)
        if(ray.y >= 0.) return vec4(vec3(0.),INFINI);
t = (TOP_SURFACE - pos.y)/ray.y + 0.00001;
    }
   
    vec4 wall = vec4(0.); // wall.xyz is the normal of the wall. wall.w is the t parameter.
   
    for(int i = 0;i<MAXSTEP;i++){ // entering the voxel run
       
        vec3 p = pos+t*ray;
        if(p.y > TOP_SURFACE) break; // when "looking" up, you may fly out before hiting
        // break immediately (perfos)
        float h = map(p.xz);
        float dh = p.y - h;
        if(dh<.0) return vec4(wall.xyz,t-.00002); // you are suddenly below the floor?
        // you hit the previous wall
       
        wall = getNextPlan(p.xz,ray.xz); // find the next wall
        float tt = 0.;
       
        float th = dh/(-ray.y); // find the floor
        th += step(th,0.)*INFINI;
       
        vec4 vox = voxInfo(p.xz); // get voxel info: center and size
        float H = Hsh2(floor(100.*vox.xy));
       
        vec3 normsph = vec3(0.); // Little dome
        float ts = INFINI;
        if(bool(step(H,.6)) && t<150.){
        ts = sphereImpact(p, ray, vec3(vox.x,h-.5,vox.y), H*min(vox.z,vox.w), normsph );
        }
           
        vec3 normcyl = vec3(0.); // Pipe
        float tc = INFINI;
        if(bool(step(H,.2)) && t<100.){
            vec2 c = vox.xy+ (4.*H-.4)*vox.zw;
            float r = .025*min(vox.z,vox.w);
            float top = 2.5*H*TOP_SURFACE;
            tc = cylinderImpact(p.xz, ray.xz, c, r, normcyl.xz );
            tc += step(top,p.y+tc*ray.y)*INFINI;
           
            float Hc = (H-.15)*20.;
        float ti = iTime*.4;
            // Flam calculation
        if(bool(step(.15,H)*step(.95,Hsh(.0001*(vox.x+vox.y)*floor(Hc+ti))) )){
                float fti = fract(Hc+ti);
                vec2 len = c-pos.xz;
                float h = length(len)*ray.y/length(ray.xz)+pos.y;
                float dh = h - top;
                float d = abs(ray.z*len.x - ray.x*len.y);
                float mvt = 1.+cos(5.*dh);
                flam.rgb += min(1.,min(1.,min(vox.z,vox.w))*.2*mvt*(r+dh)/d-.1)
                       *step(0.,dh)
                       *((.8-abs(fti-.5))/(dh+.2) -.3 )
                       *texture(Organic_jpg,vec2(.2*h-.5*ti+Hc,d*(1.+fti)*dh*mvt+Hc)).rgb;
                flam*=flam*(2.-fti);
                flam.w = t;
            }
        }
           

        tt = min(min(ts,th),tc);
        tt = min(wall.w,tt); // keep the min between floor and wall distance
        if(tt==th) return vec4(0.,1.,0.,t+tt); // if first hit = floor return hit info (floor)
        else if(tt==ts){hitObj = SPH; return vec4(normsph,t+tt);}
        else if(tt==tc){hitObj = CYL; return vec4(normcyl,t+tt);}
        else tt = wall.w; // else keep the local t parameter to the next wall
       
        t+= tt+.00001; // update global t and do again
        if(t>250.) break; // not necessary to go too far (perfos)
    }
   
   
    return vec4(0.,0.,0.,INFINI);
}

vec4 traceBis(in vec3 pos, in vec3 ray)
{
    float dh = 0.;
    float t = 0.;
   
    if(pos.y > TOP_SURFACE){ // navigating directly to the top surface (perfos)
        if(ray.y >= 0.) return vec4(vec3(0.),INFINI);
t = (TOP_SURFACE - pos.y)/ray.y + 0.00001;
    }
   
    vec4 wall = vec4(0.); // wall.xyz is the normal of the wall. wall.w is the t parameter.
   
    for(int i = 0;i<MAXSTEP;i++){ // entering the voxel run
       
        vec3 p = pos+t*ray;
        if(p.y > TOP_SURFACE) break; // when "looking" up, you may fly out before hiting
        // break immediately (perfos)
       
        wall = getNextPlanBis(p.xz,ray.xz); // find the next wall
               
        vec4 vox = voxInfoBis(p.xz);
        vec3 normsph;
        float radius = 25.;//.5*min(vox.z,vox.w);
        float tt = sphereImpact(p, ray, vec3(vox.x,TOP_SURFACE-radius-1.,vox.y), radius , normsph );
       
        if(tt<INFINI) return vec4(normsph,t+tt);
        else tt = wall.w; // else keep the local t parameter to the next wall
       
        t+= tt+.00001; // update global t and do again
        if(t>250.) break; // not necessary to go too far (perfos)
    }
   
   
    return vec4(0.,0.,0.,INFINI);
}


float mapGnd(in vec3 p){return .5*texture(Organic_jpg, GS*p.xz).r +.2*texture(Organic_jpg, 2.*GS*p.xz).r;}

vec4 traceGround(in vec3 pos, in vec3 ray)
{
if(ray.y>0.) return vec4(0.,0.,0.,INFINI);

    float t = (mapGnd(pos) - pos.y)/ray.y;
       
    for(int i = 0;i<MAXSTEP;i++){
       
        vec3 p = pos+t*ray;
        float dh = p.y-mapGnd(p);
       
        if(abs(dh) < .003){
vec2 e = vec2(-.2,.2);   
vec3 norm = normalize(e.yxx*mapGnd(p + e.yxx) + e.xxy*mapGnd(p + e.xxy) +
         e.xyx*mapGnd(p + e.xyx) + e.yyy*mapGnd(p + e.yyy) );   
           
            return vec4(norm,t);
        }
       
        t += dh;
       
        if(t>250.) break;
    }
   
    return vec4(0.,0.,0.,INFINI);
}


vec4 boxImpact( in vec3 pos, in vec3 ray, in vec3 ctr, in vec3 dim)
{
    vec3 m = 1.0/ray;
    vec3 n = m*(ctr-pos);
    vec3 k = abs(m)*dim;

    vec3 t1 = n - k;
    vec3 t2 = n + k;

float tmax = max( max( t1.x, t1.y ), t1.z );
float tmin = min( min( t2.x, t2.y ), t2.z );

if( tmax > tmin || tmin < 0.0) return vec4(vec3(0.),INFINI);

    vec3 norm = -sign(ray)*step(t2, vec3(tmin));
    return vec4(norm, tmin);
}


bool checkWindow(in vec3 ctr){
    float hash = Hsh2(ctr.xz+ctr.yy);
    float a = step(.4,hash)*step(mod(ctr.y,10.),0.);
    float b = step(.7,hash)*step(mod(ctr.y-1.,10.),0.);
    return bool(a+b);
}

vec4 traceWindow(in vec3 pos, in vec3 ray, in float t, in vec3 norm){
    float d, sh, sv;
    if(hitObj == SPHBIS){d=.03; sh=2.5; sv=1.;}
    else if(hitObj == SPH){d=.03; sh=.5; sv=.75;}
    else if(hitObj == CYL){d=.01; sh=.1; sv= 1.;}
    else {d=.1; sh=1.; sv=1.;}
   
    vec3 p = pos + t*ray;
    vec4 info = vec4(norm,t);

    vec3 boxDim = vec3(sh*.25,sv*.025,sh*.25);
vec3 boxCtr;
   
    for(int i=0; i<5; i++){
    boxCtr = vec3(floor(p.x*2./sh),floor(p.y*20./sv),floor(p.z*2./sh));
        if(checkWindow(boxCtr)){
            SIDEWIN = true;
            float tf = t + d/dot(ray,-norm);
            info = boxImpact(pos, ray, (boxCtr+.5)*vec3(sh*.5,sv*.05,sh*.5), boxDim);
            if(tf < info.w){
                WINDOW = true;
                info = vec4(norm,tf);
                break;
            }
            p = pos + (info.w+.001)*ray;
        }
        else break;
    }
    return info;
}

vec3 starGlow(in vec3 ray, in float a){
    vec3 col = vec3(.001/(1.0001-a));
    return col;
}

vec3 moonGlow(in vec3 ray, in float a){
    float dl = dot(moonRefl,ray);
    float moon = smoothstep(.9,.93,a);
    float shad = 1.-smoothstep(.7,.9,dot(moonShad, ray));
    float refl = .001/(1.0013-dl);
float clouds = .5*texture(Organic_jpg,ray.xy).r+.3*texture(Organic_jpg,3.*ray.xy).r;
    vec3 col = .8*(vec3(.5,.3,.0)+clouds*vec3(.3,.4,.1))*moon+vec3(1.,1.,.7)*refl;
    col += vec3(.3,.5,.8)*smoothstep(.89,.90,a)*(1.-smoothstep(.89,.99,a))*(dl-.9)*15.;
col *= shad;
    col -= vec3(.1,.3,.6)*(1.-moon*shad);
    col = clamp(col,0.,1.);
    return col;
}

vec3 stars(in vec3 ray){
    vec3 col = vec3(0.);
    float az = atan(.5*ray.z,-.5*ray.x)/PIdiv2;
    vec2 a = vec2(az,ray.y);
   
    float gr = -.5+a.x+a.y;
    float milky = 1.-smoothstep(0.,1.2,abs(gr));
float nebu = 1.-smoothstep(0.,.7,abs(gr));

    vec3 tex = texture(Organic_jpg,a+.3).rgb;
    vec3 tex2 = texture(Organic_jpg,a*.1).rgb;
vec3 tex3 = texture(Organic_jpg,a*5.).rgb;
float dark = 1.-smoothstep(0.,.3*tex.r,abs(gr));
   
    vec2 dty =a*12.;
    col += step(.85,Hsh2(floor(dty)))*(tex+vec3(.0,.1,.1))*max(0.,(.01/length(fract(dty)-.5)-.05));
   
    dty =a*30.;
    col += step(.8,Hsh2(floor(dty)))*tex*max(0.,(.01/length(fract(dty)-.5)-.05))*milky;
   
    dty =a*1000.;
    col += max(0.,Hsh2(floor(dty))-.9)*3.*tex3*milky;
   
    col += (.075+.7*smoothstep(.1,1.,(tex+vec3(.15,0.,0.))*.3))*nebu;
    col += .5*smoothstep(0.,1.,(tex2+vec3(0.,.2,.2))*.2)*milky;
col -= .15*(tex3 * dark);
   
    return col;
}

vec3 fewStars(in vec3 ray){
vec3 col = vec3(0.);
    float az = atan(.5*ray.z,-.5*ray.x)/PIdiv2;
    vec2 a = vec2(az,ray.y);
   
    vec3 tex = texture(Organic_jpg,a+.3).rgb;
    vec2 dty =a*14.;
    col += step(.85,Hsh2(floor(dty)))*(tex+vec3(.0,.1,.1))*max(0.,(.01/length(fract(dty)-.5)-.05));

    return col;
}

bool shadTrace(in vec3 pos, in vec3 v){
float dh = 0.;
    float t = 0.;
    vec4 wall = vec4(0.);
   
    for(int i = 0;i<10;i++){       
        vec3 p = pos + t*v;
        if(p.y > TOP_SURFACE) break;
       
        float h = map(p.xz);
        float dh = p.y - h;
        if(dh<.0) return true;
       
        vec4 vox = voxInfo(p.xz);
        float H = Hsh2(floor(100.*vox.xy));
        vec3 normsph;
        float ts = sphereImpact(p, v, vec3(vox.x,h-.5,vox.y), step(H,.6)*H*min(vox.z,vox.w), normsph );
        if(ts<INFINI) return true;
       
        vec3 normcyl = vec3(0.);
        float tc = cylinderImpact(p.xz, v.xz, vec2(vox.x,vox.y)+ (4.*H-.4)*vox.zw, .025*min(vox.z,vox.w), normcyl.xz );
        tc += step(step(H,.2)*2.5*H*TOP_SURFACE,p.y+tc*v.y)*INFINI;
        if(tc<INFINI) return true;
       
        wall = getNextPlan(p.xz,v.xz);       
        t+= wall.w + .0001 ;
    }   
    return false;   
}

bool shadTraceBis(in vec3 pos, in vec3 v){
float dh = 0.;
    float t = 0.;
    vec4 wall = vec4(0.);
   
    for(int i = 0;i<10;i++){       
        vec3 p = pos + t*v;
        if(p.y > TOP_SURFACE) break;
       
        vec4 vox = voxInfoBis(p.xz);
        vec3 normsph;
        float radius = 25.;
        float ts = sphereImpact(p, v, vec3(vox.x,TOP_SURFACE-radius-1.,vox.y), radius , normsph );
        if(ts<INFINI) return true;
       
        wall = getNextPlanBis(p.xz,v.xz);       
        t+= wall.w + .0001 ;
    }   
    return false;   
}

float shadow(in vec3 p){
    p += .00001*starLight;
    if(shadTrace(p,starLight)) return .1;
    if(shadTraceBis(p,starLight)) return .1;
    return 1.;
}

vec3 winGlow(in vec2 uv){
    uv.x *= .2;
    uv.y *= .5;
    vec2 k1 = (uv-.05*sin(uv*10.))*10.,
         k2 = (uv-.02*sin(uv*25.))*25.,
         k3 = (uv-.01*sin(uv*50.))*50.;
   
   
    vec2 p = floor(k1)/10.,
         q = floor(k2)/25.,
    s = floor(k3)/50.;
   
    vec2 bp = abs(fract(k1)-.5)
    + abs(fract(k2)-.5)
    + abs(fract(k3)-.5);
    bp /= 1.5;
    bp*=bp*bp;
   
    vec3 tex = texture(Cloth_jpg,p).rgb
    + texture(Cloth_jpg,q).rgb
    + texture(Cloth_jpg,s).rgb;
   
    tex += .5*(bp.x+bp.y);
    tex *= smoothstep(1.,2.8,tex.r);
   
return tex;
}


float metalPlate(in vec2 st){
    float coef = 0.;
   
    vec2 p = floor(st);
    float hp = Hsh2(p*0.543234); hp *= step(.2,abs(hp-.5));
    vec2 fp = fract(st)-.5;
    vec2 sfp = smoothstep(.475,.5,abs(fp));
   
    st *= vec2(.5,1.);
    vec2 q = floor(st*4.-.25);
    float hq = Hsh2(q*0.890976); hq *= step(.35,abs(hq-.5));
    vec2 fq = fract(st*4.-.25)-.5;
    vec2 sfq = smoothstep(.45,.5,abs(fq));

    st *= vec2(5.,.1);
    vec2 r = floor(st*8.-.25);
    float hr = Hsh2(r*0.123456); hr *= step(.47,abs(hr-.5));
    vec2 fr = fract(st*8.-.25)-.5;
    vec2 sfr = smoothstep(.4,.5,abs(fr));
   
    float h = max(max(hp,hq),hr);
    if(bool(h)){
        vec2 plate =    step(h,hp)*sfp*sign(fp)
                      + step(h,hq)*sfq*sign(fq)
                      + step(h,hr)*sfr*sign(fr);
       
        coef += .2*h+.8;
        coef += .5*min(1.,plate.x+plate.y);
    }
    else coef = 1.;
   
    return coef;
}


float flare(in vec3 ref, in vec3 ctr){
    float c = 0.;
    vec3
s = normalize(ref);
    float sc = dot(s,-starLight);
    c += .6*smoothstep(.9995,1.,sc);
   
    s = normalize(ref+.9*ctr);
    sc = dot(s,-starLight);
    c += .7*smoothstep(.99,1.,sc);
   
    s = normalize(ref-.7*ctr);
    sc = dot(s,-starLight);
    c += .2*smoothstep(.7,1.,sc);
   
    return c;
}

vec3 lensflare3D(in vec3 ray, in vec3 ctr)
{
    vec3 red = vec3(1.,.6,.3);
    vec3 green = vec3(.6,1.,.6);
    vec3 blue = vec3(.6,.3,.6);
vec3 col = vec3(0.);
    vec3 ref = reflect(ray,ctr);

    col += red*flare(ref,ctr);
    col += green*flare(ref-.07*ctr,ctr);
    col += blue*flare(ref-.14*ctr,ctr);
   
    ref = reflect(ctr,ray);
    col += red*flare(ref,ctr);
    col += green*flare(ref+.07*ctr,ctr);
    col += blue*flare(ref+.14*ctr,ctr);
   
    float d = dot(ctr,starLight);
return .4*col*max(0.,d*d*d*d*d);
}

vec3 lava(in vec2 p){
float tex = abs(texture(Organic_jpg,p*.05).r-.5+.3*sin(iTime*.2));
    vec3 lav = vec3(0.);
    lav.r += .5*(1.-smoothstep(.0,.2,tex));
    lav.rg += (1.-smoothstep(.0,.02,tex));
return lav;
}

vec3 getCamPos(in vec3 camTarget){
    float rau = 15.,
            alpha = iMouse.x/iResolution.x*4.*PI,
            theta = iMouse.y/iResolution.y*PI+(PI/2.0001);
   
            // to start shader
    if (iMouse.xy == vec2(0.)){
                float ts = smoothstep(18.,22.,iTime)*(iTime-20.);
                alpha = iTime*.04;
                theta = .3*(1.-cos(iTime*.1));
            }
    return rau*vec3(-cos(theta)*sin(alpha),sin(theta),cos(theta)*cos(alpha))+camTarget;
}

vec3 getRay(in vec2 st, in vec3 pos, in vec3 camTarget){
    float focal = 1.;
    vec3 ww = normalize( camTarget - pos);
    vec3 uu = normalize( cross(ww,vec3(0.0,1.0,0.0)) ) ;
    vec3 vv = cross(uu,ww);
// create view ray
return normalize( st.x*uu + st.y*vv + focal*ww );
}

// 2 functions from Shane
// the famous "Old Nvidia tutorial"!
vec3 tex3D( sampler2D tex, in vec3 p, in vec3 n ){
 
    n = max((abs(n) - 0.2)*7., 0.001);
    n /= (n.x + n.y + n.z );     
vec3 tx = (texture(tex, p.yz)*n.x + texture(tex, p.zx)*n.y + texture(tex, p.xy)*n.z).xyz;   
    return tx*tx;
}

vec3 texBump( sampler2D tx, in vec3 p, in vec3 n, float bf, in float t, in vec3 ray){   
    //const vec2 e = vec2(0.001, 0);   
    vec2 e = vec2(.2*t/iResolution.x/dot(-ray,n),0.);    // AA purpose
    //vec2 e = vec2(.5*t/iResolution.x,0.);
    mat3 m = mat3( tex3D(tx, p - e.xyy, n), tex3D(tx, p - e.yxy, n), tex3D(tx, p - e.yyx, n));   
    vec3 g = vec3(0.299, 0.587, 0.114)*m;
    g = (g - dot(tex3D(tx,  p , n), vec3(0.299, 0.587, 0.114)) )/e.x; g -= n*dot(n, g);                     
    return normalize( n + g*bf );
}


void main(){
    vec2 st = ( gl_FragCoord.xy
               //-.5*vec2(mod(gl_FragCoord.y,2.),mod(gl_FragCoord.x,2.))
               - .5*iResolution.xy ) / iResolution.y;
   
    // camera def
    vec3 camTarget = vec3(100.*sin(iTime*.01),1.,-60.*sin(iTime*.015));
   
    vec3 pos = getCamPos(camTarget);
   
    pos.y = max(pos.y,1.5*gndFactor(pos.xz)+1.); // Cam anti-collision
   
    vec3 ray = getRay(st, pos,camTarget);
   
    float moonArea = dot(ray,moonCtr);
    float starArea = dot(ray,starLight);
    bool starside = bool(step(0.,starArea));
    bool moonside = bool(step(0.,moonArea));

    vec3 color = vec3(.0);
    vec4 flamInfo = vec4(0.);
    float t = INFINI;
    vec3 norm = vec3(0.);

    vec4 info = trace(pos, ray, flamInfo);
    float sc = hitScale;
    t = info.w;
    norm = info.xyz;
   
    info = traceBis(pos, ray);
    if(info.w < t){
        t=info.w;
        norm = info.xyz;
        hitObj = SPHBIS;
  if(flamInfo.w > t) flamInfo.rgb = vec3(0.);
    }
   
    info = traceGround(pos,ray);
    if(info.w < t){
        t=info.w;
        norm = info.xyz;
        hitObj = GND;
    }
   
    float shadow = shadow(pos+t*ray);
   
    if(t==INFINI){
        float moonMask = 1.-smoothstep(.925,.93,moonArea);
        float starMask = 1.-smoothstep(.4,.9,starArea);
        if(starside) color += .7*starGlow(ray,starArea);
        if(moonside) color += moonGlow(ray,moonArea);
       
        color += fewStars(ray)*moonMask*starMask;
        color += stars(ray)*moonMask*starMask;
        color *= min(1.,abs(10.*ray.y*ray.y));
        color += .006/(ray.y*ray.y+.015)*DUST;
    }
    else{
        if(norm.y < .99 && hitObj != GND) {
            info = traceWindow(pos ,ray, t, norm);
            if(bool(info.w)) {
                norm = info.xyz;
                t = info.w;
            }
        }
       
        vec3 p = pos + t*ray;

        if(hitObj == SPH){
            if(WINDOW){
                vec2 d = p.xz - voxInfo(p.xz).xy;
                vec3 window = winGlow(vec2(.5*atan(d.x,d.y),.8*length(d)));
                vec3 refl = reflect(ray,norm);
                color += smoothstep(.95,1.,dot(starLight,refl))*norm.z*step(1.,shadow);
                color += window*min(1., 30./t);
        }
            else{
                vec2 ang;
                if(SIDEWIN) ang = p.xz;
                else ang = vec2(atan(norm.x,norm.z), atan(norm.y,length(norm.xz)));
                color += texture(Metal_jpg,ang).rgb;
                color *= metalPlate(4.*ang);
                color += .015*vec3(.5*sc,abs(sc-4.),8.-sc) * min(1.,10./t);
                norm = texBump( Organic_jpg,.2*norm, norm, .005, t, ray);
                color *= max(dot(norm, starLight),.0);
                if(SIDEWIN) color += vec3(.1,.05,.0);
                else color *= shadow;
            }
        }
        else if(hitObj == CYL){
            if(WINDOW){
                vec3 window = winGlow(2.*p.zy);
                vec3 refl = reflect(ray,norm);
                color += smoothstep(.95,1.,dot(starLight,refl))*norm.z*step(1.,shadow);
                color += window*min(1., 30./t);
        }
            else{
                vec2 ang;
                if(SIDEWIN) ang = p.xz;
                else ang = vec2(atan(norm.x,norm.z), 2.*p.y);
                color += texture(Metal_jpg,ang).rgb;
                color *= metalPlate(2.*ang);
                color += .015*vec3(.5*sc,abs(sc-4.),8.-sc) * min(1.,10./t);
                color *= max(dot(norm, starLight),.0);
                if(SIDEWIN) color += vec3(.1,.05,.0);
                else color *= shadow;
            }
        }
        else if(hitObj == SPHBIS){
            if(WINDOW){
                vec2 d = p.xz - voxInfoBis(p.xz).xy;
                vec3 window = .5*winGlow(vec2(3.*atan(d.x,d.y),.25*length(d)));
                vec3 refl = reflect(ray,norm);
                color += smoothstep(.95,1.,dot(starLight,refl))*norm.z*step(1.,shadow);
                color += window*min(1., 30./t);
        }
            else{
                vec2 ang;
                if(SIDEWIN) ang = .5*p.xz;
                else ang = vec2(atan(norm.x,norm.z), atan(norm.y,length(norm.xz)));
                color += texture(Metal_jpg,ang).rgb;
                color *= metalPlate(4.*ang);
                sc =1.;
                color += .015*vec3(.5*sc,abs(sc-4.),8.-sc) * min(1.,10./t);
                norm = texBump( Organic_jpg,2.*norm, norm, .002, t, ray);
                color *= max(dot(norm, starLight),.0);
                if(SIDEWIN) color += vec3(.1,.05,.0);
                else color *= shadow;

            }
        }   
        else if(hitObj == GND){
            vec3 dirt = texture(Organic_jpg,GS*p.xz).rgb;
            color = 1.5*p.y*dirt*dirt;
           
            color *= max(0.,dot(norm, -starLight));
            color *= shadow;
           
            vec2 e = t/iResolution.x/ray.y*ray.xz; // 2 lines for AA purpose
            vec3 lavaCol = (lava(p.xz)+lava(p.xz+e)+lava(p.xz-e))/3.;
           
color += .8*lavaCol*(1.-smoothstep(.0,.1,dirt.r));
        }
        else{
            if(p.y <.01) color = vec3(0.);
            else{
                if(WINDOW){
                    vec3 window = winGlow( (p.xy+p.z)*norm.z + (p.zy+p.x)*norm.x);
                    vec3 refl = reflect(ray,norm);
                    color += smoothstep(.95,1.,dot(starLight,refl))*norm.z*step(1.,shadow);
                    color += window*min(1., 30./t);
                }
                else{
                    vec2 side = .5*vec2(p.x,-p.z)*norm.y + .5*vec2(-p.x,-p.y)*norm.z + .5*vec2(p.y,-p.z)*norm.x;
                    color += texture(Metal_jpg,side).rgb;
                   
                    vec2 e = vec2(2.*t/iResolution.x/dot(-ray,norm),0.); // 2 lines for AA purpose
                    float mp =  ( metalPlate(4.*side)
                            + metalPlate(4.*side+e)
                        + metalPlate(4.*side-e)
                        + metalPlate(4.*side+e.yx)
                        + metalPlate(4.*side-e.yx)) /5.;
                   
                    color *= mp;
                    color += .015*vec3(.5*sc,abs(sc-4.),8.-sc) * min(1.,10./t);

                    norm = texBump( Organic_jpg, .2*p, norm, .003, t, ray);

                    color *= clamp(dot(norm, starLight)+.2,.3,1.);
                    if(SIDEWIN) color += vec3(.1,.05,.0);
                    else color *= shadow;

                    vec3 refl = reflect(ray,norm);
                    color += .3*smoothstep(.9,1.,dot(starLight,refl))*norm.z*step(1.,shadow);;
                    color = clamp(color,0.,1.);
                }
            }
        }
        color *= min(1., 20./t);
        color += min(.003*t,.35)*DUST;
    }
   
    color += flamInfo.rgb*flamInfo.rgb;

    if(starside)
    //if(!shadTrace(pos,starLight))
    color += lensflare3D(ray, getRay(vec2(0.), pos,camTarget));
   
gl_FragColor = vec4(1.5*color,1.);
}
   
   
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 08:53:21 pm
My friend,

I'm absolutely happy that you've finally come to enjoy shaders. :D

Thank you for your work!

Regarding I'veSeen, your colors are incorrect because it's a two pass shader that needs two FBO's to get rendered as intended. (see there are TWO CODE TABS on ShaderToy?)

Such shaders need to run in two render passes, like background+PP shaders combined, which we can't do yet in our OR. Please try to port only one-FBO shaders -- those whose code is written in one code tab only! (not counting the sound tab if present)

P.S. Now that there's a genuine Wood.jpg in the \Animated folder, please open up my FractalFlythrough.fs and change all multiple occurrences of metal_jpg to wood_jpg. Now the metal structure colors will be exactly like they are on ShaderToy.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 09:42:14 pm
Patrice,

I'veSeen.fs can safely be run in one pass (with one buffer) but all its textures should not be mipmapped.

To this end, the names of samplers throughout the code should be prefixed with nomip_. (actually nomip_moss_jpg is not used in the shader code at all)

Enjoy! :D

Code: [Select]
// Author: ocb
// Title: I've seen...

/***********************************************************************
Evolution based on Hope shader:  https://www.shadertoy.com/view/MllfDX
Still playing around with grids, (intersecting - overlaping...) to manage
lots of objects in order to generate all kind of cities.
Three intersecting grids generate variable size voxels which contains
cylinder (pipe), or sphere (little dome) or squared building.
One overlaping grid to generate big dome.

Using Shane's functions (the famous "Old nVidia tutorial) to create the decrepit
surface of the building.

Use mouse to look around

Sorry for thr unreadable code.
************************************************************************/

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

uniform sampler2D nomip_metal_jpg;
//uniform sampler2D Moss_jpg; // MLL: not used
uniform sampler2D nomip_cloth_jpg;
uniform sampler2D nomip_organic_jpg;

#define PI 3.141592653589793
#define PIdiv2 1.57079632679489
#define TwoPI 6.283185307179586
#define INFINI 1000000.
#define MAXSTEP 127
#define TOP_SURFACE 2.81

/*************  GRID ****************************************************/
#define A .13
#define B .41
#define C .47

#define G2 .02
#define GS .003

/*************  Object **************************************************/
#define GND 0
#define SKY 1
#define CYL 2
#define SPH 3
#define SIDE 4
#define SPHBIS 5

#define DUST vec3(1.,.9,.7)



#define moonCtr vec3(.10644925908247,.266123147706175,.958043331742229)
#define moonShad vec3(-0.435448415412873,0.224265278324226,0.87183126948543)
#define moonRefl vec3(0.524134547566281, 0.21940212059613, 0.822888622794975)

#define starLight vec3(0.814613079962557,0.203653269990639,-0.543075386641705)

int hitObj = SKY;
float hitScale = 1.;
bool WINDOW = false;
bool SIDEWIN = false;

float Hsh(in float v) {
    return fract(sin(v) * 437585.);
}


float Hsh2(in vec2 st) {
    return fract(sin(dot(st,vec2(12.9898,8.233))) * 43758.5453123);
}


float sphereImpact(in vec3 pos, in vec3 ray, in vec3 O, in float R, inout vec3 norm ){
    float d=0., t = INFINI;
    vec3 a = O - pos;
    float b = dot(a, ray);

    if (b >= 0.){ // check if object in frontside first (not behind screen)
        float c = dot(a,a) - R*R;
    d = b*b - c;
    if (d >= 0.){
        float sd = sqrt(d);
            t = b - sd;
            norm = normalize(pos + t*ray - O);
        }
    }

    return t;
}

float cylinderImpact(in vec2 pos,in vec2 ray, in vec2 O, in float R, inout vec2 norm){
    float t=INFINI;
    vec2 d = pos - O;
    float a = dot(ray,ray);
    float b = dot(d, ray);
    float c = dot(d,d) - R*R;
    float discr = b*b - a*c;
    if (discr >= 0.){
        t = (-b - sqrt(discr))/a;
        if (t < 0.001) t = (-b + sqrt(discr))/a;
        if (t < 0.001) t=INFINI;

        norm = normalize(pos + t*ray - O);
    }
return t;
}


vec4 voxInfo(in vec2 xz){
vec2 dtp = fract(xz*A)/A;
    vec2 dtq = fract((xz)*B)/B;
    vec2 dtr = fract((xz)*C)/C;
    vec2 dm1 = min(min(dtp,dtq),dtr);

    dtp = 1./A-dtp;
    dtq = 1./B-dtq;
    dtr = 1./C-dtr;
    vec2 dm2 = min(min(dtp,dtq),dtr);

    vec2 size = dm1+dm2;
    vec2 ctr = xz+.5*(dm2-dm1);

    return vec4(ctr,size);

}

vec4 voxInfoBis(in vec2 xz){
    vec2 size = vec2(1./G2);
    vec2 ctr = (floor(xz*G2)+.5)*size;
    return vec4(ctr,size);

}

vec4 getNextPlan(in vec2 xz, in vec2 v){
    vec2 s = sign(v);
    vec2 d = step(0.,s);
vec2 dtp = (d-fract(xz*A))/A/v;
    vec2 dtq = (d-fract((xz)*B))/B/v;
    vec2 dtr = (d-fract((xz)*C))/C/v;

    vec2 dmin = min(min(dtp,dtq),dtr);
    float tmin = min(dmin.x, dmin.y);

    s *= -step(dmin,vec2(tmin));

    return vec4(s.x,0.,s.y,tmin);
}

vec4 getNextPlanBis(in vec2 xz, in vec2 v){
    vec2 s = sign(v);
    vec2 d = step(0.,s);
vec2 dtp = (d-fract(xz*G2))/G2/v;

    float tmin = min(dtp.x, dtp.y);

    s *= -step(tmin,vec2(tmin));

    return vec4(s.x,0.,s.y,tmin);
}


float gndFactor(in vec2 p) // use for cam anti-collision
{
vec2 f = 1.5-3.*abs(fract(p.xy*G2)-.5);
    f=smoothstep(.9,1.8,f);
    return 1.5*(f.x+f.y);
}

float map(in vec2 xz)
{
    vec2 p = floor(xz*A)/A;
    vec2 q = floor((xz)*B)/B;
    vec2 r = floor((xz)*C)/C;

    vec2 f = 1.5-abs(fract(p*G2)-.5)-abs(fract(q*G2)-.5)-abs(fract(r*G2)-.5);
    f=smoothstep(.9,1.8,f);
    float c = 1.5*(f.x+f.y);

    float Hp = c*Hsh2(p), Hq = c*Hsh2(q), Hr = c*Hsh2(r);
    float Pp = step(.6,Hp), Pq = step(.6,Hq), Pr = step(.5,Hr);

    float tex = 1.*Hp*Pp + .5*Hq*Pq +.3*Hr*Pr;
    hitScale = Pp + 2.5*Pq + 5.*Pr;

    return tex;
}


vec4 trace(in vec3 pos, in vec3 ray, inout vec4 flam)
{
    float dh = 0.;
    float t = 0.;

    if(pos.y > TOP_SURFACE){ // navigating directly to the top surface (perfos)
        if(ray.y >= 0.) return vec4(vec3(0.),INFINI);
t = (TOP_SURFACE - pos.y)/ray.y + 0.00001;
    }

    vec4 wall = vec4(0.); // wall.xyz is the normal of the wall. wall.w is the t parameter.

    for(int i = 0;i<MAXSTEP;i++){ // entering the voxel run

        vec3 p = pos+t*ray;
        if(p.y > TOP_SURFACE) break; // when "looking" up, you may fly out before hiting
        // break immediately (perfos)
        float h = map(p.xz);
        float dh = p.y - h;
        if(dh<.0) return vec4(wall.xyz,t-.00002); // you are suddenly below the floor?
        // you hit the previous wall

        wall = getNextPlan(p.xz,ray.xz); // find the next wall
        float tt = 0.;

        float th = dh/(-ray.y); // find the floor
        th += step(th,0.)*INFINI;

        vec4 vox = voxInfo(p.xz); // get voxel info: center and size
        float H = Hsh2(floor(100.*vox.xy));

        vec3 normsph = vec3(0.); // Little dome
        float ts = INFINI;
        if(bool(step(H,.6)) && t<150.){
        ts = sphereImpact(p, ray, vec3(vox.x,h-.5,vox.y), H*min(vox.z,vox.w), normsph );
        }

        vec3 normcyl = vec3(0.); // Pipe
        float tc = INFINI;
        if(bool(step(H,.2)) && t<100.){
            vec2 c = vox.xy+ (4.*H-.4)*vox.zw;
            float r = .025*min(vox.z,vox.w);
            float top = 2.5*H*TOP_SURFACE;
            tc = cylinderImpact(p.xz, ray.xz, c, r, normcyl.xz );
            tc += step(top,p.y+tc*ray.y)*INFINI;

            float Hc = (H-.15)*20.;
        float ti = iTime*.4;
            // Flam calculation
        if(bool(step(.15,H)*step(.95,Hsh(.0001*(vox.x+vox.y)*floor(Hc+ti))) )){
                float fti = fract(Hc+ti);
                vec2 len = c-pos.xz;
                float h = length(len)*ray.y/length(ray.xz)+pos.y;
                float dh = h - top;
                float d = abs(ray.z*len.x - ray.x*len.y);
                float mvt = 1.+cos(5.*dh);
                flam.rgb += min(1.,min(1.,min(vox.z,vox.w))*.2*mvt*(r+dh)/d-.1)
                       *step(0.,dh)
                       *((.8-abs(fti-.5))/(dh+.2) -.3 )
                       *texture(nomip_organic_jpg,vec2(.2*h-.5*ti+Hc,d*(1.+fti)*dh*mvt+Hc)).rgb;
                flam*=flam*(2.-fti);
                flam.w = t;
            }
        }


        tt = min(min(ts,th),tc);
        tt = min(wall.w,tt); // keep the min between floor and wall distance
        if(tt==th) return vec4(0.,1.,0.,t+tt); // if first hit = floor return hit info (floor)
        else if(tt==ts){hitObj = SPH; return vec4(normsph,t+tt);}
        else if(tt==tc){hitObj = CYL; return vec4(normcyl,t+tt);}
        else tt = wall.w; // else keep the local t parameter to the next wall

        t+= tt+.00001; // update global t and do again
        if(t>250.) break; // not necessary to go too far (perfos)
    }


    return vec4(0.,0.,0.,INFINI);
}

vec4 traceBis(in vec3 pos, in vec3 ray)
{
    float dh = 0.;
    float t = 0.;

    if(pos.y > TOP_SURFACE){ // navigating directly to the top surface (perfos)
        if(ray.y >= 0.) return vec4(vec3(0.),INFINI);
t = (TOP_SURFACE - pos.y)/ray.y + 0.00001;
    }

    vec4 wall = vec4(0.); // wall.xyz is the normal of the wall. wall.w is the t parameter.

    for(int i = 0;i<MAXSTEP;i++){ // entering the voxel run

        vec3 p = pos+t*ray;
        if(p.y > TOP_SURFACE) break; // when "looking" up, you may fly out before hiting
        // break immediately (perfos)

        wall = getNextPlanBis(p.xz,ray.xz); // find the next wall

        vec4 vox = voxInfoBis(p.xz);
        vec3 normsph;
        float radius = 25.;//.5*min(vox.z,vox.w);
        float tt = sphereImpact(p, ray, vec3(vox.x,TOP_SURFACE-radius-1.,vox.y), radius , normsph );

        if(tt<INFINI) return vec4(normsph,t+tt);
        else tt = wall.w; // else keep the local t parameter to the next wall

        t+= tt+.00001; // update global t and do again
        if(t>250.) break; // not necessary to go too far (perfos)
    }


    return vec4(0.,0.,0.,INFINI);
}


float mapGnd(in vec3 p){return .5*texture(nomip_organic_jpg, GS*p.xz).r +.2*texture(nomip_organic_jpg, 2.*GS*p.xz).r;}

vec4 traceGround(in vec3 pos, in vec3 ray)
{
if(ray.y>0.) return vec4(0.,0.,0.,INFINI);

    float t = (mapGnd(pos) - pos.y)/ray.y;

    for(int i = 0;i<MAXSTEP;i++){

        vec3 p = pos+t*ray;
        float dh = p.y-mapGnd(p);

        if(abs(dh) < .003){
vec2 e = vec2(-.2,.2);
vec3 norm = normalize(e.yxx*mapGnd(p + e.yxx) + e.xxy*mapGnd(p + e.xxy) +
         e.xyx*mapGnd(p + e.xyx) + e.yyy*mapGnd(p + e.yyy) );

            return vec4(norm,t);
        }

        t += dh;

        if(t>250.) break;
    }

    return vec4(0.,0.,0.,INFINI);
}


vec4 boxImpact( in vec3 pos, in vec3 ray, in vec3 ctr, in vec3 dim)
{
    vec3 m = 1.0/ray;
    vec3 n = m*(ctr-pos);
    vec3 k = abs(m)*dim;

    vec3 t1 = n - k;
    vec3 t2 = n + k;

float tmax = max( max( t1.x, t1.y ), t1.z );
float tmin = min( min( t2.x, t2.y ), t2.z );

if( tmax > tmin || tmin < 0.0) return vec4(vec3(0.),INFINI);

    vec3 norm = -sign(ray)*step(t2, vec3(tmin));
    return vec4(norm, tmin);
}


bool checkWindow(in vec3 ctr){
    float hash = Hsh2(ctr.xz+ctr.yy);
    float a = step(.4,hash)*step(mod(ctr.y,10.),0.);
    float b = step(.7,hash)*step(mod(ctr.y-1.,10.),0.);
    return bool(a+b);
}

vec4 traceWindow(in vec3 pos, in vec3 ray, in float t, in vec3 norm){
    float d, sh, sv;
    if(hitObj == SPHBIS){d=.03; sh=2.5; sv=1.;}
    else if(hitObj == SPH){d=.03; sh=.5; sv=.75;}
    else if(hitObj == CYL){d=.01; sh=.1; sv= 1.;}
    else {d=.1; sh=1.; sv=1.;}

    vec3 p = pos + t*ray;
    vec4 info = vec4(norm,t);

    vec3 boxDim = vec3(sh*.25,sv*.025,sh*.25);
vec3 boxCtr;

    for(int i=0; i<5; i++){
    boxCtr = vec3(floor(p.x*2./sh),floor(p.y*20./sv),floor(p.z*2./sh));
        if(checkWindow(boxCtr)){
            SIDEWIN = true;
            float tf = t + d/dot(ray,-norm);
            info = boxImpact(pos, ray, (boxCtr+.5)*vec3(sh*.5,sv*.05,sh*.5), boxDim);
            if(tf < info.w){
                WINDOW = true;
                info = vec4(norm,tf);
                break;
            }
            p = pos + (info.w+.001)*ray;
        }
        else break;
    }
    return info;
}

vec3 starGlow(in vec3 ray, in float a){
    vec3 col = vec3(.001/(1.0001-a));
    return col;
}

vec3 moonGlow(in vec3 ray, in float a){
    float dl = dot(moonRefl,ray);
    float moon = smoothstep(.9,.93,a);
    float shad = 1.-smoothstep(.7,.9,dot(moonShad, ray));
    float refl = .001/(1.0013-dl);
float clouds = .5*texture(nomip_organic_jpg,ray.xy).r+.3*texture(nomip_organic_jpg,3.*ray.xy).r;
    vec3 col = .8*(vec3(.5,.3,.0)+clouds*vec3(.3,.4,.1))*moon+vec3(1.,1.,.7)*refl;
    col += vec3(.3,.5,.8)*smoothstep(.89,.90,a)*(1.-smoothstep(.89,.99,a))*(dl-.9)*15.;
col *= shad;
    col -= vec3(.1,.3,.6)*(1.-moon*shad);
    col = clamp(col,0.,1.);
    return col;
}

vec3 stars(in vec3 ray){
    vec3 col = vec3(0.);
    float az = atan(.5*ray.z,-.5*ray.x)/PIdiv2;
    vec2 a = vec2(az,ray.y);

    float gr = -.5+a.x+a.y;
    float milky = 1.-smoothstep(0.,1.2,abs(gr));
float nebu = 1.-smoothstep(0.,.7,abs(gr));

    vec3 tex = texture(nomip_organic_jpg,a+.3).rgb;
    vec3 tex2 = texture(nomip_organic_jpg,a*.1).rgb;
vec3 tex3 = texture(nomip_organic_jpg,a*5.).rgb;
float dark = 1.-smoothstep(0.,.3*tex.r,abs(gr));

    vec2 dty =a*12.;
    col += step(.85,Hsh2(floor(dty)))*(tex+vec3(.0,.1,.1))*max(0.,(.01/length(fract(dty)-.5)-.05));

    dty =a*30.;
    col += step(.8,Hsh2(floor(dty)))*tex*max(0.,(.01/length(fract(dty)-.5)-.05))*milky;

    dty =a*1000.;
    col += max(0.,Hsh2(floor(dty))-.9)*3.*tex3*milky;

    col += (.075+.7*smoothstep(.1,1.,(tex+vec3(.15,0.,0.))*.3))*nebu;
    col += .5*smoothstep(0.,1.,(tex2+vec3(0.,.2,.2))*.2)*milky;
col -= .15*(tex3 * dark);

    return col;
}

vec3 fewStars(in vec3 ray){
vec3 col = vec3(0.);
    float az = atan(.5*ray.z,-.5*ray.x)/PIdiv2;
    vec2 a = vec2(az,ray.y);

    vec3 tex = texture(nomip_organic_jpg,a+.3).rgb;
    vec2 dty =a*14.;
    col += step(.85,Hsh2(floor(dty)))*(tex+vec3(.0,.1,.1))*max(0.,(.01/length(fract(dty)-.5)-.05));

    return col;
}

bool shadTrace(in vec3 pos, in vec3 v){
float dh = 0.;
    float t = 0.;
    vec4 wall = vec4(0.);

    for(int i = 0;i<10;i++){
        vec3 p = pos + t*v;
        if(p.y > TOP_SURFACE) break;

        float h = map(p.xz);
        float dh = p.y - h;
        if(dh<.0) return true;

        vec4 vox = voxInfo(p.xz);
        float H = Hsh2(floor(100.*vox.xy));
        vec3 normsph;
        float ts = sphereImpact(p, v, vec3(vox.x,h-.5,vox.y), step(H,.6)*H*min(vox.z,vox.w), normsph );
        if(ts<INFINI) return true;

        vec3 normcyl = vec3(0.);
        float tc = cylinderImpact(p.xz, v.xz, vec2(vox.x,vox.y)+ (4.*H-.4)*vox.zw, .025*min(vox.z,vox.w), normcyl.xz );
        tc += step(step(H,.2)*2.5*H*TOP_SURFACE,p.y+tc*v.y)*INFINI;
        if(tc<INFINI) return true;

        wall = getNextPlan(p.xz,v.xz);
        t+= wall.w + .0001 ;
    }
    return false;
}

bool shadTraceBis(in vec3 pos, in vec3 v){
float dh = 0.;
    float t = 0.;
    vec4 wall = vec4(0.);

    for(int i = 0;i<10;i++){
        vec3 p = pos + t*v;
        if(p.y > TOP_SURFACE) break;

        vec4 vox = voxInfoBis(p.xz);
        vec3 normsph;
        float radius = 25.;
        float ts = sphereImpact(p, v, vec3(vox.x,TOP_SURFACE-radius-1.,vox.y), radius , normsph );
        if(ts<INFINI) return true;

        wall = getNextPlanBis(p.xz,v.xz);
        t+= wall.w + .0001 ;
    }
    return false;
}

float shadow(in vec3 p){
    p += .00001*starLight;
    if(shadTrace(p,starLight)) return .1;
    if(shadTraceBis(p,starLight)) return .1;
    return 1.;
}

vec3 winGlow(in vec2 uv){
    uv.x *= .2;
    uv.y *= .5;
    vec2 k1 = (uv-.05*sin(uv*10.))*10.,
         k2 = (uv-.02*sin(uv*25.))*25.,
         k3 = (uv-.01*sin(uv*50.))*50.;


    vec2 p = floor(k1)/10.,
         q = floor(k2)/25.,
    s = floor(k3)/50.;

    vec2 bp = abs(fract(k1)-.5)
    + abs(fract(k2)-.5)
    + abs(fract(k3)-.5);
    bp /= 1.5;
    bp*=bp*bp;

    vec3 tex = texture(nomip_cloth_jpg,p).rgb
    + texture(nomip_cloth_jpg,q).rgb
    + texture(nomip_cloth_jpg,s).rgb;

    tex += .5*(bp.x+bp.y);
    tex *= smoothstep(1.,2.8,tex.r);

return tex;
}


float metalPlate(in vec2 st){
    float coef = 0.;

    vec2 p = floor(st);
    float hp = Hsh2(p*0.543234); hp *= step(.2,abs(hp-.5));
    vec2 fp = fract(st)-.5;
    vec2 sfp = smoothstep(.475,.5,abs(fp));

    st *= vec2(.5,1.);
    vec2 q = floor(st*4.-.25);
    float hq = Hsh2(q*0.890976); hq *= step(.35,abs(hq-.5));
    vec2 fq = fract(st*4.-.25)-.5;
    vec2 sfq = smoothstep(.45,.5,abs(fq));

    st *= vec2(5.,.1);
    vec2 r = floor(st*8.-.25);
    float hr = Hsh2(r*0.123456); hr *= step(.47,abs(hr-.5));
    vec2 fr = fract(st*8.-.25)-.5;
    vec2 sfr = smoothstep(.4,.5,abs(fr));

    float h = max(max(hp,hq),hr);
    if(bool(h)){
        vec2 plate =    step(h,hp)*sfp*sign(fp)
                      + step(h,hq)*sfq*sign(fq)
                      + step(h,hr)*sfr*sign(fr);

        coef += .2*h+.8;
        coef += .5*min(1.,plate.x+plate.y);
    }
    else coef = 1.;

    return coef;
}


float flare(in vec3 ref, in vec3 ctr){
    float c = 0.;
    vec3
s = normalize(ref);
    float sc = dot(s,-starLight);
    c += .6*smoothstep(.9995,1.,sc);

    s = normalize(ref+.9*ctr);
    sc = dot(s,-starLight);
    c += .7*smoothstep(.99,1.,sc);

    s = normalize(ref-.7*ctr);
    sc = dot(s,-starLight);
    c += .2*smoothstep(.7,1.,sc);

    return c;
}

vec3 lensflare3D(in vec3 ray, in vec3 ctr)
{
    vec3 red = vec3(1.,.6,.3);
    vec3 green = vec3(.6,1.,.6);
    vec3 blue = vec3(.6,.3,.6);
vec3 col = vec3(0.);
    vec3 ref = reflect(ray,ctr);

    col += red*flare(ref,ctr);
    col += green*flare(ref-.07*ctr,ctr);
    col += blue*flare(ref-.14*ctr,ctr);

    ref = reflect(ctr,ray);
    col += red*flare(ref,ctr);
    col += green*flare(ref+.07*ctr,ctr);
    col += blue*flare(ref+.14*ctr,ctr);

    float d = dot(ctr,starLight);
return .4*col*max(0.,d*d*d*d*d);
}

vec3 lava(in vec2 p){
float tex = abs(texture(nomip_organic_jpg,p*.05).r-.5+.3*sin(iTime*.2));
    vec3 lav = vec3(0.);
    lav.r += .5*(1.-smoothstep(.0,.2,tex));
    lav.rg += (1.-smoothstep(.0,.02,tex));
return lav;
}

vec3 getCamPos(in vec3 camTarget){
    float rau = 15.,
            alpha = iMouse.x/iResolution.x*4.*PI,
            theta = iMouse.y/iResolution.y*PI+(PI/2.0001);

            // to start shader
    if (iMouse.xy == vec2(0.)){
                float ts = smoothstep(18.,22.,iTime)*(iTime-20.);
                alpha = iTime*.04;
                theta = .3*(1.-cos(iTime*.1));
            }
    return rau*vec3(-cos(theta)*sin(alpha),sin(theta),cos(theta)*cos(alpha))+camTarget;
}

vec3 getRay(in vec2 st, in vec3 pos, in vec3 camTarget){
    float focal = 1.;
    vec3 ww = normalize( camTarget - pos);
    vec3 uu = normalize( cross(ww,vec3(0.0,1.0,0.0)) ) ;
    vec3 vv = cross(uu,ww);
// create view ray
return normalize( st.x*uu + st.y*vv + focal*ww );
}

// 2 functions from Shane
// the famous "Old Nvidia tutorial"!
vec3 tex3D( sampler2D tex, in vec3 p, in vec3 n ){

    n = max((abs(n) - 0.2)*7., 0.001);
    n /= (n.x + n.y + n.z );
vec3 tx = (texture(tex, p.yz)*n.x + texture(tex, p.zx)*n.y + texture(tex, p.xy)*n.z).xyz;
    return tx*tx;
}

vec3 texBump( sampler2D tx, in vec3 p, in vec3 n, float bf, in float t, in vec3 ray){
    //const vec2 e = vec2(0.001, 0);
    vec2 e = vec2(.2*t/iResolution.x/dot(-ray,n),0.);    // AA purpose
    //vec2 e = vec2(.5*t/iResolution.x,0.);
    mat3 m = mat3( tex3D(tx, p - e.xyy, n), tex3D(tx, p - e.yxy, n), tex3D(tx, p - e.yyx, n));
    vec3 g = vec3(0.299, 0.587, 0.114)*m;
    g = (g - dot(tex3D(tx,  p , n), vec3(0.299, 0.587, 0.114)) )/e.x; g -= n*dot(n, g);
    return normalize( n + g*bf );
}


void main(){
    vec2 st = ( gl_FragCoord.xy
               //-.5*vec2(mod(gl_FragCoord.y,2.),mod(gl_FragCoord.x,2.))
               - .5*iResolution.xy ) / iResolution.y;

    // camera def
    vec3 camTarget = vec3(100.*sin(iTime*.01),1.,-60.*sin(iTime*.015));

    vec3 pos = getCamPos(camTarget);

    pos.y = max(pos.y,1.5*gndFactor(pos.xz)+1.); // Cam anti-collision

    vec3 ray = getRay(st, pos,camTarget);

    float moonArea = dot(ray,moonCtr);
    float starArea = dot(ray,starLight);
    bool starside = bool(step(0.,starArea));
    bool moonside = bool(step(0.,moonArea));

    vec3 color = vec3(.0);
    vec4 flamInfo = vec4(0.);
    float t = INFINI;
    vec3 norm = vec3(0.);

    vec4 info = trace(pos, ray, flamInfo);
    float sc = hitScale;
    t = info.w;
    norm = info.xyz;

    info = traceBis(pos, ray);
    if(info.w < t){
        t=info.w;
        norm = info.xyz;
        hitObj = SPHBIS;
  if(flamInfo.w > t) flamInfo.rgb = vec3(0.);
    }

    info = traceGround(pos,ray);
    if(info.w < t){
        t=info.w;
        norm = info.xyz;
        hitObj = GND;
    }

    float shadow = shadow(pos+t*ray);

    if(t==INFINI){
        float moonMask = 1.-smoothstep(.925,.93,moonArea);
        float starMask = 1.-smoothstep(.4,.9,starArea);
        if(starside) color += .7*starGlow(ray,starArea);
        if(moonside) color += moonGlow(ray,moonArea);

        color += fewStars(ray)*moonMask*starMask;
        color += stars(ray)*moonMask*starMask;
        color *= min(1.,abs(10.*ray.y*ray.y));
        color += .006/(ray.y*ray.y+.015)*DUST;
    }
    else{
        if(norm.y < .99 && hitObj != GND) {
            info = traceWindow(pos ,ray, t, norm);
            if(bool(info.w)) {
                norm = info.xyz;
                t = info.w;
            }
        }

        vec3 p = pos + t*ray;

        if(hitObj == SPH){
            if(WINDOW){
                vec2 d = p.xz - voxInfo(p.xz).xy;
                vec3 window = winGlow(vec2(.5*atan(d.x,d.y),.8*length(d)));
                vec3 refl = reflect(ray,norm);
                color += smoothstep(.95,1.,dot(starLight,refl))*norm.z*step(1.,shadow);
                color += window*min(1., 30./t);
        }
            else{
                vec2 ang;
                if(SIDEWIN) ang = p.xz;
                else ang = vec2(atan(norm.x,norm.z), atan(norm.y,length(norm.xz)));
                color += texture(nomip_metal_jpg,ang).rgb;
                color *= metalPlate(4.*ang);
                color += .015*vec3(.5*sc,abs(sc-4.),8.-sc) * min(1.,10./t);
                norm = texBump( nomip_organic_jpg,.2*norm, norm, .005, t, ray);
                color *= max(dot(norm, starLight),.0);
                if(SIDEWIN) color += vec3(.1,.05,.0);
                else color *= shadow;
            }
        }
        else if(hitObj == CYL){
            if(WINDOW){
                vec3 window = winGlow(2.*p.zy);
                vec3 refl = reflect(ray,norm);
                color += smoothstep(.95,1.,dot(starLight,refl))*norm.z*step(1.,shadow);
                color += window*min(1., 30./t);
        }
            else{
                vec2 ang;
                if(SIDEWIN) ang = p.xz;
                else ang = vec2(atan(norm.x,norm.z), 2.*p.y);
                color += texture(nomip_metal_jpg,ang).rgb;
                color *= metalPlate(2.*ang);
                color += .015*vec3(.5*sc,abs(sc-4.),8.-sc) * min(1.,10./t);
                color *= max(dot(norm, starLight),.0);
                if(SIDEWIN) color += vec3(.1,.05,.0);
                else color *= shadow;
            }
        }
        else if(hitObj == SPHBIS){
            if(WINDOW){
                vec2 d = p.xz - voxInfoBis(p.xz).xy;
                vec3 window = .5*winGlow(vec2(3.*atan(d.x,d.y),.25*length(d)));
                vec3 refl = reflect(ray,norm);
                color += smoothstep(.95,1.,dot(starLight,refl))*norm.z*step(1.,shadow);
                color += window*min(1., 30./t);
        }
            else{
                vec2 ang;
                if(SIDEWIN) ang = .5*p.xz;
                else ang = vec2(atan(norm.x,norm.z), atan(norm.y,length(norm.xz)));
                color += texture(nomip_metal_jpg,ang).rgb;
                color *= metalPlate(4.*ang);
                sc =1.;
                color += .015*vec3(.5*sc,abs(sc-4.),8.-sc) * min(1.,10./t);
                norm = texBump( nomip_organic_jpg,2.*norm, norm, .002, t, ray);
                color *= max(dot(norm, starLight),.0);
                if(SIDEWIN) color += vec3(.1,.05,.0);
                else color *= shadow;

            }
        }
        else if(hitObj == GND){
            vec3 dirt = texture(nomip_organic_jpg,GS*p.xz).rgb;
            color = 1.5*p.y*dirt*dirt;

            color *= max(0.,dot(norm, -starLight));
            color *= shadow;

            vec2 e = t/iResolution.x/ray.y*ray.xz; // 2 lines for AA purpose
            vec3 lavaCol = (lava(p.xz)+lava(p.xz+e)+lava(p.xz-e))/3.;

color += .8*lavaCol*(1.-smoothstep(.0,.1,dirt.r));
        }
        else{
            if(p.y <.01) color = vec3(0.);
            else{
                if(WINDOW){
                    vec3 window = winGlow( (p.xy+p.z)*norm.z + (p.zy+p.x)*norm.x);
                    vec3 refl = reflect(ray,norm);
                    color += smoothstep(.95,1.,dot(starLight,refl))*norm.z*step(1.,shadow);
                    color += window*min(1., 30./t);
                }
                else{
                    vec2 side = .5*vec2(p.x,-p.z)*norm.y + .5*vec2(-p.x,-p.y)*norm.z + .5*vec2(p.y,-p.z)*norm.x;
                    color += texture(nomip_metal_jpg,side).rgb;

                    vec2 e = vec2(2.*t/iResolution.x/dot(-ray,norm),0.); // 2 lines for AA purpose
                    float mp =  ( metalPlate(4.*side)
                            + metalPlate(4.*side+e)
                        + metalPlate(4.*side-e)
                        + metalPlate(4.*side+e.yx)
                        + metalPlate(4.*side-e.yx)) /5.;

                    color *= mp;
                    color += .015*vec3(.5*sc,abs(sc-4.),8.-sc) * min(1.,10./t);

                    norm = texBump( nomip_organic_jpg, .2*p, norm, .003, t, ray);

                    color *= clamp(dot(norm, starLight)+.2,.3,1.);
                    if(SIDEWIN) color += vec3(.1,.05,.0);
                    else color *= shadow;

                    vec3 refl = reflect(ray,norm);
                    color += .3*smoothstep(.9,1.,dot(starLight,refl))*norm.z*step(1.,shadow);;
                    color = clamp(color,0.,1.);
                }
            }
        }
        color *= min(1., 20./t);
        color += min(.003*t,.35)*DUST;
    }

    color += flamInfo.rgb*flamInfo.rgb;

    if(starside)
    //if(!shadTrace(pos,starLight))
    color += lensflare3D(ray, getRay(vec2(0.), pos,camTarget));

gl_FragColor = vec4(1.5*color,1.);
}
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 09:51:10 pm
Did you checked the latest OR code changes?

Thank you very much for the I'veSeen.fs fix, it looks great!
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 09:53:13 pm
Not yet. I'll do it early in the morning when I'm going to have my usual insomnia. ;)

Are you satisfied with the fixed shader?
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 09:59:22 pm
See my previous answer (cross posting)  :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 14, 2019, 11:03:32 pm
Sanctuary revisited, altogether with visible light animation  :o
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 14, 2019, 11:21:58 pm
Do you mean shader colors are affected by model colors?!  :o
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 15, 2019, 03:13:19 am
Re. your modes: I added them all. What they really do is remove duplicate calls to shader reset because it is done at new shader parse time anyway.

Your fixes did not however cure listview focus repositioning. What did cure it was, in case WM_NOTIFY of WndProc() somewhere near line 3045, adding a forced redraw of listview control:

........
                    } else {
                        Path_Combine(gP.mt.FullName, EXEresource(), zTxt);
                        if (ZI_UpdateNamedGLTextureFromFileEx(gP.mt.FullName, gP.mt.Texture, gP.mt.Square) == 0) {
                            Mobj_setWallPaper(gP.mt.FullName);
                            WindowRedraw(hCtrl); // MLL: 12-15-2019
                            gP.bRedraw = TRUE; // Redraw the OpenGL scene
                        }
                    }
                }
            }
        } else {
........


And one last thing. Earlier I could D&D my monkey directly into non-default static or animated backgrounds without resetting them to default. Now it is impossible; the background is always changed to static default unless otherwise specified in the model's MTL file. Okay, I can live with that.

But now if you D&D an audio file into an empty viewport, you can't get rid of that audio for good even if you Close all and clear scene. You can only shut it up temporarily with the audio checkbox. So, I've made gl_CloseAll() unconditional on clicking the Close all... menu. Now I can shoot that audio dead together with background animation (if any) when the viewport is still empty: (see ProcessMenu() somewhere near line 2040)

    case MENU_FILE_CLOSE: // MLL 12-20-2018:
        /*if (gP.bObjectLoaded)*/ { // MLL: 12-15-2019
            gl_CloseAll();
            HWND hCtrl = GetDlgItem(gP.hMain, IDC_AUDIO);        // PAT: 12-03-2019
            if (IsWindow(hCtrl)) {
                SendMessage(hCtrl, BM_SETCHECK, BST_UNCHECKED, 0);
                EnableWindow(hCtrl, FALSE);
            }
            hCtrl = GetDlgItem(gP.hMain, IDC_GAUGE_VOLUME);      // PAT: 12-05-2019
            if (IsWindow(hCtrl)) { EnableWindow(hCtrl, FALSE); } // PAT: 12-05-2019
        }
        break;


Now we can consider OR more or less compatible with Win 7. Congrats! :D
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 15, 2019, 09:50:50 am
The original OR version was using ListBox rather than ListView, that is a much more complex control, and the reason why we have to fight against the slow priority of the WM_PAINT message with WindowRedraw, especially when dealing with the high priority of the OpenGL animations.

Right now, i am looking into glsl_LoadShaderFromFile to let a @local shader work with local textures rather than L"Animated\\
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 15, 2019, 12:33:29 pm
Patrice,

I think you should rather add one more "sister" function, say, glsl_LoadLocalShaderFromFile(), probably even with somewhat duplicate code, to load @local shaders -- rather than obscure, bloat and slow down the existing glsl_LoadShaderFromFile() function.

In fact, in my source code, the function you're working with is currently called glsl_LoadBkgndShaderFromFile() as opposed to glsl_LoadShaderFromFile() that's reserved exclusively for the blazing fast loading of "system" shaders such as the ones used for post-processing (brightness/contrast, hue/saturation, sepia, vibrance, and vignette ATM).

I'm very proud of speeds we've been able to achieve so far in our indie product, and I think we wouldn't want to slow it down unnecessarily with excessive branching in over-complicated functions. E.g. it takes ShaderToy/my Firefox/WebGL 2.0 4.7 seconds to recompile the I'veSeen shader while it takes ObjReader as little as 0.125 seconds only to reparse all its sampler2d names and recompile it once its name is clicked in the listview. That's almost 40 times faster! ;)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 15, 2019, 02:30:16 pm
The changes i am doing won't impact the loading speed at all.

Just changing the path to the model folder rather than OR's Animated folder when using
#wallpaper @shader.fs

Added:
Problem solved, now i can do what i want, and load the specific .fs texture from the model folder.
This allows me to provide a new .fs animation altogether with the model, even if it is not already available in the default OR's Animated folder.

Attachments
ObjReader64.7z (a copy of my binary file)
planar.7z (an example of local shader animation using a local texture)

Syncing
in shaders.h, near line 177
            if (p = strstr(samplerMap, "_")) // replace '_' with '.' to get valid map file name
                *p = '.';

            if (wcsstr(fName, L"\\")) { // PAT: 12-15-2019
                Path_Combine(wTmp, gP.wModelPath, cswconv(samplerMap));
            } else {
                Path_Combine(wTmp, EXEresource(), L"Animated\\");
                Add_Str(wTmp, cswconv(samplerMap));
            }

            if (Mobj_createGlTextureFromFileEX(wTmp, X, Y, lpArray, TEX_REPEAT)) {


in Main.cpp, near line 1957

        if (nCount) {
            LVFINDINFO lvfi = { 0 };
            lvfi.flags = LVFI_STRING;
            //lvfi.psz = L"voronoi.fs"; // PAT: 11-25-2019

            if (wcsstr(fName, L"\\") == 0) { // PAT: 12-15-2019
                lvfi.psz = fName;
                long nFound = ListView_FindItem(hList, -1, &lvfi);
                if (nFound < 0)
                    nFound = 0;
                ListView_SelectPlus(hList, nFound);
            }

            SendMessage(hList, WM_SETREDRAW, TRUE, 0);
            RedrawWindow(hList, NULL, NULL, // this combination of flags seems to do the trick
                RDW_INVALIDATE | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN | RDW_UPDATENOW);


Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 15, 2019, 09:10:31 pm
Oh Patrice,

This IS really cool!  :o 8)

Quote
... specific .fs texture ...
You mean, specific .fs shader?

This .mp3 audio is very hissy, especially in the left channel... Any other, preferably lossless, format available? (I have an E-MU 24-bit 192KHz audio card attached to an 80W Sharp hi-fi stereo setup with 9-band equalization)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 15, 2019, 09:35:54 pm
Patrice,

In this Sanctuary.fs, line 32, make the following change:

    float floorr = p.y + 0.25;

This will lift the camera a bit so that the statue's feet at its default size will always fit in the well it's flying over. :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 15, 2019, 09:44:24 pm
Very good, thank you!
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 15, 2019, 09:47:42 pm
I'm glad to help! :D

No, Uncertain-Future is much better than Titan-Powerplant (there's a typo in the name). It's a pity there's so much hiss in the recording... :-[
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 15, 2019, 09:58:22 pm
Try also with that one
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 15, 2019, 10:02:03 pm
(https://pbs.twimg.com/profile_images/551268783307124736/u4n5m9rR_400x400.jpeg)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 15, 2019, 10:14:57 pm
Then try that one, from the song of the distant earth...
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 15, 2019, 11:16:51 pm
This one is nice but associates with something more material. ;)

Volga Boatmen
(http://tutmoidom.ru/galereya/images/repin_burlaki_692_350.jpg)

and their song: (pulling the ropes to haul a barge)
https://www.youtube.com/watch?v=RiSpp6ml5xY (https://www.youtube.com/watch?v=RiSpp6ml5xY)

;D
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 16, 2019, 01:20:01 pm
My friend

Here is a link to free audio resources
https://soundimage.org/sci-fi-2/

and i have attached a sound track to use with Tokyo.fs


BTW we need a new global meta to adjust the zoom at startup.
#zoom xx
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 16, 2019, 04:46:04 pm
About #Zoom
do you think we could use something like this when loading a new model
        CAMERA_FOVY = 20.0f * 0.8f; // Zoom 20% bigger
        CAMERA_OFFZ = 3.05f * 0.8f; // Zoom 20% bigger
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
        gl_AdjustNearPlane(); gl_Resize(); // recalc gP.glZNEAR and apply it
        zeroCamera();
        gP.bRedraw = TRUE; gl_DrawScene(); // redraw immediately


Translation could be usefull as well ;)

these are meant to be used with shader animation
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 16, 2019, 05:15:25 pm
0. Thank you very much for the link! Audio pieces are very good. So, the hiss in Uncertain-Future.mp3 is intentional; it's some sort of hi-freq noise but I still don't like it. Below is another piece that I think could fit Planar best of all.

1. No, we should save both camera positional data for the camera and target and rotational data for the model because they are all interrelated; 9 floating values all in all. They will satisfy both our Animate reset and gl_DrawScene procedures. I will think of, and experiment on, how to implement it through a menu element similar to our Save lighting to mtl file.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 16, 2019, 06:23:11 pm
Abyss

Using a reworked version of the galaxy_trip.fs...


Quote
I will think of, and experiment on, how to implement it through a menu element similar to our Save lighting to mtl file.
That would be nice, thank you!
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 16, 2019, 07:49:40 pm
Cool! :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 17, 2019, 05:11:06 pm
I would like to setup the location at startup, like on the attached screen shot.

See also the attached Tokyo project for test purpose.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 17, 2019, 06:40:59 pm
To me, this HUD gives no idea of rotation even if it isn't a billboard. I think it will be better to position/rotate the real model directly.

I'm working on adding this feature now in response to a Save pose to mtl file click, specifically on ways to add a new meta #pose to a .MAT file that doesn't have it yet. The problem is that in a general case, the automatic positions of new global #metas in the file aren't defined or accessed clearly and easily, especially if they are to be in between the lights and newmtl's...
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 17, 2019, 07:56:42 pm
This HUD is not a real project, it is just a template/helper to adjust the screen size.

Save pose to mtl file will do exactly what is needed to setup the startup location, thank you!
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 17, 2019, 08:38:49 pm
Okay Patrice,

Here come the mods for model initial posing anywhere in the 3D viewport.

globals.h:

struct PROPM {
    BOOL  bHasPositions;
    BOOL  bHasTextureCoords;
    BOOL  bHasNormals;
    BOOL  bHasTangents;
    long  numberOfVertexCoords;
    long  numberOfTextureCoords;
    long  numberOfNormals;
    long  numberOfTriangles;
    long  numberOfMaterials;
    long  numberOfMeshes;
    long  numberOfTextures;
    float center[3];
    float pose[6];      // MLL 12-17-2019: model initial translational/rotational "pose" other than at [0,0,0]
    float rWidth;
    float rHeight;
    float rDepth;
    float rExtent;
};


constants.h near line 231:

........
// MLL 12-08-2018: FOV support
#define MENU_FOV_30             40068
#define MENU_FOV_45             40069
#define MENU_FOV_90             40070

// MLL 12-17-2019: pose support
#define MENU_SAVE_POSE          40071 // Note: put the number that actually follows MENU_FOV_90 in your code!!! (your constants may differ)
........


Main.cpp near line 985:

void zeroCamera() { // MLL 12-20-2018: immediate non-animated reset; 12-17-2019: #pose support
    gP.rTargetPos[0] = gM.center[0] + gM.pose[0];
    gP.rTargetPos[1] = gM.center[1] + gM.pose[1];
    gP.rTargetPos[2] = gM.center[2];

    gP.rCameraPos[0] = gP.rTargetPos[0] + gM.pose[0];
    gP.rCameraPos[1] = gP.rTargetPos[1] + gM.pose[1];
    gP.rCameraPos[2] = CAMERA_OFFZ + gM.pose[2];

    //gP.rPitch = gP.rYaw = gP.rRoll = 0.0f; // MLL 10-28-2018:
    gP.rPitch = gM.pose[3];
    gP.rYaw = gM.pose[4];
    gP.rRoll = gM.pose[5];
}


Main.cpp near line 2765:

........
    case MENU_SAVE_POSE:  // MLL 12-17-2019:
        if (gP.bObjectLoaded)
            Mobj_saveLight(TRUE); // this updates pose values only
        break;

    case MENU_SAVE_LIGHT: // PAT: 01-27-2018
........


Main.cpp in menu creation: (I have it as a separate sub)

........
    // PAT: 12-31-2018 avoid menu duplication (see View)
    //AppendMenu(hSaveMenu, MF_ENABLED, MENU_WALLPAPER, L"Take screenshot...");
    //AppendMenu(hSaveMenu, MF_ENABLED, MENU_PRINT, L"Send screenshot to printer...");
    //AppendMenu(hFileMenu, MF_POPUP, (UINT_PTR)hSaveMenu, L"Save scene as"); // e.g. after modification

    AppendMenu(hFileMenu, MF_SEPARATOR, 0, 0);
    AppendMenu(hFileMenu, MF_ENABLED, MENU_SAVE_POSE, L"Save pose to mtl file");
    AppendMenu(hFileMenu, MF_ENABLED, MENU_SAVE_LIGHT, L"Save lighting to mtl file");
    AppendMenu(hFileMenu, MF_SEPARATOR, 0, 0);
    AppendMenu(hFileMenu, MF_ENABLED, MENU_FILE_CLOSE, L"Close all and clear scene");
........
(much lower)
........
    AppendMenu(hLightsMenu, MF_ENABLED, MENU_LIGHTSETTING, L"Control panel\t[F2]");// L"Simplified light settings");
    //AppendMenu(hLightsMenu, MF_SEPARATOR, 0, 0);
    //AppendMenu(hLightsMenu, MF_ENABLED, MENU_SAVE_LIGHT, L"Save lighting to mtl file");
    AppendMenu(hLightsMenu, MF_SEPARATOR, 0, 0);
........


Mobj.h near line 905:

void Mobj_saveLight(IN BOOL poseOnly = FALSE) { // MLL 12-17-2019: #pose support
    if (gP.hMaterial) {
        long nCount = (long) SendMessageA(gP.hMaterial, LB_GETCOUNT, 0, 0);
        if (nCount > 1) {
            long nLen, nItem = 0;
            char szLine[MAX_PATH]; ClearMemory(szLine, sizeof(szLine));
            SendMessageA(gP.hMaterial, LB_GETTEXT, nItem, (LPARAM) szLine);

            // Create .bak file
            char szBak[MAX_PATH]; strcpy_s(szBak, szLine); nLen = lstrlenA(szBak) - 1;
            szBak[nLen] = 'k'; nLen--;
            szBak[nLen] = 'a'; nLen--;
            szBak[nLen] = 'b';
            CopyFileA(szLine, szBak, FALSE);

            FILE* pFile = NULL;
            if (poseOnly) { // MLL 12-17-2019: update #pose entry only
                BOOL hasPose = FALSE, hasLights = FALSE;
                FILE* pBak = fopen(szBak, "r");
                pFile = fopen(szLine, "w");
                if (pBak && pFile) {
                    memcpy(gM.pose, gP.rCameraPos, sizeof(float) * 3);
                    gM.pose[3] = gP.rPitch; gM.pose[4] = gP.rYaw; gM.pose[5] = gP.rRoll;
                    ClearMemory(szLine, sizeof(szLine));
                    while (fgets(szLine, MAX_PATH, pBak) != NULL) {
                        if (szLine[0] == '#') {
                            CharLowerA(szLine);
                            if (strstr(szLine, "#pose")) { // #pose found; insert new values
                                sprintf(szLine, "#pose %.2f %.2f %.2f %.2f %.2f %.2f\n", // better precision is imperceptible
                                    gM.pose[0], gM.pose[1], gM.pose[2], gM.pose[3], gM.pose[4], gM.pose[5]);
                                hasPose = TRUE;
                            }
                            else if (strstr(szLine, "#light"))
                                hasLights = TRUE;
                        }
                        fputs(szLine, pFile);
                    }
                    // MLL 12-17-2019: Not very elegant but working
                    if (!hasPose) { // #pose not found; insert new #pose meta
                        fseek(pBak, SEEK_SET, 0);
                        fseek(pFile, SEEK_SET, 0);
                        if (hasLights) {
                            int nLights = 0;
                            while ((fgets(szLine, MAX_PATH, pBak) != NULL)) { // skip #light metas
                                if (szLine[0] == '#') {
                                    CharLowerA(szLine);
                                    if (strstr(szLine, "#light")) {
                                        fputs(szLine, pFile);
                                        nLights++;
                                    }
                                    if (nLights == 12)
                                        break;
                                }
                            }
                        }
                        sprintf(szLine, "\n#pose %.2f %.2f %.2f %.2f %.2f %.2f\n", // add new #pose meta
                            gM.pose[0], gM.pose[1], gM.pose[2], gM.pose[3], gM.pose[4], gM.pose[5]);
                        fputs(szLine, pFile);
                        while ((fgets(szLine, MAX_PATH, pBak) != NULL)) // add all other remaining lines
                            fputs(szLine, pFile);
                    }
                    fclose(pBak);
                    fclose(pFile);
                }
            } else {
                pFile = fopen(szLine, "w");
                if (pFile) {
                    SaveLighting(pFile);
                    for (nItem = 1; nItem < nCount; nItem++) {
                        ClearMemory(szLine, sizeof(szLine));
                        SendMessageA(gP.hMaterial, LB_GETTEXT, nItem, (LPARAM)szLine);
                        if ((nItem == 1) && (szLine[0] == '\n')) { continue; }
                        fputs(szLine, pFile);
                    }
                    fclose(pFile);
                }
            }
            if (pFile)
                skDialogInfo($NULL, L"\nMaterial file updated successfully.", $NULL);
        }
    }
}


Mobj.h in Mobj_importMaterials():

(at the top)
........
    char fullPath[MAX_PATH] = { 0 };
    char s1[MAX_PATH] = { 0 }; char s2[32] = { 0 }; char s3[32] = { 0 }; // 10-09-2019 Bass.dll
    char s4[32], s5[32], s6[32]; // MLL 12-17-2019:
    HWND hCtrl = 0; // PAT: 11-05-2019
........
(lower in global #metas)
........
                } else if (strcmp(szBuffer, "#demo") == 0) {                // PAT: 11-02-2019 MODEL ROTATION
                    if (gP.bGiration == 0)
                        PutFocusOn(GetDlgItem(gP.hMain, IDC_DEMO_MODE));
                } else if (strcmp(szBuffer, "#pose") == 0) {                // MLL 12-17-2019: MODEL INITIAL POSE other than at [0,0,0]
                    fgets(szBuffer, sizeof(szBuffer), pFile);
                    s1[0] = s2[0] = s3[0] = s4[0] = s5[0] = s6[0] = 0;
                    sscanf(szBuffer, "%s %s %s %s %s %s", s1, s2, s3, s4, s5, s6);
                    gM.pose[0] = (float)atof(s1); gM.pose[1] = (float)atof(s2); gM.pose[2] = (float)atof(s3);
                    gM.pose[3] = (float)atof(s4); gM.pose[4] = (float)atof(s5); gM.pose[5] = (float)atof(s6);
                    printf("\nModel posed at translation %.1f %.1f %.1f, rotation %.1f %.1f %.1f\n\n",
                        gM.pose[0], gM.pose[1], gM.pose[2], gM.pose[3], gM.pose[4], gM.pose[5]);
                } else {
........

Renderers.h:

// MLL 12-20-2018: animate model position reset; MLL 02-07-2019: FPS-independent; 12-17-2019: #pose support
void lerpReset(IN BOOL start = FALSE) {
    static int frames, maxFrames; // render frames counter
    static float dtpX, dtpY; // target position deltas
    static float dcpX, dcpY, dcpZ; // camera position deltas
    static float drP, drY, drR; // camera rotation deltas
    static float frac;

    // Forward declarations
    void gl_AdjustNearPlane();
    void gl_Resize();
    void gl_DrawScene();
    void zeroCamera();

    if (start) {
        if (gP.rTargetPos[0] == gM.center[0] + gM.pose[0]     &&
            gP.rTargetPos[1] == gM.center[1] + gM.pose[1]     &&
            gP.rTargetPos[2] == gM.center[2]                  &&
            gP.rCameraPos[0] == gP.rTargetPos[0] + gM.pose[0] &&
            gP.rCameraPos[1] == gP.rTargetPos[1] + gM.pose[1] &&
            gP.rCameraPos[2] == CAMERA_OFFZ + gM.pose[2]      &&
            gP.rPitch == gM.pose[3]                           &&
            gP.rYaw == gM.pose[4]                             &&
            gP.rRoll == gM.pose[5]) {
            gP.bIsLerping = FALSE; // no need to lerp; already reset
            return;
        }

        frames = 0;
        maxFrames = (int)(gP.nFPS * 0.5f); // ca. half a second animation regardless of FPS
        frac = 1.0f / maxFrames;
        dtpX = (gP.rTargetPos[0] - gM.pose[0]) * frac;
        dcpX = (gP.rCameraPos[0] - gM.pose[0]) * frac;
        dtpY = (gP.rTargetPos[1] - gM.pose[1]) * frac;
        dcpY = (gP.rCameraPos[1] - gM.pose[1]) * frac;
        dcpZ = (gP.rCameraPos[2] - CAMERA_OFFZ - gM.pose[2]) * frac;
        drP = (gP.rPitch - gM.pose[3]) * frac; if (drP < 0.0f) drP = -drP;
        drY = (gP.rYaw - gM.pose[4]) * frac; if (drY < 0.0f) drY = -drY;
        drR = (gP.rRoll - gM.pose[5]) * frac; if (drR < 0.0f) drR = -drR;
        gP.bIsLerping = TRUE;
        return;
    }

    frames += 1;

    if (gP.bIsLerping) {
        if (frames == maxFrames) {
            zeroCamera();
            dtpX = dtpY = 0.0f;
            dcpX = dcpY = dcpZ = 0.0f;
            drP = drY = drR = 0.0f;
            frames = 0; frac = 0.0f;
            gP.bIsLerping = FALSE;
            gl_AdjustNearPlane();
            gl_Resize();
            return;
        }
    }

    if (dcpX != 0.0f + gM.pose[0]) {
        gP.rTargetPos[0] -= dtpX;
        gP.rCameraPos[0] -= dcpX;
    }
    if (dcpY != 0.0f + gM.pose[1]) {
        gP.rTargetPos[1] -= dtpY;
        gP.rCameraPos[1] -= dcpY;
    }
    if (dcpZ != (CAMERA_OFFZ + gM.pose[2]) * frac)
        gP.rCameraPos[2] -= dcpZ;
    if (drP != 0.0f + gM.pose[3])
        gP.rPitch -= drP;
    if (drY != 0.0f + gM.pose[4])
        gP.rYaw -= drY;
    if (drR != 0.0f + gM.pose[5])
        gP.rRoll -= drR;

    gl_AdjustNearPlane();
    gl_Resize();
}


My sources have different line numbering in many cases, so I can't be more precise. Those code pieces above that represent entire functions should replace the existing ones completely.

Please let me know if my mods are complete and work OK for you.

#pose'ing shouldn't be written manually. Prefer to use the menu after positioning/rotating the model in the viewport.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 17, 2019, 09:38:31 pm
Thanks for the changes you have done already

- Location/translation seems to work well
- But the Zoom factor is not saved/restored.

Indeed i want to retrieve the scene exactly in the same state it had when saved.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 17, 2019, 09:55:54 pm
What do you mean, "is not saved/restored"?! :o

The camera/model Z position is saved in gM.pose[2]. (3rd number in the #pose text)

Below is a snapshot of newly saved and reloaded arbitrary model...
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 17, 2019, 10:00:36 pm
Try to save the screen shot of my Tokyo example.

See the screen shot attached to this post
http://www.objreader.com/index.php?topic=197.msg5790#msg5790

Change the size of the model with the mouse wheel before saving.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 17, 2019, 10:28:52 pm
Change the size of the model with the mouse wheel before saving.

How else do you think I put the dragon in the position you're seeing in the above picture?! ::) ;D

Zooming out (minification with respect to [0,0,0]) seems to work while zooming in (magnification) doesn't.

I'll look into this tomorrow morning. I'm already quite tired for today.

See you in the morning!
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 17, 2019, 10:36:42 pm
Have a good night my friend!

See you tomorrow.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 18, 2019, 08:20:55 am
Patrice,

I'm going to have my landline serviced today. So it's highly probable that I'll be offline till late in the evening.

But I'll be fixing #pose zooming insomuch as my other work permits and I'll come back to you later in the evening with my progress. I'm sure I'll be able to cope with that problem.

See you, my friend, and take care!
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 22, 2019, 07:51:41 pm
Hi Patrice,

Try this:

globals.h:

struct PROPM {
    BOOL  bHasPositions;
    BOOL  bHasTextureCoords;
    BOOL  bHasNormals;
    BOOL  bHasTangents;
    long  numberOfVertexCoords;
    long  numberOfTextureCoords;
    long  numberOfNormals;
    long  numberOfTriangles;
    long  numberOfMaterials;
    long  numberOfMeshes;
    long  numberOfTextures;
    float center[3];
    float pose[9];      // MLL 12-17-2019: model initial target & camera translational/rotational "pose" other than at [0,0,0]
    float rWidth;
    float rHeight;
    float rDepth;
    float rExtent;
};


Main.cpp near line 985:

void zeroCamera() { // MLL 12-20-2018: immediate non-animated reset, 12-17-2019: #pose support
    if (gM.pose[3] == 0.0f && gM.pose[4] == 0.0f && gM.pose[5] == 0.0f) { // lazy check for non-posed model
        gP.rTargetPos[0] = gM.center[0];
        gP.rTargetPos[1] = gM.center[1];
        gP.rTargetPos[2] = gM.center[2];

        gP.rCameraPos[0] = gP.rTargetPos[0];
        gP.rCameraPos[1] = gP.rTargetPos[1];
        gP.rCameraPos[2] = CAMERA_OFFZ;

        gP.rPitch = gP.rYaw = gP.rRoll = 0.0f; // MLL 10-28-2018:
    }
    else {
        gP.rTargetPos[0] = gM.pose[0];
        gP.rTargetPos[1] = gM.pose[1];
        gP.rTargetPos[2] = gM.pose[2];

        gP.rCameraPos[0] = gM.pose[3];
        gP.rCameraPos[1] = gM.pose[4];
        gP.rCameraPos[2] = gM.pose[5] + CAMERA_OFFZ;

        gP.rPitch = gM.pose[6];
        gP.rYaw = gM.pose[7];
        gP.rRoll = gM.pose[8];
    }
}


Main.cpp in gl_LoadModel near line 1300:

........
    Mobj_setLightColor(); // PAT: 01-28-2018

    if (gP.bLerpReset) { // MLL 12-20-2018: reset animation support
        gP.rCameraPos[0] = gP.rCameraPos[1] = 0.0f; // MLL 12-17-2019: first appear from viewport exact center
        gP.rCameraPos[2] = 99.0f;
    }
    ResetCamera();
    gP.bRedraw = TRUE;
    gl_DrawScene();
........


Mobj.h near line 160:

void Mobj_initObjModel() {
    // Boolean flags
    gM.bHasPositions = FALSE;
    gM.bHasNormals = FALSE;
    gM.bHasTextureCoords = FALSE;
    gM.bHasTangents = FALSE;

    gM.numberOfVertexCoords = 0;
    gM.numberOfTextureCoords = 0;
    gM.numberOfNormals = 0;
    gM.numberOfTriangles = 0;
    gM.numberOfMaterials = 0;
    gM.numberOfMeshes = 0;
    gM.numberOfTextures = 0;

    gM.rWidth = 0.0f;
    gM.rHeight = 0.0f;
    gM.rDepth = 0.0f;
    gM.rExtent = 0.0f;

    gM.center[0] = 0.0f;
    gM.center[1] = 0.0f;
    gM.center[2] = 0.0f;

    // MLL 12-17-2019: #pose support
    gM.pose[0] = 0.0f;
    gM.pose[1] = 0.0f;
    gM.pose[2] = 0.0f;
    gM.pose[3] = 0.0f;
    gM.pose[4] = 0.0f;
    gM.pose[5] = 0.0f;
    gM.pose[6] = 0.0f;
    gM.pose[7] = 0.0f;
    gM.pose[8] = 0.0f;
}


Mobj.h near line 905:

void Mobj_saveLight(IN BOOL poseOnly = FALSE) { // MLL 12-17-2019: #pose support
    if (gP.hMaterial) {
        long nCount = (long) SendMessageA(gP.hMaterial, LB_GETCOUNT, 0, 0);
        if (nCount > 1) {
            long nLen, nItem = 0;
            char szLine[MAX_PATH]; ClearMemory(szLine, sizeof(szLine));
            SendMessageA(gP.hMaterial, LB_GETTEXT, nItem, (LPARAM) szLine);

            // Create .bak file
            char szBak[MAX_PATH]; strcpy_s(szBak, szLine); nLen = lstrlenA(szBak) - 1;
            szBak[nLen] = 'k'; nLen--;
            szBak[nLen] = 'a'; nLen--;
            szBak[nLen] = 'b';
            CopyFileA(szLine, szBak, FALSE);

            FILE* pFile = NULL;
            if (poseOnly) { // MLL 12-17-2019: update #pose entry only
                BOOL hasPose = FALSE, hasLights = FALSE;
                FILE* pBak = fopen(szBak, "r");
                pFile = fopen(szLine, "w");
                if (pBak && pFile) {
                    gM.pose[0] = gP.rTargetPos[0]; gM.pose[1] = gP.rTargetPos[1]; gM.pose[2] = gP.rTargetPos[2];
                    gM.pose[3] = gP.rCameraPos[0]; gM.pose[4] = gP.rCameraPos[1]; gM.pose[5] = gP.rCameraPos[2] - CAMERA_OFFZ;
                    gM.pose[6] = gP.rPitch; gM.pose[7] = gP.rYaw; gM.pose[8] = gP.rRoll;
                    ClearMemory(szLine, sizeof(szLine));
                    while (fgets(szLine, MAX_PATH, pBak) != NULL) {
                        if (szLine[0] == '#') {
                            CharLowerA(szLine);
                            if (strstr(szLine, "#pose")) { // #pose found; insert new values
                                sprintf(szLine, "#pose %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", // better precision is imperceptible
                                    gM.pose[0], gM.pose[1], gM.pose[2],
                                    gM.pose[3], gM.pose[4], gM.pose[5],
                                    gM.pose[6], gM.pose[7], gM.pose[8]);
                                hasPose = TRUE;
                            }
                            else if (strstr(szLine, "#light"))
                                hasLights = TRUE;
                        }
                        fputs(szLine, pFile);
                    }
                    // MLL 12-17-2019: Not very elegant but working
                    if (!hasPose) { // #pose not found; insert new #pose meta
                        fseek(pBak, SEEK_SET, 0);
                        fseek(pFile, SEEK_SET, 0);
                        if (hasLights) {
                            int nLights = 0;
                            while ((fgets(szLine, MAX_PATH, pBak) != NULL)) { // skip #light metas
                                if (szLine[0] == '#') {
                                    CharLowerA(szLine);
                                    if (strstr(szLine, "#light")) {
                                        fputs(szLine, pFile);
                                        nLights++;
                                    }
                                    if (nLights == 12)
                                        break;
                                }
                            }
                        }
                        sprintf(szLine, "\n#pose %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", // add new #pose meta
                            gM.pose[0], gM.pose[1], gM.pose[2],
                            gM.pose[3], gM.pose[4], gM.pose[5],
                            gM.pose[6], gM.pose[7], gM.pose[8]);
                        fputs(szLine, pFile);
                        while ((fgets(szLine, MAX_PATH, pBak) != NULL)) // add all other remaining lines
                            fputs(szLine, pFile);
                    }
                    fclose(pBak);
                    fclose(pFile);
                }
            } else {
                pFile = fopen(szLine, "w");
                if (pFile) {
                    SaveLighting(pFile);
                    for (nItem = 1; nItem < nCount; nItem++) {
                        ClearMemory(szLine, sizeof(szLine));
                        SendMessageA(gP.hMaterial, LB_GETTEXT, nItem, (LPARAM)szLine);
                        if ((nItem == 1) && (szLine[0] == '\n')) { continue; }
                        fputs(szLine, pFile);
                    }
                    fclose(pFile);
                }
            }
            if (pFile)
                skDialogInfo($NULL, L"\nMaterial file updated successfully.", $NULL);
        }
    }
}


Mobj.h in Mobj_importMaterials():

(at the top)
........
    char fullPath[MAX_PATH] = { 0 };
    char s1[MAX_PATH] = { 0 }; char s2[32] = { 0 }; char s3[32] = { 0 }; // 10-09-2019 Bass.dll
    char s4[32], s5[32], s6[32], s7[32], s8[32], s9[32]; // MLL 12-17-2019:
    HWND hCtrl = 0; // PAT: 11-05-2019
........
(lower in global #metas)
........
                } else if (strcmp(szBuffer, "#demo") == 0) {                // PAT: 11-02-2019 MODEL ROTATION
                    if (gP.bGiration == 0)
                        PutFocusOn(GetDlgItem(gP.hMain, IDC_DEMO_MODE));
                } else if (strcmp(szBuffer, "#pose") == 0) {                // MLL 12-17-2019: MODEL INITIAL POSE other than at [0,0,0]
                    fgets(szBuffer, sizeof(szBuffer), pFile);
                    s1[0] = s2[0] = s3[0] = s4[0] = s5[0] = s6[0] = s7[0] = s8[0] = s9[0] = 0;
                    sscanf(szBuffer, "%s %s %s %s %s %s %s %s %s", s1, s2, s3, s4, s5, s6, s7, s8, s9);
                    gM.pose[0] = (float)atof(s1); gM.pose[1] = (float)atof(s2); gM.pose[2] = (float)atof(s3);
                    gM.pose[3] = (float)atof(s4); gM.pose[4] = (float)atof(s5); gM.pose[5] = (float)atof(s6);
                    gM.pose[6] = (float)atof(s7); gM.pose[7] = (float)atof(s8); gM.pose[8] = (float)atof(s9);
                    printf("\nModel posed at target translation %.f %.f %.f,"
                        "camera translation %.f %.f %.f, rotation %.f %.f %.f\n\n",
                        gM.pose[0], gM.pose[1], gM.pose[2], gM.pose[3], gM.pose[4], gM.pose[5], gM.pose[6], gM.pose[7], gM.pose[8]);
                } else {
........


Renderers.h:

// MLL 12-17-2019: #pose support
void lerpReset(IN BOOL start = FALSE) {
    static int frames, maxFrames; // render frames counter
    static float dtpX, dtpY, dtpZ; // target position deltas
    static float dcpX, dcpY, dcpZ; // camera position deltas
    static float drP, drY, drR; // camera rotation deltas
    static float frac;

    // Forward declarations
    void gl_AdjustNearPlane();
    void gl_Resize();
    void gl_DrawScene();
    void zeroCamera();

    if (start) {
        if (gP.rTargetPos[0] == (gM.pose[0] ? gM.pose[0] : gM.center[0])              &&
            gP.rTargetPos[1] == (gM.pose[1] ? gM.pose[1] : gM.center[1])              &&
            gP.rTargetPos[2] == (gM.pose[2] ? gM.pose[2] : gM.center[2])              &&
            gP.rCameraPos[0] == (gM.pose[3] ? gM.pose[3] : gP.rTargetPos[0])          &&
            gP.rCameraPos[1] == (gM.pose[4] ? gM.pose[4] : gP.rTargetPos[1])          &&
            gP.rCameraPos[2] == (gM.pose[5] ? gM.pose[5] + CAMERA_OFFZ : CAMERA_OFFZ) &&
            gP.rPitch == gM.pose[6] &&
            gP.rYaw == gM.pose[7] &&
            gP.rRoll == gM.pose[8]) {
            gP.bIsLerping = FALSE; // no need to lerp; already reset
            return;
        }

        frames = 0;
        maxFrames = (int)(gP.nFPS * 0.5f); // ca. half a second animation regardless of FPS
        frac = 1.0f / maxFrames;
        dtpX = (gP.rTargetPos[0] - gM.pose[0]) * frac;
        dtpY = (gP.rTargetPos[1] - gM.pose[1]) * frac;
        dtpZ = (gP.rTargetPos[2] - gM.pose[2]) * frac;
        dcpX = (gP.rCameraPos[0] - gM.pose[3]) * frac;
        dcpY = (gP.rCameraPos[1] - gM.pose[4]) * frac;
        dcpZ = (gP.rCameraPos[2] - gM.pose[5] - CAMERA_OFFZ) * frac;
        drP = (gP.rPitch - gM.pose[6]) * frac; if (drP < 0.0f) drP = -drP;
        drY = (gP.rYaw - gM.pose[7]) * frac; if (drY < 0.0f) drY = -drY;
        drR = (gP.rRoll - gM.pose[8]) * frac; if (drR < 0.0f) drR = -drR;
        gP.bIsLerping = TRUE;
        return;
    }

    frames += 1;

    if (gP.bIsLerping) {
        if (frames >= maxFrames) {
            zeroCamera();
            dtpX = dtpY = dtpZ = 0.0f;
            dcpX = dcpY = dcpZ = 0.0f;
            drP = drY = drR = 0.0f;
            frames = 0; frac = 0.0f;
            gP.bIsLerping = FALSE;
            gl_AdjustNearPlane();
            gl_Resize();
            return;
        }
    }

    if (dcpX != 0.0) {
        gP.rTargetPos[0] -= dtpX;
        gP.rCameraPos[0] -= dcpX;
    }
    if (dcpY != 0.0) {
        gP.rTargetPos[1] -= dtpY;
        gP.rCameraPos[1] -= dcpY;
    }
    if (dcpZ != (CAMERA_OFFZ * frac)) {
        gP.rTargetPos[2] -= dtpZ;
        gP.rCameraPos[2] -= dcpZ;
    }
    if (drP != 0.0f)
        gP.rPitch -= drP;
    if (drY != 0.0f)
        gP.rYaw -= drY;
    if (drR != 0.0f)
        gP.rRoll -= drR;

    gl_AdjustNearPlane();
    gl_Resize();
}



Hopefully, this time it's gonna work. I know lerpReset() still isn't perfect but it's passable on fast animations and a low number of animated frames (up to 0.5 secs in duration all in all).

Please let me know your impression.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 22, 2019, 10:04:53 pm
EXCELLENT, that is exactly what i was especting.

That would help me to produce more realistic scene.

Thank you very much !
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 23, 2019, 11:51:44 am
Hey Patrice,

WebGL accepts negative arguments to smoothstep() while OpenGL doesn't.

Now catch this Postcard.fs:

Code: [Select]
// Postcard by nimitz (twitter: @stormoid)
// https://www.shadertoy.com/view/XdBSWd
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// Contact the author for other licensing options

/*
Implementation of: http://iquilezles.org/www/articles/dynclouds/dynclouds.htm

Added some raymarched mountains and normal mapped water to complete the scene.

One thing I did differently is modyfying the scale of the fbm based on the distance
from the shaded clouds allowing for a much less "planar" look to the cloud layer.
*/

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
uniform sampler2D colornoise_png;

//Compare with simple clouds
//#define BASIC_CLOUDS

#define time iTime * 2.0
#define FAR 420.0

//------------------------------------------------------------------
//----------------------Utility functions---------------------------
//------------------------------------------------------------------
vec3 rotx(vec3 p, float a) {
    float s = sin(a), c = cos(a);
    return vec3(p.x, c * p.y - s * p.z, s * p.y + c * p.z);
}

vec3 roty(vec3 p, float a) {
    float s = sin(a), c = cos(a);
    return vec3(c * p.x + s * p.z, p.y, -s * p.x + c * p.z);
}

float nmzHash(vec2 q) {
    uvec2 p = uvec2(ivec2(q));
    p = p * uvec2(374761393U, 22695477U) + p.yx;
    p.x = p.x * (p.y ^ (p.x >> 15U));
    return float(p.x ^ (p.x >> 16U)) * (1.0 / float(0xffffffffU));
}

float noise(in vec2 p) {
    vec2 ip = floor(p);
    vec2 fp = fract(p);
vec2 u = fp * fp * (3.0 - 2.0 * fp);
    return -1.0 + 2.0 * mix(mix(nmzHash(ip + vec2(0.0, 0.0)), nmzHash(ip + vec2(1.0, 0.0)), u.x),
                mix(nmzHash(ip + vec2(0.0, 1.0)), nmzHash(ip + vec2(1.0, 1.0)), u.x), u.y);
}
//------------------------------------------------------------------
//---------------------------Terrain--------------------------------
//------------------------------------------------------------------
float terrain(in vec2 p) {
    p *= 0.035;
    float rz = 0.;
    float m = 1.;
    float z = 1.;
    for (int i = 0; i <= 2; i++) {
        rz += (sin(noise(p / m) * 1.7) * 0.5 + 0.5) * z;
        m *= -0.25;
        z *= .2;
    }
    rz = exp2(rz - 1.5);
    rz -= sin(p.y * .2 + sin(p.x * .45));
    return rz * 20. - 14.;
}

float tmap(in vec3 p) {return p.y - terrain(p.zx);}
//Using "cheap AA" from eiffie (https://www.shadertoy.com/view/XsSXDt)
vec3 tmarch(in vec3 ro, in vec3 rd, in float d) {
float precis = 0.01;
    float h = precis * 2.0;
    float hm = 100., dhm = 0.;
    for (int i = 0; i < 15; i++) {
        d += h = tmap(ro + rd * d) * 1.5;
        if (h < hm) {
            hm = h;
            dhm = d;
        }
        if(abs(h) < precis || d > FAR) break;
    }
return vec3(d, hm, dhm);
}

vec3 normal(in vec3 pos, float t) {
float e = 0.001 * t;
    vec2  eps = vec2(e, 0.0);
    float h = terrain(pos.xz);
    return normalize(vec3(terrain(pos.xz - eps.xy) - h, e, terrain(pos.xz - eps.yx) - h));
}

float plane(in vec3 ro, in vec3 rd, vec3 c, vec3 u, vec3 v) {
vec3 q = ro - c;
vec3 n = cross(u, v);
    return -dot(n, q) / dot(rd, n);
}
//------------------------------------------------------------------
//-------------------------2d Clouds--------------------------------
//------------------------------------------------------------------
vec3 lgt = normalize(vec3(-1.0, 0.1, .0));
vec3 hor = vec3(0.);

float nz(in vec2 p) {return texture(colornoise_png, p * .01).x;}
mat2 m2 = mat2(0.80,  0.60, -0.60,  0.80);
float fbm(in vec2 p, in float d) {
d = smoothstep(0., 100., d);
    p *= .3 / (d + 0.2);
    float z = 2.;
float rz = 0.;
    p  -= time * 0.02;
for (float i = 1.; i <= 5.; i++) {
rz += (sin(nz(p) * 6.5) * 0.5 + 0.5) * 1.25 / z;
z *= 2.1;
p *= 2.15;
        p += time * 0.027;
        p *= m2;
}
    return pow(abs(rz), 2. -d);
}

vec4 clouds(in vec3 ro, in vec3 rd, in bool wtr) {
    //Base sky coloring is from iq's "Canyon" (https://www.shadertoy.com/view/MdBGzG)
    float sun = clamp(dot(lgt, rd), 0.0, 1.0);
    hor = mix(1. * vec3(0.70, 1.0, 1.0), vec3(1.3, 0.55, 0.15), 0.25 + 0.75 * sun);
    vec3 col = mix(vec3(0.5, 0.75, 1.), hor, exp(-(4. + 2. * (1. - sun)) * max(0.0, rd.y - 0.05)));
    col *= 0.4;

    if (!wtr) {
        col += 0.8 * vec3(1.0, 0.8, 0.7) * pow(sun, 512.0);
        col += 0.2 * vec3(1.0, 0.4, 0.2) * pow(sun, 32.0);
    }
    else {
        col += 1.5 * vec3(1.0, 0.8, 0.7) * pow(sun, 512.0);
        col += 0.3 * vec3(1.0, 0.4, 0.2) * pow(sun, 32.0);
    }
    col += 0.1 * vec3(1.0, 0.4, 0.2) * pow(sun, 4.0);

float pt = (90.0 - ro.y) / rd.y;
    vec3 bpos = ro + pt * rd;
    float dist = sqrt(distance(ro, bpos));
    float s2p = distance(bpos, lgt * 100.);

    const float cls = 0.002;
    float bz = fbm(bpos.xz * cls, dist);
    float tot = bz;
    const float stm = .0;
    const float stx = 1.15;
    tot = smoothstep(stm, stx, tot);
    float ds = 2.;
    for (float i = 0.; i <= 3.; i++) {
        vec3 pp = bpos + ds * lgt;
        float v = fbm(pp.xz * cls, dist);
        v = smoothstep(stm, stx, v);
        tot += v;
        #ifndef BASIC_CLOUDS
        ds *= .14 * dist;
        #endif
    }

    col = mix(col, vec3(.5, 0.5, 0.55) * 0.2, pow(bz, 1.5));
    tot = smoothstep(-7.5, 0., 1. - tot);
    vec3 sccol = mix(vec3(0.11, 0.1, 0.2), vec3(.2, 0., 0.1), smoothstep(0., 900., s2p));
    col = mix(col, sccol, 1. - tot) * 1.6;
    vec3 sncol = mix(vec3(1.4, 0.3, 0.), vec3(1.5, .65, 0.),smoothstep(0., 1200., s2p));
    float sd = pow(sun, 10.) + .7;
    col += sncol * bz * bz * bz * tot * tot * tot * sd;

    if (wtr) col = mix(col, vec3(0.5, 0.7, 1.) * 0.3, 0.4); //make the water blue-er
    return vec4(col, tot);
}
//------------------------------------------------------------------
//-------------------------------Extras-----------------------------
//------------------------------------------------------------------
float bnoise(in vec2 p) {
    float d = sin(p.x * 1.5 + sin(p.y * .2)) * 0.1;
    return d += texture(colornoise_png, p.xy * 0.01 + time * 0.001).x * 0.04;
}

vec3 bump(in vec2 p, in vec3 n, in float t) {
    vec2 e = vec2(40., 0.) / (t * t);
    float n0 = bnoise(p);
    vec3 d = vec3(bnoise(p + e.xy) - n0, 2., bnoise(p + e.yx) - n0) / e.x;
    n = normalize(n - d);
    return n;
}
//------------------------------------------------------------------
//------------------------------------------------------------------
void main() {
    vec2 bp = gl_FragCoord.xy / iResolution.xy * 2. - 1.;
    vec2 p  = bp;
p.x *= iResolution.x / iResolution.y;
vec2 mo = iMouse.xy / iResolution.xy - .5;
    mo = (mo == vec2(-.5)) ? mo = vec2(-0.4, -0.15) : mo;
mo.x *= iResolution.x / iResolution.y;
vec3 ro = vec3(140., 0., 100.);
    vec3 rd = normalize(vec3(p, -2.7));
    rd = rotx(rd, 0.15 + mo.y * 0.4); rd = roty(rd, 1.5 + mo.x * 0.5);
    vec3 brd = rd;
    vec3 col = vec3(0);

float pln = plane(ro, rd, vec3(0., -4., 0.), vec3(1., 0., 0.), vec3(0.0, .0, 1.0));
    vec3 ppos = ro + rd * pln;
    bool wtr = false;
    vec3 bm = vec3(0);
    if (pln < 500. && pln > 0.) {
        vec3 n = vec3(0., 1., 0.);
        float d = distance(ro, ppos);
        n = bump(ppos.xz, n, d);
        bm = n;
        rd = reflect(rd, n);
        wtr = true;
    }
    vec4 clo = clouds(ro, rd, wtr);
    col = clo.rgb;

    vec3 rz = tmarch(ro, brd, 350.);
    float px = 3.5 / iResolution.y;
    if (rz.x < FAR && (rz.x < pln || pln < 0.)) {
        vec3 pos = ro + brd * rz.x;
        float dst = distance(pos, ro);
        vec3 nor = normal(pos, dst);
        float nl = clamp(dot(nor, lgt), 0., 1.);
        vec3 mcol = vec3(0.04) + vec3(nl) * 0.4 * vec3(.5, 0.35, 0.1);
        mcol = mix(mcol, hor, smoothstep(210., 400., rz.x - (pos.y + 18.) * 5.));//fogtains
        col = mix(mcol, col, clamp(rz.y / (px * rz.z), 0., 1.));
    }

    //smooth water edge
    if (wtr && rz.x > pln) col = mix(col, hor * vec3(0.3, 0.4, .6) * 0.4, smoothstep(10., 200., pln));

    //post
    col = pow(clamp(col, 0.0, 1.0), vec3(.9));
    col.g *= 0.93;
    //fancy vignetting
    float vgn1 = pow(smoothstep(0.0, .3, (bp.x + 1.) * (bp.y + 1.) * (bp.x - 1.) * (bp.y - 1.)), .5);
    float vgn2 = 1. - pow(dot(vec2(bp.x * .3, bp.y), bp), 3.);
    col *= mix(vgn1, vgn2, .4) * .5 + 0.5;
gl_FragColor = vec4(col, 1.0);
}


Enjoy! :)


P.S. You can also optionally make all occurrencies of colornoise_png unmipmapped by adding nomip_colornoise_png. It will make the clouds a little less dense.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 23, 2019, 04:04:31 pm
Thank you for this new shader !

I shall release soon, version #2.85, to be able to use the new #pose meta command within material files.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 24, 2019, 02:16:19 am
Here are some more practical animated backgrounds:

ThinWater.fs:

Code: [Select]
uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
uniform sampler2D stone_jpg;
uniform sampler2D moss_jpg;

float lum(vec3 rgb) {
return dot(rgb,vec3(0.299, 0.587, 0.114));
}

float depthf(vec2 uv) {
    vec2 uv_= uv;
    uv_.y += iTime * .25;
    float back = lum(texture(stone_jpg, uv).rgb);//luminance approximates depth
    uv_.y += back * .2;//create flow
    float water = lum(texture(moss_jpg, uv_).rgb);
return dot(vec2(water, back), vec2(.5, .5));
}

void main() {
    vec2 uv = gl_FragCoord / iResolution.xy;

    float d = 0.03;
    float d0 = depthf(uv);
    vec2 grad = (vec2(
    depthf(uv + vec2(d, 0)),
        depthf(uv + vec2(0, d))
    ) - d0) / d;
    vec3 norm = normalize(1. - vec3(grad.x, grad.y, 0.));

    float shine = max(0., reflect(normalize(vec3(1.)), norm).z) * .2;

    uv += refract(vec3(0., 0., 1.), norm, .5).xy * .008;

    vec3 col = texture(stone_jpg, uv).rgb;
    col = pow(col, vec3(1. / 2.2)); //gamma

    col += shine * shine;

    col = pow(col, vec3(2.2));
    gl_FragColor = vec4(col, 1.0);
}

GlowFrame.fs:

Code: [Select]
// Inner outline shader for Match2 game cell.
// Based on shader created by @remonvv
// https://www.shadertoy.com/view/MdjfRK
//
// Thanks to t.me/ru_cocos2dx@satan_black for help

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

float rand(vec2 n) {
    return fract(sin(dot(n, vec2(12.9898,12.1414))) * 83758.5453);
}

float noise(vec2 n) {
    const vec2 d = vec2(0.0, 1.0);
    vec2 b = floor(n);
    vec2 f = mix(vec2(0.0), vec2(1.0), fract(n));
    return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
}

vec3 ramp(float t) {
return t <= .5 ? vec3( 1. - t * 1.4, .2, 1.05 ) / t : vec3( .3 * (1. - t) * 2., .2, 1.05 ) / t;
}

float fire(vec2 n) {
    return noise(n) + noise(n * 2.1) * .6 + noise(n * 5.4) * .42;
}

/*
vec3 getLine(vec2 fc, mat2 mtx, float shift){
    float t = iTime;
    vec2 uv = (fc / iResolution.xy) * mtx;

    uv.x += uv.y < .5 ? 23.0 + t * .35 : -11.0 + t * .3;
    uv.y = abs(uv.y - shift);
    uv *= 10.0;

    float q = fire(uv - t * .013) / 2.0;
    vec2 r = vec2(fire(uv + q / 2.0 + t - uv.x - uv.y), fire(uv + q - t));
    vec3 color = vec3(1.0 / (pow(vec3(0.5, 0.0, .1) + 1.61, vec3(4.0))));

    float grad = pow((r.y + r.y) * max(.0, uv.y) + .1, 4.0);
    color = ramp(grad);
    color /= (1.50 + max(vec3(0), color));
    return color;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
vec2 uv = fragCoord / iResolution.xy;
    fragColor = vec4(getLine(fragCoord, mat2(1., 1., 0., 1.), 1.), 1.);
    fragColor += vec4(getLine(fragCoord, mat2(1., 1., 1., 0.), 1.), 1.);
    fragColor += vec4(getLine(fragCoord, mat2(1., 1., 0., 1.), 0.), 1.);
    fragColor += vec4(getLine(fragCoord, mat2(1., 1., 1., 0.), 0.), 1.);
    if(fragColor.r <= .05 && fragColor.g <= .05 && fragColor.b <= .05 ){
    fragColor = texture(iChannel0, uv);
    } else {
        fragColor += texture(iChannel0, uv);
    }
}
*/

vec3 getLine(vec3 col, vec2 fc, mat2 mtx, float shift) {
    float t = iTime;
    vec2 uv = (fc / iResolution.xy) * mtx;

    uv.x += uv.y < .5 ? 23.0 + t * .35 : -11.0 + t * .3;
    uv.y = abs(uv.y - shift);
    uv *= 5.0;

    float q = fire(uv - t * .013) / 2.0;
    vec2 r = vec2(fire(uv + q / 2.0 + t - uv.x - uv.y), fire(uv + q - t));
    vec3 color = vec3(1.0 / (pow(vec3(0.5, 0.0, .1) + 1.61, vec3(4.0))));

    float grad = pow((r.y + r.y) * max(.0, uv.y) + .1, 4.0);
    color = ramp(grad);
    color /= (1.50 + max(vec3(0), color));

    if(color.b < .00000005)
        color = vec3(.0);

    return mix(col, color, color.b);
}

void main() {
    vec2 uv = gl_FragCoord / iResolution.xy;
    vec3 color = vec3(0.);
    color = getLine(color, gl_FragCoord, mat2(1., 1., 0., 1.), 1.02);
    color = getLine(color, gl_FragCoord, mat2(1., 1., 1., 0.), 1.02);
    color = getLine(color, gl_FragCoord, mat2(1., 1., 0., 1.), -0.02);
    color = getLine(color, gl_FragCoord, mat2(1., 1., 1., 0.), -0.02);

    gl_FragColor = vec4(color, 1.0);
}

IntoTheLight.fs:

Code: [Select]
uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

float star(in vec2 uv, in float t) {
    float phi = atan(uv.y, uv.x);
    float d = length(uv)
        * (1.
           + 0.15 * sin( phi * 4. + 0.2 * t)
           + 0.1 * sin( 1.2 * phi * 10. + 0.6 * t)
           + 0.2 * sin( phi * phi * 2. + 0.4 * t)
          ) * 7.7 * ( 1. + 0.1 * sin(t));
    d = log(d * d);
    return 0.7 * d;
}

void main() {
vec2 uv = (gl_FragCoord - .5 * iResolution.xy) / iResolution.x;

    float t = 1.4 * iTime;
    float d = 0.5 * min(star(uv, t), star(uv, t - 2.1));
    d = (1. + 0.1 * sin(t)) * min(d, star(uv, t - 3.1));

    gl_FragColor = vec4(sqrt(smoothstep(1., 0., d)));
}

Kepler.fs:

Code: [Select]
/*--------------------------------------------------------------------------------------
License CC0 - http://creativecommons.org/publicdomain/zero/1.0/
To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
----------------------------------------------------------------------------------------
^ This means do ANYTHING YOU WANT with this code. Because we are programmers, not lawyers.
-Otavio Good
*/

uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

uniform sampler2D moss_jpg;
uniform sampler2D pebblesud_jpg;
uniform sampler2D bwnoise_png;
uniform sampler2D stars_jpg;

float PI=3.14159265;
vec3 sunCol = vec3(258.0, 208.0, 100.0) / 15.0;
vec3 environmentSphereColor = vec3(0.3001, 0.501, 0.901) * 0.0;

float distFromSphere;
vec3 normal;
vec3 texBlurry;

vec3 saturate(vec3 a) {
return clamp(a, 0.0, 1.0);
}

vec2 saturate(vec2 a) {
return clamp(a, 0.0, 1.0);
}

float saturate(float a) {
return clamp(a, 0.0, 1.0);
}

vec3 GetSunColor(vec3 rayDir, vec3 sunDir) {
float dense = 16.0;
vec3 localRay = normalize(rayDir);
float sunIntensity = 1.0 - (dot(localRay, sunDir) * 0.5 + 0.5);
//sunIntensity = (float)Math.Pow(sunIntensity, 14.0);
sunIntensity = 0.2 / sunIntensity;
sunIntensity = min(sunIntensity, 40000.0);
sunIntensity = max(0.0, sunIntensity - 3.0);

localRay.x = localRay.x + 1.0 - iTime * 0.1;
//vec3 right = normalize(cross(sunDir, vec3(0.0,1.0,0.0)));
//vec3 up = normalize(cross(sunDir, right));
vec2 wrap = fract((localRay.xy)*dense);
vec4 rand = texture(bwnoise_png, floor(localRay.xy*dense)/dense).xyzw;
vec3 starColor = rand.xyz;
starColor = starColor * 0.75 + 0.25;
rand.xy = rand.xy * 2.0 - 1.0;
vec2 center = vec2(0.5, 0.5) + rand.xy * 0.9;// floor(fract((localRay.xy)*8.0)) + 0.5;
float star = length(wrap - center);
float test = star;
star = saturate((1.0 - star));
float blink = texture(bwnoise_png, localRay.xy + iTime * 0.03).x;
float cluster = 0.3;// /*(localRay.x+0.5) */ (localRay.y+0.5) * 2.8 + 0.8;
star = pow(star, 60.0 + saturate(rand.z - 0.0) * 250.0 * cluster);
star *= blink;

float milkyMask = saturate(0.25 - abs(localRay.x - 0.65));
vec3 milkyway = texture(stars_jpg, (localRay.yx*1.5 )+vec2(0.65, 0.3)).yxz;
vec3 milkyLOD = texture(stars_jpg, (localRay.yx*1.5 )+vec2(0.65, 0.3), 3.0).yxz;
vec3 milkyDetail = texture(stars_jpg, (-localRay.yx*8.0 )+vec2(0.65, 0.3)).yxz;
milkyway *= milkyDetail.xxx;
milkyway *= vec3(1.0, 0.8, 0.91)*1.5;
milkyway = pow(milkyway, vec3(2.0, 2.0, 2.0)*3.0);
milkyway += vec3(0.2, 0.0015, 1.001) * milkyLOD * 0.006;

vec3 finalColor = milkyway /* milkyMask*/ * 10850.0;
finalColor += environmentSphereColor + sunCol * sunIntensity + starColor * star * 12000.0 * cluster;
return finalColor;
//return environmentSphereColor + sunCol * sunIntensity + starColor * star * 12000.0 * cluster;
//return vec3(1.0,1.0,1.0)*cluster*1000.0;
}

vec3 GetSunColorReflection(vec3 rayDir, vec3 sunDir) {
vec3 localRay = normalize(rayDir);
float sunIntensity = 1.0 - (dot(localRay, sunDir) * 0.5 + 0.5);
//sunIntensity = (float)Math.Pow(sunIntensity, 14.0);
sunIntensity = 0.2 / sunIntensity;
sunIntensity = min(sunIntensity, 40000.0);
return environmentSphereColor + sunCol * sunIntensity;
}

vec3 LensFlare(vec2 uv, vec2 lfPos) {
vec2 delta = uv - lfPos;
float dist = length(delta);
float angle = atan(delta.x, delta.y);
vec3 tex = texture(moss_jpg, vec2(angle*5.0, dist*0.125) /*- iTime*0.1*/).xyz;
float bump = sin(angle * 6.0) * 0.5 + 0.54;
bump -= pow(dist, 0.0125);
bump = saturate(bump);

return sunCol * tex.x * 0.1 * bump / (dist);
}

float IntersectSphereAndRay(vec3 pos, float radius, vec3 posA, vec3 posB, out vec3 intersectA2, out vec3 intersectB2) {
// Use dot product along line to find closest point on line
vec3 eyeVec2 = normalize(posB-posA);
float dp = dot(eyeVec2, pos - posA);
vec3 pointOnLine = eyeVec2 * dp + posA;
// Clamp that point to line end points if outside
//if ((dp - radius) < 0) pointOnLine = posA;
//if ((dp + radius) > (posB-posA).Length()) pointOnLine = posB;
// Distance formula from that point to sphere center, compare with radius.
float distance = length(pointOnLine - pos);
float ac = radius*radius - distance*distance;
float rightLen = 0.0;
if (ac >= 0.0) rightLen = sqrt(ac);
intersectA2 = pointOnLine - eyeVec2 * rightLen;
intersectB2 = pointOnLine + eyeVec2 * rightLen;
distFromSphere = distance - radius;
if (distance <= radius) return 1.0;
return 0.0;
}

vec2 Spiral(vec2 uv) {
float reps = 2.0;
vec2 uv2 = fract(uv*reps);
vec2 center = floor(fract(uv*reps)) + 0.5;
vec2 delta = uv2 - center;
float dist = length(delta);
float angle = atan(delta.y, delta.x);
//if (distance(center, uv2) < 0.02) return vec2(10,10);
float nudge = dist * 4.0;
vec2 offset = vec2(delta.y, -delta.x);// * 0.2 / dist ;// vec2(sin(angle+nudge), cos(angle+nudge));
float blend = max(abs(delta.x), abs(delta.y))* 2.0;
blend = clamp((0.5 - dist) * 2.0, 0.0, 1.0);
blend = pow(blend, 1.5);
//offset *= clamp(1.0 - blend, 0.0, 1.0);
offset *= clamp(blend, 0.0, 1.0);
//if (dist > 0.5) offset = vec2(0,0);
//offset *= dist;
return uv + offset*vec2(1.0,1.0)*1.1*texBlurry.x ;//+ vec2(iTime*0.03, 0.0);
}

void main() {
//vec2 uv = fragCoord.xy / iResolution.yy + vec2(-0.4,0.0);
//vec3 worldPix = vec3(uv*2.0 - 1.0, 1.65);// + (iMouse.x - iResolution.x * 0.2)* 0.01);
//vec3 camPos = vec3(0.0,0.1,0.0);

vec2 uv = gl_FragCoord.xy / iResolution.xy - 0.5;

// Camera up vector.
vec3 camUp=vec3(0,1,0); // vuv

// Camera lookat.
vec3 camLookat=vec3(0,0.0,0); // vrp

float mx=-PI/2.0;//iMouse.x/iResolution.x*PI*2.0;
float my=0.0;//-iMouse.y/iResolution.y*10.0;//*PI/2.01;
vec3 camPos=vec3(cos(my)*cos(mx),sin(my),cos(my)*sin(mx))*(2.5); // prp

// Camera setup.
vec3 camVec=normalize(camLookat - camPos);//vpn
vec3 sideNorm=normalize(cross(camUp, camVec)); // u
vec3 upNorm=cross(camVec, sideNorm);//v
vec3 worldFacing=(camPos + camVec);//vcv
vec3 worldPix = worldFacing + uv.x * sideNorm * (iResolution.x/iResolution.y) + uv.y * upNorm;//scrCoord
vec3 relVec = normalize(worldPix - camPos);//scp


vec3 planetPos = vec3(0.0,0.0,0.0);
vec3 iA, iB, iA2, iB2;
float t = iTime * 0.05 + 0.35 - iMouse.x*0.01; // MLL: was *0.1+0.7
float cloudT = iTime * 0.1;
float distFromSphere2;
vec3 normal2;
float hit2 = IntersectSphereAndRay(planetPos, 1.05, camPos, worldPix, iA2, iB2);
normal2 = normal;
distFromSphere2 = distFromSphere;
float hit = IntersectSphereAndRay(planetPos, 1.0, camPos, worldPix, iA, iB);
//float hit = IntersectSphereAndRay(planetPos, 1.0, camPos, pixPos, iA, iB);
normal = normalize(iA - planetPos);
//if (abs(normal.x) <= 0.001) normal.x += 0.001;
vec2 polar = vec2(atan(normal.x, normal.z)/*0.955*/, acos(normal.y));
polar.x = (polar.x + PI) / (PI * 2.0);
polar.y = polar.y / PI;// + 0.5;
if (abs(normal.x) <= 0.02) {
//polar.x = 0.0;
}
polar.x = (polar.x+2.03);
polar.xy = iA.xy;
//polar.y = floor(polar.y * 32.0) / 32.0;
/* if (abs(normal.x) < abs(normal.z)) {
polar = vec2((atan(normal.z, normal.x))*0.955, acos(iA.y));
//polar.x = 0.0;
}*/
//+ vec2(0.0,iTime * 0.01)
vec4 texNoise = texture(bwnoise_png, (polar.xy+vec2(t,0)) * 2.0);
texNoise.y = texture(bwnoise_png, (polar.xy+vec2(t,0)) * 1.0).y;
texNoise.z = texture(bwnoise_png, (polar.xy+vec2(t,0)) * 4.0).z;
texBlurry = texture(moss_jpg, (polar.xy+vec2(t,0))*0.03125*0.25 ).rgb;

vec3 tex = texture(moss_jpg, (polar.xy+vec2(t,0))*1.0).rgb;
//vec3 tex = texture(moss_jpg, polar.xy, 0.0).rgb;
tex *= tex;
vec3 texFlip = texture(moss_jpg, (1.0 - (polar.xy+vec2(t,0))*0.5)).rgb;
texFlip *= texFlip;

vec3 texS = texture(moss_jpg, (Spiral(polar.xy+vec2(t,0))+vec2(cloudT*0.25,0))*1.0).rgb;
texS *= texS;
vec3 texFlipS = texture(moss_jpg, (1.0 - (Spiral(polar.xy+vec2(t,0))+vec2(cloudT*0.25,0))*0.5)).rgb;
texFlipS *= texFlipS;

float atmosphereDensity = (1.45 + normal.z);
vec3 atmosphereColor = vec3(0.075, 0.35, 0.99) * 0.45;
float cloudDensity = max(0.0, (pow(texFlipS.x * texS.x, 0.7) * 3.0));
vec3 finalAtmosphere = atmosphereColor * atmosphereDensity + cloudDensity;
vec3 finalColor = finalAtmosphere;

vec3 detailMap = min(texture(stars_jpg, (polar.xy+vec2(t,0)) * 2.0).xyz, 0.25) * 4.0;
float land = pow(max(0.0, texture(pebblesud_jpg, (polar.xy+vec2(t,0))* 0.25).z - 0.25), 0.4)*0.75;
float land2 = land * texBlurry.x * 6.0;
land *= detailMap.x;
//land2 *= detailMap.x;
land2 = max(0.0, land2);
land -= tex.x*0.65;
land = max(0.0, land);
float iceFactor = abs(pow(normal.y,2.0));
vec3 landColor = max(vec3(0.0,0.0,0.0), vec3(0.13,0.65,0.01) * land);// * (1.0 + iceFactor*2.0);
vec3 landColor2 = max(vec3(0.0,0.0,0.0), vec3(0.8,0.4,0.01) * land2);
vec3 mixedLand = (landColor + landColor2)* 0.5;
mixedLand *= (detailMap.zyx + 2.0) * 0.333;
//float hardBlur = saturate((texBlurry.x - 0.2)* 104.0 + 0.2)* 0.2 + 0.4;
//vec3 finalLand = mix(landColor, landColor2, hardBlur);
vec3 finalLand = mix(mixedLand, vec3(7.0, 7.0, 7.0) * land, iceFactor);
finalLand = mix(atmosphereColor * 0.05, finalLand, pow(min(1.0,max(0.0,-distFromSphere*1.0)), 0.2));
finalColor += finalLand;
finalColor *= hit;

float refNoise = (texNoise.x + texNoise.y + texNoise.z)* 0.3333;
vec3 noiseNormal = normal;
noiseNormal.x += refNoise*0.05*hit;
noiseNormal.y += tex.x*hit*0.1;
noiseNormal.z += texFlip.x*hit*0.1;
noiseNormal = normalize(noiseNormal);
vec3 ref = reflect(normalize(worldPix - camPos), noiseNormal);

refNoise = refNoise*0.25 + 0.75;
float orbitSpeed = 0.125;
//vec3 sunDir = normalize(vec3(-0.9 + sin(iTime*0.2)*0.5, -0.1, -0.9150));
vec3 sunDir = normalize(vec3(-0.009 + sin(iTime*orbitSpeed), -0.13, -cos(iTime*orbitSpeed)));
vec3 r = normalize(cross(sunDir, vec3(0.0,1.0,0.0)));
vec3 up = normalize(cross(sunDir, r));
float binarySpeed = 0.5;
float binaryDist = 0.3;
sunDir += r * sin(iTime*binarySpeed) * binaryDist + up * cos(iTime*binarySpeed) * binaryDist;
sunDir = normalize(sunDir);

vec3 sunDir2 = normalize(vec3(-0.009 + sin((iTime+0.2)*orbitSpeed), 0.13, -cos((iTime+0.2)*orbitSpeed)));
r = normalize(cross(sunDir2, vec3(0.0,1.0,0.0)));
up = normalize(cross(sunDir2, r));
sunDir2 -= r * sin(iTime*binarySpeed) * binaryDist + up * cos(iTime*binarySpeed) * binaryDist;
sunDir2 = normalize(sunDir2);

vec3 refNorm = normalize(ref);
float glance = saturate(dot(refNorm, sunDir) * saturate(sunDir.z - 0.65));
float glance2 = saturate(dot(refNorm, sunDir2) * saturate(sunDir2.z - 0.65));
float landMask = finalLand.x + finalLand.y * 1.5;
vec3 sunRef = GetSunColorReflection(refNorm, sunDir)*0.005*hit * (1.0 - saturate(landMask*3.5)) * (1.0-texS.x) * refNoise;
vec3 sunRef2 = GetSunColorReflection(refNorm, sunDir2)*0.005*hit * (1.0 - saturate(landMask*3.5)) * (1.0-texS.x) * refNoise;

//sunRef = mix(sunRef, atmosphereColor * vec3(1.0, 0.2, 0.1)*3.0, saturate(atmosphereDensity - 0.35)) * hit;
//sunRef *= atmosphereColor;
// fade to sunset color at outer atmosphere
sunRef = mix(sunRef, vec3(3.75, 0.8, 0.02)* hit, glance);
sunRef2 = mix(sunRef2, vec3(3.75, 0.8, 0.02)* hit, glance2);
finalColor += sunRef;
finalColor += sunRef2;

vec3 sunsColor = GetSunColor(normalize(ref), sunDir) *0.000096*(1.0-hit) +
GetSunColor(normalize(ref), sunDir2)*0.000096*(1.0-hit);

float outerGlow = 1.0 - clamp(distFromSphere * 20.0, 0.0, 1.0);
outerGlow = pow(outerGlow, 5.2);
finalColor += (atmosphereColor + vec3(0.2, 0.2, 0.2)) * outerGlow * (1.0 - hit);

float light = saturate(dot(sunDir, noiseNormal));
light += saturate(dot(sunDir2, noiseNormal));
finalColor *= light * 0.75 + 0.001; // ambient light (from stars, of course)
finalColor += sunsColor;

float scattering, scattering2;
if (hit2 == 1.0) scattering = distance(iA2, iB2);
scattering2 = scattering;
scattering *= pow(saturate(dot(relVec, sunDir) - 0.96), 2.0);
scattering2 *= pow(saturate(dot(relVec, sunDir2) - 0.96), 2.0);
scattering *= hit2 * (1.0 - hit);
scattering2 *= hit2 * (1.0 - hit);
scattering *= outerGlow;
scattering2 *= outerGlow;
finalColor += vec3(1.0, 0.25, 0.05) * scattering * 3060.0;
finalColor += vec3(1.0, 0.25, 0.05) * scattering2 * 3060.0;

//vec3 sunUV = worldFacing + sunDir2.x * sideNorm * (iResolution.x/iResolution.y) + sunDir2.y * upNorm;
//float lame = distance(sunUV, worldPix);
//vec3 sunUV = sunDir2 / vec3(sideNorm  * (iResolution.x/iResolution.y) * 0.4 + upNorm * 0.999);
//finalColor += LensFlare(uv * vec2((iResolution.x/iResolution.y), 1.0), vec2(sunUV.x, sunUV.y));

//finalColor = vec3(1.0,1.0,1.0) * (finalLand.x + finalLand.y)*hit;
//finalColor += vec3(1.0,1.0,1.0) * glance;
//finalColor = vec3(0, polar.x, 0.0);
//finalColor = GetSunColorReflection(normalize(ref), sunDir)*0.005*hit * (1.0 - clamp(finalLand.x*12.0, 0.0, 1.0)) * (1.0-texS.x) * refNoise;
//if (abs(normal.x) <= 0.001) finalColor = vec3(1.0,0.0,0.0);

gl_FragColor = vec4(sqrt(finalColor), 1.0);
}
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 24, 2019, 10:12:30 am
Thank you my friend!

I don't know if you have that one.

Flame.fs
Code: [Select]
uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

float noise(vec3 p) //Thx to Las^Mercury
{
vec3 i = floor(p);
vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
a.xy = mix(a.xz, a.yw, f.y);
return mix(a.x, a.y, f.z);
}

float sphere(vec3 p, vec4 spr)
{
return length(spr.xyz-p) - spr.w;
}

float flame(vec3 p)
{
float d = sphere(p*vec3(1.,.5,1.), vec4(.0,-1.,.0,1.));
return d + (noise(p+vec3(.0,iTime*2.,.0)) + noise(p*3.)*.5)*.25*(p.y) ;
}

float scene(vec3 p)
{
return min(100.-length(p) , abs(flame(p)) );
}

vec4 raymarch(vec3 org, vec3 dir)
{
float d = 0.0, glow = 0.0, eps = 0.02;
vec3  p = org;
bool glowed = false;

for(int i=0; i<64; i++)
{
d = scene(p) + eps;
p += d * dir;
if( d>eps )
{
if(flame(p) < .0)
glowed=true;
if(glowed)
        glow = float(i)/64.;
}
}
return vec4(p,glow);
}

void main()
{
vec2 v = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
v.x *= iResolution.x/iResolution.y;

vec3 org = vec3(0., -2., 4.);
vec3 dir = normalize(vec3(v.x*1.6, -v.y, -1.5));

vec4 p = raymarch(org, dir);
float glow = p.w;

vec4 col = mix(vec4(1.,.5,.1,1.), vec4(0.1,.5,1.,1.), p.y*.02+.4);

gl_FragColor = mix(vec4(0.), col, pow(glow*2.,4.));
//gl_FragColor = mix(vec4(1.), mix(vec4(1.,.5,.1,1.),vec4(0.1,.5,1.,1.),p.y*.02+.4), pow(glow*2.,4.));

}
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 24, 2019, 10:58:18 am
I used to play with it in my Objector but I didn't add it to OR ani shaders.

Thank you!

I'm currently adding a lot of PP shaders but they'll go into OR v3.0.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 24, 2019, 01:46:12 pm
Version #2.85 has been released.

For me, the next step would be to be able to adjust the mesh animation on the music tempo ;)

That could be done that way to retrieve the peek level

    if (gB.channel) {
        DWORD nLevel = BASS_ChannelGetLevel(gB.channel);
        float rValue = max(LOINT(nLevel), HIINT(nLevel)) / (float)67200;
        zTrace(STRF(rValue));
    }

then we have to combine the rValue peek level with rotate[0] and rotangle to follow the music tempo.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 24, 2019, 06:37:52 pm
then we have to combine the rValue peek level with rotate[0] and rotangle to follow the music tempo.

Easier said than done. It seems to me the sound we need to retreat to rely on isn't a peak level but low-frequency beat that sets forth the music overall tempo.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 24, 2019, 08:42:34 pm
I shall use exactly the same concept than with my BassBox plugins that served me well for two decades.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 24, 2019, 10:39:33 pm
Hey Patrice,

Here are all the standard post-processing shaders I'm planning to include in OR v3.00.

The only minus is they cannot be chained one after another; you have to choose the one that's the best, or none at all.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 25, 2019, 10:10:54 am
Thank you for the head's up, i don't know if they could help to enhance our existing 3D models, but they could produce for sure fancy 2D screen shots.

What about the glowing post processing effect you worked on, two years ago?
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 25, 2019, 12:47:27 pm
Glow isn't so much general aesthetic post-processing, but rather a sort of specific material like metal or glass or liquid. It differs from other ordinary materials in that it is supposed to have its dedicated texture map (called glow map) and preferably an own multi-buffer shader renderer.

And it wasn't two years ago. It was less than a year ago. But then I got distracted by other sorts of general-purpose post-processing and also by various screen anti-aliasing techniques. ObjReader is still very far from overall perfection, you know...
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 25, 2019, 02:07:11 pm
My friend

For the fun, try this with robots2, and the attached audio file

void gl_DrawScene() {
    if (gP.bGiration || gP.bUseFPS || gP.bAnimateLights || // lights/reset animation support added
        gP.bRotation || gP.bIsLerping || gP.tCurAniBkgndShader.nShaderID) // gP.bRotation, means meta #rotate is being used
        gP.bRedraw = TRUE;
    if (!gP.bRedraw || !IsWindowVisible(gP.hGL))
        return;

    gP.bDoneRender = TRUE;

    // PAT: 12-25-2019
    if (gB.channel) {
        DWORD nLevel = BASS_ChannelGetLevel(gB.channel);
        gP.rGiroStep = max(LOINT(nLevel), HIINT(nLevel)) / (float)67200;
        //zTrace(STRF(gP.rGiroStep));
    }

    static CHAR zMsg[16];
    static DWORD nCount, nFPS;


Note: i have to do the same with individual mesh rotation.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 25, 2019, 03:27:34 pm
void gl_DrawScene() {
    if (gP.bGiration || gP.bUseFPS || gP.bAnimateLights || // lights/reset animation support added
        gP.bRotation || gP.bIsLerping || gP.tCurAniBkgndShader.nShaderID) // gP.bRotation, means meta #rotate is being used
        gP.bRedraw = TRUE;
........

In fact that expression is extremely ugly and inefficient. All these flags should in fact be members of a union of 32 0/1 bitfields and a 32-bit BOOL, in which case that BOOL will remain TRUE for as long as at least one bitfield in it is set to 1. Then supposing the union is itself a member of gP, the check can be reduced to just one if() instead of many, i.e. speeded up at least 6 times.

And we will have yet 32-6=26 more bitfield flags reserved for possible future use. 8)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 25, 2019, 03:39:33 pm
Yep, that's a good suggestion!

BTW, audio sync works also now with individual mesh rotation, but it occures to me that perhaps we should have a new check box option,
to sync animation on audio.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 25, 2019, 03:42:26 pm
The effect is cool. And yes, please add that new checkbox to optionally sync the audio and animation.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 25, 2019, 04:11:10 pm
The Tor bitset manipulation could be handy to reduce drastically the size of the global properties for boolean flags.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 25, 2019, 07:23:21 pm
Ok, here is the full sync.zip file altogether with the new "Sync audio" check box.

Enjoy!
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 25, 2019, 08:43:44 pm
Thank you Patrice,

I was just out of my house for sometime...

Haha, the effect is real cool. I like it! :D

Thanks again!
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 25, 2019, 11:00:07 pm
Ahahahahahahahah!!! ;D ;D ;D ;D
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 27, 2019, 02:05:41 pm
Mike

1 - I think that "Sync audio" should be checked automatically when starting in "Play audio' mode.

2 - Do you think that it would it be possible to turn on #map_bump and the like, when using #billboard?

...
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 27, 2019, 03:02:23 pm
1. Whatever.

2. No, I don't think it will be possible or worth it to render billboards with anything other than diffuse maps.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 27, 2019, 06:55:10 pm
I am adding an extra parameter to
#playaudio Five_Circles.mp3 50 loop sync

in mobj.h
                } else if (strcmp(szBuffer, "#playaudio") == 0) {           // 10-09-2019 Bass.dll
                    s1[0] = 0; s2[0] = 0; s3[0] = 0; s4[0] = 0;
                    fgets(szBuffer, sizeof(szBuffer), pFile);
                    sscanf(szBuffer, "%s %s %s %s", s1, s2, s3, s4);
                    MultiByteToWideChar(CP_ACP, 0, s1, lstrlenA(s1), gB.playaudio, MAX_PATH);   // gB.playaudio the audio file to play
                    gB.volume = max((float) atof(s2) / 100.0f, 0.0625f);                        // gB.volume the audio volume percentage converted to float 0.0f to 1.0f
                    if (strcmp(s3, "loop") == 0) { gB.loop = TRUE; }                            // gB.loop "loop" means play in loop mode
                    if (strcmp(s4, "sync") == 0) { gP.bSyncAudio = TRUE; }                      // PAT: 12-27-2019 play animation in sync mode with audio


in gl_LoadModel from Main.cpp

    if (lstrlen(gB.playaudio)) {                                // 10-09-2019 Bass.dll
        hCtrl = GetDlgItem(gP.hMain, IDC_AUDIO);                // PAT: 11-05-2019
        SendMessage(hCtrl, BM_SETCHECK, BST_CHECKED, 0);        // PAT: 11-05-2019
        EnableWindow(hCtrl, TRUE);                              // PAT: 11-05-2019

        hCtrl = GetDlgItem(gP.hMain, IDC_GAUGE_VOLUME);         // PAT: 12-05-2019
        if (IsWindow(hCtrl)) { EnableWindow(hCtrl, TRUE); }     // PAT: 12-05-2019

        hCtrl = GetDlgItem(gP.hMain, IDC_SYNC_AUDIO);           // PAT: 12-25-2019
        EnableWindow(hCtrl, TRUE);
        if (gP.bSyncAudio) { SendMessage(hCtrl, BM_SETCHECK, BST_CHECKED, 0); } // PAT: 12-27-2019

        WCHAR zAudioFile[MAX_PATH] = { 0 };                     // 10-09-2019 Bass.dll
        Path_Combine(zAudioFile, gP.wModelPath, gB.playaudio);  // 10-09-2019 Bass.dll
        BassChannelPlay(zAudioFile);                            // 10-09-2019 Bass.dll
    }


and a small project to test with.

Strangely this simple project doesn't work with some of the shaders.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 28, 2019, 04:30:50 pm
I think i have found a work around.

Looks like, at least one mesh should use map_bump  ::)
then that works with all the animations...
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 28, 2019, 04:51:24 pm
Yes, this happens only with the models that have transparencies but no bumpmaps and are therefore rendered by FFP on default. You don't have to supply the missing bumpmaps; just uncheck the Use fixed pipeline menu, which will force the model to be rendered via a simple shader that appears fully compatible with the animated backgrounds.

Yet another argument to finally do away with the legacy immediate mode rendering... ::)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 28, 2019, 07:05:09 pm
Quote
Yet another argument to finally do away with the legacy immediate mode rendering
NO, there are things like ambient reflection that are widely used within the model collection, and so far they are working well only in legacy mode.

Here is a new Glow project that i am using to combine billboard and animations.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 28, 2019, 09:31:42 pm
NO, there are things like ambient reflection that are widely used within the model collection, and so far they are working well only in legacy mode.

No Patrice,

All such projects like Mark 17, Binome, R2D2, Pyramide, Projector etc. are working better with the simple Blinn-Phong shader that's capable of displaying "ambient reflection" much more precise, lighting-wise, than legacy immediate mode!  ::)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 28, 2019, 10:24:20 pm
Then please, take either Planar or Chromosaurus, and show me with the current OR, how to create the same effect with the simple Blin-Phong shader, to replace the code below in red, with the same result.

If you can do it, then i am eager to learn how to do it myself.

in Planar
newmtl planar
#rotate 0.15 0 1 0
Ka 1 1 1
Kd 1 1 1
Ks 3.5 2.5 2.5
Ns 512
d 0.9
illum 3
refl smoke.png


in Chromosaurus
newmtl chrome
Ka 0.71 0.71 0.71
Kd 1 1 1
Ks 2 2 2
Ns 225
illum 3
refl steel6.png

newmtl gold
Ka 0.71 0.71 0.71
Kd 1 1 1
Ks 2 2 2
Ns 12
illum 3
refl gold.png


Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 29, 2019, 12:31:36 am
Heh, while I'm scrutinizing you task ;), enjoy the following two very simple shaders. I think you're going to like them:

LightRays.fs:

Code: [Select]
uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)

float rayStrength(vec2 raySource, vec2 rayRefDirection, vec2 coord, float seedA, float seedB, float speed) {
vec2 sourceToCoord = coord - raySource;
float cosAngle = dot(normalize(sourceToCoord), rayRefDirection);

return clamp(
(0.45 + 0.15 * sin(cosAngle * seedA + iTime * speed)) +
(0.3 + 0.2 * cos(-cosAngle * seedB + iTime * speed)),
0.0, 1.0) *
clamp((iResolution.x - length(sourceToCoord)) / iResolution.x, 0.5, 1.0);
}

void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
uv.y = 1.0 - uv.y;
vec2 coord = vec2(gl_FragCoord.x, iResolution.y - gl_FragCoord.y);


// Set the parameters of the sun rays
vec2 rayPos1 = vec2(iResolution.x * 0.7, iResolution.y * -0.4);
vec2 rayRefDir1 = normalize(vec2(1.0, -0.116));
float raySeedA1 = 36.2214;
float raySeedB1 = 21.11349;
float raySpeed1 = 1.5;

vec2 rayPos2 = vec2(iResolution.x * 0.8, iResolution.y * -0.6);
vec2 rayRefDir2 = normalize(vec2(1.0, 0.241));
const float raySeedA2 = 22.39910;
const float raySeedB2 = 18.0234;
const float raySpeed2 = 1.1;

// Calculate the colour of the sun rays on the current fragment
vec4 rays1 =
vec4(1.0, 1.0, 1.0, 1.0) *
rayStrength(rayPos1, rayRefDir1, coord, raySeedA1, raySeedB1, raySpeed1);

vec4 rays2 =
vec4(1.0, 1.0, 1.0, 1.0) *
rayStrength(rayPos2, rayRefDir2, coord, raySeedA2, raySeedB2, raySpeed2);

gl_FragColor = rays1 * 0.5 + rays2 * 0.4;

// Attenuate brightness towards the bottom, simulating light-loss due to depth.
// Give the whole thing a blue-green tinge as well.
float brightness = 1.0 - (coord.y / iResolution.y);
gl_FragColor.x *= 0.1 + (brightness * 0.8);
gl_FragColor.y *= 0.3 + (brightness * 0.6);
gl_FragColor.z *= 0.5 + (brightness * 0.5);
    gl_FragColor.a = 1.0;
}

SideScroll.fs:

Code: [Select]
uniform vec4 iDate; // (year, month, day, time in seconds) MLL: year/month/day not used
uniform vec3 iMouse; // mouse pixel coords. xy: current (if MLB down); if vec3 then z: click
uniform vec2 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
uniform sampler2D stone_jpg;

void main() {
vec2 q = (gl_FragCoord.xy / iResolution.xy);
    vec2 uv = q - vec2(0.85);

    // Create a 3D point
    float h = 0.125; // MLL: horizon height
vec3 p = vec3(uv.x, uv.y - h - 1.0, uv.y - h);

    // Projecting back to 2D space
    vec2 uvm7 = p.xy / p.z;

    // Texture scaling if you need
    float scale = 0.5;
    uvm7 *= scale;

    // Rotations if needed
    float a = iTime * 0.05; // MLL: scroll speed
    mat2 rotation = mat2(cos(a), - sin(a), sin(a), cos(a));
    uvm7 *= rotation;

    // Read background texture
    vec3 col = texture(stone_jpg, uvm7).xyz;

    // Darkness based on the horizon
    col *= abs(uv.y - h - 0.005); // MLL: the smaller the number, the darker

    // Output the color
gl_FragColor = vec4(col, 1.0);
}

:)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 29, 2019, 10:47:41 am
Thank you!

Here is a link for more tileable textures

http://www.texturise.club

For sidescroll.fs i prefer to use the attached asphalt.jpg or concrete.jpg rather than stone.jpg
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 29, 2019, 11:03:10 am
BTW if you goto line 17 in TinyClouds.fs and change it to

        p.xz -= iTime;


you'll have the clouds flowing in the opposite direction, which will make the shader perfectly suitable for all sorts of your aircraft models facing the viewer as originally intended.

 :D
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 29, 2019, 05:07:33 pm
I am fixing the model right now to move transparent materials in sync with the body, also fixing a few triangulate errors resulting of the merging of several meshes altogether...
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 29, 2019, 06:40:28 pm
In the meantime, watch the Spitfire crossing La Manche. ;D

The scene is a merger of your new model, static aero wallpaper, and 2DClouds.fs shader with a reversed direction of cloud movement.  8)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 29, 2019, 07:33:22 pm
Excellent!

Here is the fully reworked model, even the pilot's head his moving slowly.
Everything is now fully in sync (not an easy task), and the small artefacts have been fixed.

Note: the audio track is the sound of a true Rolls Royce Merlin engine.

I did put a copy of the c4d project, to have a backup elsewhere ;)

The combination of sound and animation brings the models to life. ;)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 29, 2019, 07:53:38 pm
Awesome work, Patrice!

Thank you very much!
Title: Transformer
Post by: Patrice Terrier on December 30, 2019, 06:31:07 pm
For the fun of it...
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 30, 2019, 06:40:26 pm
Cool! ;D
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 31, 2019, 08:59:56 am
Re. Reply #156 on: December 28,

Patrice,

I do not know what you are talking about. It's been years since PPL became OR's default rendering pipeline, and its Blinn-Phong shader (the one that draws some mesh materials that don't use bumpmaps while other meshes do) is the shader that displays your illum 3 reflections, both"ambient" (wallpapered) and local (refl'ed in a specific material). And Use fixed pipeline, which is OR's prehistoric immediate-mode pipeline, stays unchecked at all times unless it comes across a mammoth-aged model that never used a single bumpmap in any of its materials.

PPL reflections are drawn with better quality than FFP ones, and they have smoother surfaces and superior, more uniform lighting. I cannot understand why you keep on clutching onto that deprecated pipeline. Gimme just one single example of a model that would need it to be rendered at least as good as it is rendered in PPL. Alas, you Planar and Chromosaurus both fail that simple comparison. ;)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 31, 2019, 10:08:55 am
Yes i am speaking of
the one that draws some mesh materials that don't use bumpmaps while other meshes do
using illum 3 or illum 4

Try using only this material with planar.

And add a zTrace into the FFP and PPL.

#multilight
#wallpaper @sanctuary.fs
#alphatocoverage
#playaudio Uncertain-Future.mp3 50 loop

newmtl planar
#rotate 0.15 0 1 0
Ka 1 1 1
Kd 1 1 1
Ks 3.5 2.5 2.5
Ns 512
d 0.9
illum 3
refl smoke.png


Then you will see that it is rendered into the drawUsingFixedFunctionPipeline

if you add this to force PPL

#multilight
#wallpaper @sanctuary.fs
#alphatocoverage
#playaudio Uncertain-Future.mp3 50 loop

newmtl planar
#rotate 0.15 0 1 0
Ka 1 1 1
Kd 1 1 1
Ks 3.5 2.5 2.5
map_bump neutral_bump.png
Ns 512
d 0.9
illum 3
refl smoke.png


Then it is rendered into the drawUsingProgrammablePipeline
loosing the reflection, even changing the other un-orthodoxe settings being used (shown in blue).
So far i am unable to recreate the same effects in PPL than in FFP.

illum 3 and illum 4, are currently not working in PPL mode, that was my point.

Added:
More exactly, it works in PPL mode, ONLY, if using the menu "Render" then "Ambient reflection". ;)
The gP.bSpecular flag seems to be enabled only when the menu is used, while it should be set also from the materail file.
Investigating...

Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 31, 2019, 01:25:58 pm
No, you are not correct, my friend!

If halo-less planar.obj is loaded without the bumpmap, it is rendered by FFP on default (menu is checked). But if you uncheck the menu to force PPL, FFP is cancelled, and the figure and cylinder are rendered by PPL's upper part that is called the Blinn-Phong shader. It comes in the drawUsingProgrammablePipeline() under this condition:

........
            // 12-09-2015 ML: !!! can't do "Specular mode" in multishader !!!
            // ML 01-18-2018: diffuse only mapping for billboards for now
            if (!pMaterial->bumpMapID || bSpecular || isBillboard) {

                // Bind the color map texture.  // ML: 11-26-2015
                glActiveTexture(GL_TEXTURE0);
                glEnable(GL_TEXTURE_2D);
........


It utilizes the shader that's called gR.blinnPhongShader:

........
                    goto doneBillboard;
                }

                // Per fragment Blinn-Phong code path.
                glUseProgram(gR.blinnPhongShader); // MLL 02-27-2018: bypass billboard code above

                // Update shader parameters.
                glUniform1f(glGetUniformLocation(gR.blinnPhongShader, "rDoFlat"), rDoFlat); // MLL 03-17-2019:
                glUniform1f(glGetUniformLocation(gR.blinnPhongShader, "rDoWire"), rDoWire); // MLL 07-01-2019:
                glUniform1i(glGetUniformLocation(gR.blinnPhongShader, "diffMap"), 0);
                glUniform1i(glGetUniformLocation(gR.blinnPhongShader, "nLights"), nLights); // ML: 12-11-2015
                glUniform1i(glGetUniformLocation(gR.blinnPhongShader, "nLightFlags"), nLightFlags); // ML 02-01-2018:
                glUniform1i(glGetUniformLocation(gR.blinnPhongShader, "bDoSpherical"), bDoSpherical); // ML: 11-26-2015
........


and it uses the bDoSpherical boolean uniform to switch on automatic spherical coordinate generation in the shader, which is equivalent to the legacy immediate mode

........
                        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
                        glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
                        glEnable(GL_TEXTURE_GEN_S);
                        glEnable(GL_TEXTURE_GEN_T);
........


commands.

On the other hand, if you try and add a bumpmap to the planar material, then spherical coord autogeneration becomes impossible, and the material is rendered through gR.normalMapShader in the lower else-branch of PPL material evaluation:

........
            } else {

                // Normal mapping code path.
                glUseProgram(gR.normalMapShader);

                // Bind the emission map texture. // MLL 12-08-2018:
                glActiveTexture(GL_TEXTURE6); bFlagBump = TRUE;
........


So, both FFP and PPL have built-in automatics to sense reflective materials with both global (wallpaper-based) and local (refl-based) "ambient" reflectance. The pipelines can simply be toggled with the Use fixed pipeline menu.

And finally, the Render->Ambient reflection menu is meant for any model with any set of materials to be optionally rendered entirely in the global wallpaper-based fancy "ambient" reflection mode. To me (and I am an average user in this case) it's as useless and pure fancy as any other shader in that section (gooch, cartoon, x-ray, etc.).

Hopefully, now you understand how "ambient reflection" works in OR and how entirely worthless its immediate mode is against the almighty programmable pipeline. ;)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 31, 2019, 01:55:50 pm
Quote
On the other hand, if you try and add a bumpmap to the planar material, then spherical coord autogeneration becomes impossible, and the material is rendered through gR.normalMapShader in the lower else-branch of PPL material evaluation

Yes, i forgot that bumpmap and reflection are incompatible, probably because of the nasty neurone decimation i have encountered since falling down from my roof.  ::)

Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 31, 2019, 02:32:00 pm
It's not that bad at all, my friend! :D

Tell you what: bumpmapping and reflection are incompatible only in the normal-map ubershader we're currently using for our most advanced materials including transparencies.

When we switch over to dedicated shaders for reflection/refraction materials like glass and water or mirrors, normal maps are going to become standard means for emulating complex-profile transparent reflective/refractive surfaces:
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 31, 2019, 02:50:49 pm
yes, this is what i was looking for :D
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on December 31, 2019, 10:01:23 pm
Good afternoon gentlemen...

Daisy, Daisy...

BTW, the shader "#wallpaper IntoThelight.fs" blows up OR, when started from a material file  ???
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on December 31, 2019, 11:54:42 pm
Hehe...  ;D Do you think such a small computer would be able to control the entire spaceship? I think it used to be the size of a mainframe.

IntoTheLight.fs works as-is by D&D. And it also works if renamed to IntoTheLite.fs and used locally:

#wallpaper @intothelite.fs

But it fails if specified as a global wallpaper regardless of name:

#wallpaper intothelite.fs

or

#wallpaper intothelight.fs

 :o ??? :-\

Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 01, 2020, 12:49:33 am
There is one glitch with Hal: if you zoom it out far enough, you will notice its logo HAL9000 disappear from time to time at certain distances. The same can be seen when it's zooming in via Animate reset on model load.

Is it possibly z-buffer fighting between the logo and leather mesh surfaces? :-\
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 01, 2020, 10:08:53 am
Quote
But it fails if specified as a global wallpaper regardless of name:
Yes, because it is the ame problem we already have

in the case of a wallpaper starting with a i intothelight.fs
it shokes in Mobj_importMaterials on

        case 'i': // illum
            fscanf(pFile, "%d", &nIllum);
            pMaterial->illum = nIllum;
            if (nIllum == 1) {
                pMaterial->specular[0] = 0.0f;
                pMaterial->specular[1] = 0.0f;
                pMaterial->specular[2] = 0.0f;
                pMaterial->specular[3] = 1.0f;
            }
            break;


Here is one solution to protect use agains the NULL pointer causing the havoc.

        case 'i': // illum
            fscanf(pFile, "%d", &nIllum);
            if (nIllum) { // PAT: 01-01-2020 avoid NULL pointer
                pMaterial->illum = nIllum;
                if (nIllum == 1) {
                    pMaterial->specular[0] = 0.0f;
                    pMaterial->specular[1] = 0.0f;
                    pMaterial->specular[2] = 0.0f;
                    pMaterial->specular[3] = 1.0f;
                }
            }
            break;
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 01, 2020, 10:40:04 am
No, I suggest

........
        case 'i': // illum
            if (strstr(szBuffer, "illum")) {
                fscanf(pFile, "%d", &nIllum);
                pMaterial->illum = nIllum;
                if (nIllum == 1) {
                    pMaterial->specular[0] = 0.0f;
                    pMaterial->specular[1] = 0.0f;
                    pMaterial->specular[2] = 0.0f;
                    pMaterial->specular[3] = 1.0f;
                }
            }
            break;
........


and all the problems with locality or name are gone. Besides, it matches how other cases isolate their parameters.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 01, 2020, 11:19:25 am
No, try with illumination.fs or just illum.fs
strstr alone is not enough even combined with a length of 5, because there could be no value following "illum".

illum is the only one assigning directly a pointer.

I have attached the new HAL version, indeed it is the hal monolith ;)

Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 01, 2020, 03:00:47 pm
No Patrice,

Your inference on pointers is completely wrong here!

&nIllum will always be non-NULL because nIllum is a valid long temp var that we allocate on the stack and pre-assign with a value of 0. If the fscanf() call fails, i.e. it is not a valid illum assignment but an unlucky chance of shader being called illum.fs or similar, then nIllum will still stay 0, which is still a valid illum value! See the reference table in renderers.h near line 455:

........
            //0 Color on and Ambient off
........


So, the only legit way to check if fscanf() worked as it should is to check its return value that will be non-zero if it is a valid illum assignment, and zero if it is just a clash of names and there is no any numeric parameter following the "illum" string:

........
        case 'i': // illum
            if (fscanf(pFile, "%d", &nIllum)) {
                pMaterial->illum = nIllum;
                if (nIllum == 1) {
                    pMaterial->specular[0] = 0.0f;
                    pMaterial->specular[1] = 0.0f;
                    pMaterial->specular[2] = 0.0f;
                    pMaterial->specular[3] = 1.0f;
                }
            }
            break;
........


The new Hal's logo behaves better indeed and disappears only once at its extreme far distance. Thank you! :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 01, 2020, 03:29:23 pm
Quote
if (fscanf(pFile, "%d", &nIllum)) {

Sold! ;)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 01, 2020, 05:34:20 pm
Here is a video link, to show you something i have been playing with  :o

video (http://www.objreader.com/download/video/lighting.mp4)

The idea would be to change on the fly the ambient lighting, perhaps in Mobj_lightSettings,
so far the video has been done on a change done directly into
drawUsingProgrammablePipeline
using this piece of blue code that should replace the line in red.

            //float diffuse[4];
            //diffuse[0] = pMaterial->diffuse[0];
            //diffuse[1] = pMaterial->diffuse[1];
            //diffuse[2] = pMaterial->diffuse[2];
            //diffuse[3] = pMaterial->diffuse[3];
            //if (gB.channel) {
            //    if (gP.bSyncAudio) { // PATH: 12-25-2019
            //        DWORD nLevel = BASS_ChannelGetLevel(gB.channel);
            //        float rPulse = (max(LOINT(nLevel), HIINT(nLevel)) / 20000.0f);
            //        diffuse[0] = rPulse;
            //        diffuse[1] = rPulse;
            //        diffuse[2] = rPulse;
            //    }
            //}
            //glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse[0]);

            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pMaterial->diffuse);
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pMaterial->specular);
            glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, pMaterial->emissive); // ML 01-02-2018: glow
            glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, pMaterial->shininess * rShine)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 01, 2020, 05:59:37 pm
Hehe, the idea is wonderful!

In fact, the ability to modulate anything with anything (e.g. an oscillator's input frequency with another frequency and/or its output phase and/or amplitude with some other phase and/or amplitude) was how music synthesizers were invented! :D
Title: Modulating the emissive channel
Post by: Patrice Terrier on January 03, 2020, 03:55:00 pm
I am testing the new #pulse meta with individual mesh, applying the modulation to the emissive channel.

See the changes i have done into sync.zip,
search for:
// PAT: 01-03-2020 Pulse light on sound modulation
and try it with the new attached HAL_9000.zip

Check with different audio tracks, and tell me what you think.

I am using an extra parameter to adjust the modulation level.

#pulse 1.0 (default) to 4.5 or more
the higher = the less sensitive, because of this computation
float rPulse = (max(LOINT(nLevel), HIINT(nLevel)) / (20000.0f * pMaterial->rPulseLevel));

Of course we could use the same for the other parameters...
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 03, 2020, 08:15:55 pm
Please update this function in mobj.h that somehow escaped sync'ing:

void Mobj_destroy() {
    gM.bHasPositions = false;
    gM.bHasTextureCoords = false;
    gM.bHasNormals = false;
    gM.bHasTangents = false;

    gM.numberOfVertexCoords = 0;
    gM.numberOfTextureCoords = 0;
    gM.numberOfNormals = 0;
    gM.numberOfTriangles = 0;
    gM.numberOfMaterials = 0;
    gM.numberOfMeshes = 0;
    gM.numberOfTextures = 0;

    gM.center[0] = gM.center[1] = gM.center[2] = 0.0f;
    gM.pose[0] = gM.pose[1] = gM.pose[2] = gM.pose[3] = gM.pose[4] =
        gM.pose[5] = gM.pose[6] = gM.pose[7] = gM.pose[8] = 0.0f;

    gM.rWidth = gM.rHeight = gM.rDepth = gM.rExtent = 0.0f;

    gsm_directoryPath.clear();

    gtm_meshes.clear();
    gtm_materials.clear();
    gtm_vertexBuffer.clear();
    gnm_indexBuffer.clear();
    gnm_attributeBuffer.clear();

    grm_vertexCoords.clear();
    grm_textureCoords.clear();
    grm_normals.clear();

    m_materialCache.clear();
    m_vertexCache.clear();

    deleteVBOs();
}


and also in mobj.h and renderers.h, please change all the remaining occurrences of true and false to TRUE and FALSE.


What regards light pulsing, HAL seems to be working but its implementation is not as elegant as the mainframe one. Can you better send me Robots2, the one that was there in your initial pulsed video? That model looked more coherent to my mind.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 03, 2020, 08:51:50 pm
TRUE/FALSE have been changed everywhere, and Mobj_Destroy() has been updated, thank you!

Quote
Can you better send me Robots2, the one that was there in your initial pulsed video?
This one was using diffuse rather than emissive.

I could add an extra parameter in the material file to select between KD, KS, KE and use a switch case into the PulseLight procedure.

Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 03, 2020, 09:22:23 pm
Actually, you can take any light component(s) as an input source to pulse but send the resultant pulse e.g. into the emissive component for output.

There are many variants what can be pulsed and where it can be output to. Have you tried to send the pulse (possibly overbrightened) to the specular component just to see what happens? ;)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 04, 2020, 03:44:55 pm
OK, here is the new release.
Now the new mtl parameters per material are
#pulse_A float_value (AMBIENT)
#pulse_D float_value (DIFFUSE
#pulse_S float_value (SPECULAR)
#pulse_E float_value (EMISSIVE)

New Robots2.mtl
Code: [Select]
#Light frontAmbient 0 0 0
#Light frontDiffuse 165 165 165
#Light frontSpecular 127 127 121

#Light leftAmbient 0 0 0
#Light leftDiffuse 127 127 121
#Light leftSpecular 47 79 79

#Light rightAmbient 0 0 0
#Light rightDiffuse 127 127 121
#Light rightSpecular 112 128 144

#Light topAmbient 0 0 0
#Light topDiffuse 25 25 112
#Light topSpecular 1 0 0

#multilight
#straylight 65
#wallpaper AniLights.fs
#playaudio Most_Geometric_Person.mp3 50 loop sync
#demo

newmtl mat_01
#rotate 0.05 0 0 1 359 361 0
#pulse_E 1
Ka 0.01 0.01 0.01
Kd 0.40000000596046 0.40000000596046 0.40000000596046
Ks 1 1 1
Ke 0.4 0.4 0.4
map_Ka mat_01_AO.png
map_Kd mat_01_ALB.png
map_bump mat_01_NRM.png
map_Ke mat_01_EMS.png
map_Ns mat_01_roughness.png
Ns 512
illum 2

newmtl mat_02
#rotate 0.05 0 0 1 359 361 0
Ka 0.01 0.01 0.01
Kd 0.40000000596046 0.40000000596046 0.40000000596046
Ks 1 1 1
map_Ka mat_02_AO.png
map_Kd mat_02_ALB.png
map_bump mat_02_NRM.png
map_Ns mat_02_roughness.png
Ns 512
illum 2

newmtl mat_03
#rotate -0.1275 0 1 0 0 0 0 1
#pulse_D 1
##pulse_E 2
Ka 0.01 0.01 0.01
Kd 0.39235669374466 0.39235669374466 0.39235669374466
Ks 1 1 1
Ke 0.35 0.35 0.35
map_Ka mat_03_AO.png
map_Kd mat_03_ALB.png
map_bump mat_03_NRM.png
map_Ke mat_03_EMS.png
Ns 512
illum 2

newmtl mat_04
#rotate -0.1275 0 1 0 0 0 0 1
#pulse_S 0.25
#pulse_D 2
##pulse_E 2
Ka 0.01 0.01 0.01
Kd 0.35159236192703 0.35159236192703 0.35159236192703
Ks 1 1 1
Ke 1 1 1
map_Ka mat_04_AO.png
map_Kd mat_04_ALB.png
map_bump mat_04_NRM.png
map_Ke mat_04_EMS.png
Ns 512
illum 2

See sync.zip for the changes that have been done.
Search for: // PAT: 01-04-2020
Note: the 2 new textures must be put into the robots2 folder
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 04, 2020, 05:04:12 pm
OK but where's Most_Geometric_Person.mp3?
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 04, 2020, 05:42:00 pm
Here it is.

I made an error in PulseLight, currently the settings are exclusive, while they should be cumulative
We must use if comparison rather than switch   :-[
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 04, 2020, 06:08:56 pm
Thank you!

Are you going to correct the sources now or later?
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 04, 2020, 06:11:33 pm
Use these

constants.h
Code: [Select]
#define AMBIENT                 1 // PAT: 01-04-2020 pulseID
#define DIFFUSE                 2 // PAT: 01-04-2020 pulseID
#define SPECULAR                4 // PAT: 01-04-2020 pulseID
#define EMISSIVE                8 // PAT: 01-04-2020 pulseID

mobj.h
Code: [Select]
                } else if (instr(szBuffer, "#pulse_") == 1) { // PAT: 01-04-2020 pulseID
                    if (fscanf(pFile, "%f", &pMaterial->rPulseLevel)) {
                        switch (szBuffer[7]) {
                        case 'a': // pulse_ambient
                            pMaterial->pulseID |= AMBIENT;
                            break;
                        case 'd': // pulse_diffuse
                            pMaterial->pulseID |= DIFFUSE;
                            break;
                        case 's': // pulse_specular
                            pMaterial->pulseID |= SPECULAR;
                            break;
                        case 'e': // pulse_emissive
                            pMaterial->pulseID |= EMISSIVE;
                            break;
                        default:
                            fgets(szBuffer, sizeof(szBuffer), pFile);
                            break;
                        }
                    }

renders.h
Code: [Select]
void PulseLight(MobjMat* pMaterial, IN float rShine) { // PAT: 01-04-2020 pulseID
            float ambient[4], diffuse[4], specular[4], emissive[4];
            ambient[0] = pMaterial->ambient[0];
            ambient[1] = pMaterial->ambient[1];
            ambient[2] = pMaterial->ambient[2];
            ambient[3] = pMaterial->ambient[3];

            diffuse[0] = pMaterial->diffuse[0];
            diffuse[1] = pMaterial->diffuse[1];
            diffuse[2] = pMaterial->diffuse[2];
            diffuse[3] = pMaterial->diffuse[3];

            specular[0] = pMaterial->specular[0];
            specular[1] = pMaterial->specular[1];
            specular[2] = pMaterial->specular[2];
            specular[3] = pMaterial->specular[3];

            emissive[0] = pMaterial->emissive[0];
            emissive[1] = pMaterial->emissive[1];
            emissive[2] = pMaterial->emissive[2];
            emissive[3] = pMaterial->emissive[3];

            if (gB.channel) {
                if ((pMaterial->pulseID) && (gP.bSyncAudio)) { // PAT: 01-04-2020 pulseID
                    DWORD nLevel = BASS_ChannelGetLevel(gB.channel);
                    float rPulse = (max(LOINT(nLevel), HIINT(nLevel)) / (20000.0f * pMaterial->rPulseLevel));
                    if (CheckStyle(pMaterial->pulseID, AMBIENT)) {
                        ambient[0] = rPulse;
                        ambient[1] = rPulse;
                        ambient[2] = rPulse;
                    }
                    if (CheckStyle(pMaterial->pulseID, DIFFUSE)) {
                        diffuse[0] = rPulse;
                        diffuse[1] = rPulse;
                        diffuse[2] = rPulse;
                    }
                    if (CheckStyle(pMaterial->pulseID, SPECULAR)) {
                        specular[0] = rPulse;
                        specular[1] = rPulse;
                        specular[2] = rPulse;
                    }
                    if (CheckStyle(pMaterial->pulseID, EMISSIVE)) {
                        emissive[0] = rPulse;
                        emissive[1] = rPulse;
                        emissive[2] = rPulse;
                    }
                }
            }

            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &ambient[0]);
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse[0]);
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &specular[0]);
            glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &emissive[0]);

            glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, pMaterial->shininess * rShine);
}
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 04, 2020, 06:39:29 pm
Everything seems to be working nicely, thank you!
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 04, 2020, 06:45:03 pm
Cumulative works as espected, and emissive could produce some kind of nice glow when used sparingly.
Title: BusterDrone
Post by: Patrice Terrier on January 04, 2020, 08:44:03 pm
To see the cumulative effects in action...
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 04, 2020, 08:58:33 pm
Aha! But where's the attachment?! :o

Oh, there it is! ;D

!!! COOL !!!  :D
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 04, 2020, 09:14:01 pm
I am very pleased of the result, that was exactly what i had in mind.

Next challenge should be the scene lighting.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 05, 2020, 06:37:29 am
I don't think the overall effect of modulating scene lighting ("straylight") would be much different from what you have now.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 05, 2020, 10:13:24 am
I was not thinking of straylight that is very obvious, but multilight using a custom color gradient to match the pulse level in Mobj_lightSettings.

And we could use this in the material file, just the same than with the new #pulse meta
#front_A (AMBIENT)
#front_D (DIFFUSE)
#front_S (SPECULAR)

#left_A (AMBIENT)
#left_D (DIFFUSE)
#left_S (SPECULAR)

#right_A (AMBIENT)
#right_D (DIFFUSE)
#right_S (SPECULAR)

#top_A (AMBIENT)
#top_D (DIFFUSE)
#top_S (SPECULAR)
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 05, 2020, 01:34:17 pm
I think there's no need to add new notation for light pulsing at all. You can just add more numeric parameters to the existing #Light frontAmbient 0 0 0 etc. lines. That #Light notation is already too bulky in there to still extend it any further with dozens of new #metas...
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 05, 2020, 02:03:11 pm
Now that the code is working well, i shall make a little code optimization to use BASS_ChannelGetLevel only once per gl_DrawScene call.
I shall try to use a colorLUT with lighting to see the effect it can produce.

Added:
Because lighting is global rather than mesh specific, the effect must be very subtle ???

See the attached code (search for // PAT: 01-05-2020)

and play with that one:

void gl_DrawScene() {
    if (gP.bGiration || gP.bUseFPS || gP.bAnimateLights || // lights/reset animation support added
        gP.bRotation || gP.bIsLerping || gP.tCurAniBkgndShader.nShaderID) // gP.bRotation, means meta #rotate is being used
        gP.bRedraw = TRUE;
    if (!gP.bRedraw || !IsWindowVisible(gP.hGL))
        return;

    gP.bDoneRender = TRUE;

    // PAT: 12-25-2019
    float rGiroStep = gP.rGiroStep;
    if (gB.channel) {
        if (gP.bSyncAudio) {
            DWORD nLevel = BASS_ChannelGetLevel(gB.channel);
            gP.audioLevel = max(LOINT(nLevel), HIINT(nLevel));
            rGiroStep = gP.audioLevel / (float)67200;

            // PAT: 01-05-2020
            // WARNING, this is for test only!
            long ColorRange = min((long) ((nLevel / 32767.0f)*32.0f), 32);
            BYTE a = 255, r = 0, g = 0, b = 0;
            ColorLUT(rand()%(33-ColorRange), r, g, b);
            //SETCOLORAMB(0);
            //SETCOLORDIF(0);
            //SETCOLORSPEC(0);
            //ColorLUT(ColorRange, r, g, b);
            SETCOLORDIF(1);
            SETCOLORDIF(2);
            SETCOLORDIF(3);

        }
    }

    static CHAR zMsg[16];
    static DWORD nCount, nFPS;
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 05, 2020, 07:04:27 pm
Seems to compile fine. Which model should I use to test?
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 05, 2020, 07:45:26 pm
you can try with robots2

try with this:
ColorLUT(ColorRange, r, g, b);
that will use the full range of the ColorLUT, mostly red in OR, because i have used the same LUT than in BassBox (for comparison purpose), but it is not well suited for OR.

you can also play with the
SETCOLORAMB
or the other settings

Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 06, 2020, 03:57:15 pm
Here is a minor fix:

void gl_DrawScene() {
    if (gP.bGiration || gP.bUseFPS || gP.bAnimateLights || // lights/reset animation support added
        gP.bRotation || gP.bIsLerping || gP.tCurAniBkgndShader.nShaderID || gP.bSyncAudio) // gP.bRotation, means meta #rotate is being used
        gP.bRedraw = TRUE;


Following your previous suggestion:
Rather than individual boolean flag, we could use power of 2 for each parameter, and use CheckStyle as i have done for PulseLight.
And a new global DWORD gP.DrawScene parameter to enable disable each of them, and get rid of all the extra boolean flags.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 06, 2020, 05:49:02 pm
Rather than individual boolean flag, we could use power of 2 for each parameter, and use CheckStyle as i have done for PulseLight.

In MS VC++, bitfields can be scoped within a union to an ordinary struct with a unique name for each bitfield, e.g.:

union {
    struct {
        unsigned int bGiration: 1 = 0; // type name: size in bits = initialization
        unsigned int bUseFPS: 1 = 0;
        unsigned int bAnimateLights: 1 = 0;
        unsigned int bRotation: 1 = 0;
        unsigned int bIsLerping: 1 = 0;
        unsigned int bSyncAudio: 1 = 0;
        unsigned int unused: 26 = 0; // currently unused
    }
    unsigned int reDraw;
}


which enables all the bitflags to be set/reset in their respective menu events exactly as they are now, whereas int reDraw (or gP.reDraw if the union is made part of gP) may be used in gl_DrawScene() as a unified BOOL flag:

if (gP.reDraw) // gP.bGiration == 1 and/or gP.bRotation == 1 etc.
        gP.bRedraw = TRUE;


gP.reDraw will stay non-FALSE (i.e. != 0) for as long as at least one named bitflag in its sibling struct in the union remains non-FALSE (i.e. != 0).
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 06, 2020, 09:39:36 pm
Thanks, i am not familiar with this bitfield construction i have to try it ;)

I have attached a new pulse animation...
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 07, 2020, 10:07:20 am
Looks neat! :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 07, 2020, 10:10:52 am
bit fields
https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=vs-2019

While this will preserve the current source code, it seems very specific to the C++ preprocessor, and thus hard to translate to another language more accustomed to use bitset.  :-[
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 07, 2020, 12:36:00 pm
0. I am not likely to translate the OR code into any other language besides CPP in the foreseeable future. Are you?

1. We aren't going to use bitfields wider than 1 bit, or bitfield structures other than 32 bits wide, so we aren't going to suffer from alignment problems described in the MSDN. Thus, the bitfield structure will always be exactly as wide as a DWORD. 32 bit flags are pretty much enough for all our needs as I can see them.

2. I've been using bitfields for decades without any problem for strong typing Variant variables in FBSL whenever I needed it for interfacing with strong data types in other languages (C and asm).
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 07, 2020, 03:56:26 pm
Visual Studio shokes on the use of the equal sign

union {
    struct {
        unsigned int bGiration: 1 = 0; // type name: size in bits = initialization
        unsigned int bUseFPS: 1 = 0;
        unsigned int bAnimateLights: 1 = 0;
        unsigned int bRotation: 1 = 0;
        unsigned int bIsLerping: 1 = 0;
        unsigned int bSyncAudio: 1 = 0;
        unsigned int unused: 26 = 0; // currently unused
    }
    DWORD reDraw;
}


Saying: this operator is not alowed in a constant expression.

Please send me the correct Struct PROP to use with it.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 07, 2020, 05:05:41 pm
Struct initialization is largely dependent on the C language standard a particular compiler supports.

VC doesn't allow C structures to be initialized the way I showed (FBSL used to be compiled using GCC). The VC way to define this union should be as follows: (compile as a console app)

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    union {
        struct {
            unsigned bGiration : 1; // type name: size in bits
            unsigned bUseFPS : 1;
            unsigned bAnimateLights : 1;
            unsigned bRotation : 1;
            unsigned bIsLerping : 1;
            unsigned bSyncAudio : 1;
            unsigned unused : 26; // currently unused
        };
        unsigned reDraw;
    } bFlag = { 0, 1, 0, 1, 0, 1, 0 }; // initialization

    printf("flags: %d %d %d %d %d %d, reDraw = %d, evaluates to %s\n", bFlag.bGiration, bFlag.bUseFPS, bFlag.bAnimateLights,
        bFlag.bRotation, bFlag.bIsLerping, bFlag.bSyncAudio, bFlag.reDraw, bFlag.reDraw ? "TRUE" : "FALSE");

    bFlag.reDraw = 0; // zeroize all bitflags at once

    printf("flags: %d %d %d %d %d %d, reDraw = %d, evaluates to %s\n", bFlag.bGiration, bFlag.bUseFPS, bFlag.bAnimateLights,
        bFlag.bRotation, bFlag.bIsLerping, bFlag.bSyncAudio, bFlag.reDraw, bFlag.reDraw ? "TRUE" : "FALSE");
   
    return 0;
}


Alternatively, if the compiler supports the C99 standard, it can use what's called Designated Initialization, or selective initialization of members in an arbitrary order:

........
    } bFlag = { .bGiration = 0, .bAnimateLights = 0, .bIsLerping = 0,
                .bUseFPS = 1, .bRotation = 1, .bSyncAudio = 1 }; // initialization


to the exact same effect.

Elsewhere throughout the code, the bit flags may be assigned, compared, etc. just like any other ordinary struct or union members.

The bFlag{} union may go into the gP structure as any other of its existing member fields.
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 09, 2020, 07:36:58 pm
Mike

I have done the code change, thank you!

Today i had to sort a problem i have with my fixed landline that is hacked (again) by pirate calling surtaxed phone number using my own number.
I already had this problem on last december 19 and 20, and i did filed a complaint at the gendarmerie...
Because of the recurrence i took the decision to cancel my landline phone number, and i have installed a new internet box to use a "Gigaset trio" to replace my previous fixed phones.

That kept me busy the whole day to reinstall everything on my local network.

Yesterday i made a personnal version of the Bot_Assasin project, to see how far i could go with a concept i had in mind.
and the result of my work named "Star surfer" has been posted in the "animation" collection.
Try it with different audio songs.
Title: Re: Animated Backgrounds?
Post by: Michael Lobko-Lobanovsky on January 11, 2020, 05:03:45 pm
Your star surfer is very impressive, my friend! :)
Title: Re: Animated Backgrounds?
Post by: Patrice Terrier on January 11, 2020, 07:55:20 pm
Quote
Your star surfer is very impressive
Yes, i like it very much :)

I have just solved right now a problem i had with FileZilla since i installed my new box.
The symptom, i was unable to display the folder content once connected via ftp to the OR server. :(

I had to install WinSCP to replace FileZilla and solve this issue (i wasted the whole day trying to find a solution).

But the good news is that my new box is much faster than the previous one
upload 7804 ko
download 43192 Ko
not bad for a DSL line ;)

BTW, thanks to the new global #pose meta that allows us to use sky dome or box wall.