[Solved] Porting Shadertoy shaders to Ogre Topic is solved

Problems building or running the engine, queries about how to use features etc.
Post Reply
tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

[Solved] Porting Shadertoy shaders to Ogre

Post by tritonas00 »

Ogre Version: 13.5.3
Operating System: Arch Linux
Render System: OpenGL

Hi! I'm trying to to convert some shaders from Shadertoy to Ogre. First attempt is https://www.shadertoy.com/view/4tdSWr. Managed to render it:

Image

As i'm very new to this a have some questions:

1 How to make the shader animate? Tried to set iTime as a uniform but no luck. Does it have to be done in the vertex shader?

2 How to cancel the rotation? Currently it seems its following the camera. Demo:

3 How to get the viewport resolution properly? (iResolution)

example.vert

Code: Select all

uniform mat4 worldViewProj;
attribute vec4 vertex;

void main(void)
{
    vec4 P = vertex;
    gl_Position = worldViewProj * P;
}

example.frag

Code: Select all

const float cloudscale = 1.1;
const float speed = 0.03;
const float clouddark = 0.5;
const float cloudlight = 0.3;
const float cloudcover = 0.2;
const float cloudalpha = 8.0;
const float skytint = 0.5;
const vec3 skycolour1 = vec3(0.2, 0.4, 0.6);
const vec3 skycolour2 = vec3(0.4, 0.7, 1.0);
const mat2 m = mat2( 1.6,  1.2, -1.2,  1.6 );

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));	
}

float fbm(vec2 n) {
    float total = 0.0, amplitude = 0.1;
    for (int i = 0; i < 7; i++) {
        total += noise(n) * amplitude;
        n = m * n;
        amplitude *= 0.4;
    }
    return total;
}

void main(void)
{
    vec3 iResolution = vec3(1600, 900, 1); // eeh
    float iTime = 1.0; // eeh

    vec2 p = gl_FragCoord.xy / iResolution.xy;
    vec2 uv = p*vec2(iResolution.x/iResolution.y,1.0);    
    float time = iTime * speed;
    float q = fbm(uv * cloudscale * 0.5);
    
    //ridged noise shape
    float r = 0.0;
    uv *= cloudscale;
    uv -= q - time;
    float weight = 0.8;
    for (int i=0; i<8; i++){
        r += abs(weight*noise( uv ));
        uv = m*uv + time;
        weight *= 0.7;
    }
    
    //noise shape
    float f = 0.0;
    uv = p*vec2(iResolution.x/iResolution.y,1.0);
    uv *= cloudscale;
    uv -= q - time;
    weight = 0.7;
    for (int i=0; i<8; i++){
        f += weight*noise( uv );
        uv = m*uv + time;
        weight *= 0.6;
    }
    
    f *= r + f;
    
    //noise colour
    float c = 0.0;
    time = iTime * speed * 2.0;
    uv = p*vec2(iResolution.x/iResolution.y,1.0);
    uv *= cloudscale*2.0;
    uv -= q - time;
    weight = 0.4;
    for (int i=0; i<7; i++){
        c += weight*noise( uv );
        uv = m*uv + time;
        weight *= 0.6;
    }
    
    //noise ridge colour
    float c1 = 0.0;
    time = iTime * speed * 3.0;
    uv = p*vec2(iResolution.x/iResolution.y,1.0);
    uv *= cloudscale*3.0;
    uv -= q - time;
    weight = 0.4;
    for (int i=0; i<7; i++){
        c1 += abs(weight*noise( uv ));
        uv = m*uv + time;
        weight *= 0.6;
    }
	
    c += c1;
    
    vec3 skycolour = mix(skycolour2, skycolour1, p.y);
    vec3 cloudcolour = vec3(1.1, 1.1, 0.9) * clamp((clouddark + cloudlight*c), 0.0, 1.0);
   
    f = cloudcover + cloudalpha*f*r;
    
    vec3 result = mix(skycolour, clamp(skytint * skycolour + cloudcolour, 0.0, 1.0), clamp(f + c, 0.0, 1.0));

    gl_FragColor = vec4( result, 1.0 );
}

The material:

Code: Select all

vertex_program myVertexShader glsl
{
    source example.vert

    default_params
    {
        param_named_auto worldViewProj worldviewproj_matrix
    }
}

fragment_program myFragmentShader glsl
{
    source example.frag
}

material tracks/skyboxcol
{
    technique
    {
        pass
        {
            vertex_program_ref myVertexShader
            {
            }
            fragment_program_ref myFragmentShader
            {
            }
        }
    }
}

Also a funny experiment with https://www.shadertoy.com/view/Ms2SD1 with a very dated mod loaded :lol:

Image

Last edited by tritonas00 on Wed Nov 01, 2023 9:08 am, edited 3 times in total.
rpgplayerrobin
Gnoll
Posts: 619
Joined: Wed Mar 18, 2009 3:03 am
x 353

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by rpgplayerrobin »

Point 1 and 3:
You add those parameters in the fragment or vertex program parameters.
In your case it is in the fragment parameters of course, since it is in the fragment shader that they are missing.
Search for "param_indexed_auto" here: https://ogrecave.github.io/ogre/api/13/ ... d_005fauto
And to find parameters you need, check here: https://ogrecave.github.io/ogre/api/13/ ... 24f0d43ce3
So for your example it would be:

Code: Select all

param_named_auto iTime time
param_named_auto resolutionX viewport_width
param_named_auto resolutionY viewport_height

Do not forget to also add those variables to the fragment shader code, something like this:

Code: Select all

uniform float iTime;
uniform float resolutionX;
uniform float resolutionY;

Point 2:
They are quite clear in the shader that those are 2D clouds.
If you want to handle it in 3D you would have to make a 3D noise instead, but then you would also have to handle where it is going to be located, and 3D noise is really slow (normal noise is also pretty slow though).
But I guess you could just create a plane and use the 2D clouds on that instead, and not use it as a compositor like you seem to be doing right now, then just place that plane on the top of the scene (where clouds are usually located).

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by tritonas00 »

Thank you very much, it helped a lot!

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by tritonas00 »

So im trying with a plane:

Code: Select all

Ogre::Plane plane;
plane.d = 1000;
plane.normal = Ogre::Vector3::NEGATIVE_UNIT_Y;

Ogre::MeshManager::getSingleton().createPlane("sky", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
    plane, 5000, 5000, 1, 1, true, 1, 1, 1, Ogre::Vector3::UNIT_Z); 

Ogre::Entity* entity = App::GetGfxScene()->GetSceneManager()->createEntity("sky");
entity->setMaterialName("tracks/skyboxcol"); 
entity->setCastShadows(false); 

auto node = App::GetGfxScene()->GetSceneManager()->getRootSceneNode()->createChildSceneNode();
node->attachObject(entity); 

It seems it always follows the movement of the camera instead of staying in place. Demo:

Tried setFixedYawAxis but no luck. Any idea what i'm doing wrong? Don't want the sky to follow the camera.

User avatar
sercero
Bronze Sponsor
Bronze Sponsor
Posts: 449
Joined: Sun Jan 18, 2015 4:20 pm
Location: Buenos Aires, Argentina
x 156

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by sercero »

I don't think you will be able to rotate the sky with the camera.

That is because the sky is just a background image that gets rendered behind the other objects.

To get the kind of sky you want you should generate a skybox.

paroj
OGRE Team Member
OGRE Team Member
Posts: 1994
Joined: Sun Mar 30, 2014 2:51 pm
x 1074
Contact:

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by paroj »

you are using gl_FragCoord as input to the shader, which are the pixel coordinates on your screen. So no matter what you do with the plane, this will cancel it out.

rpgplayerrobin
Gnoll
Posts: 619
Joined: Wed Mar 18, 2009 3:03 am
x 353

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by rpgplayerrobin »

Paroj is right, you need to use the actual texture coordinates (uv) of the plane instead of using iResolution and gl_FragCoord.

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by tritonas00 »

Yep you are absolutely right.

I will post the complete shader soon.

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by tritonas00 »

vertex shader

Code: Select all

#version 400

uniform mat4 worldViewProj;

attribute vec4 vertex;
attribute vec2 uv0;

out vec2 f_texcoord;

void main(void)
{
    gl_Position = worldViewProj * vertex;
    f_texcoord = uv0;
}

fragment shader

Code: Select all

#version 400

const float cloudscale = 1.1;
const float speed = 0.03;
const float clouddark = 0.5;
const float cloudlight = 0.3;
const float cloudcover = 0.2;
const float cloudalpha = 8.0;
const float skytint = 0.5;
const vec3 skycolour1 = vec3(0.2, 0.4, 0.6);
const vec3 skycolour2 = vec3(0.4, 0.7, 1.0);
const mat2 m = mat2( 1.6,  1.2, -1.2,  1.6 );

uniform float iTime;

in vec2 f_texcoord;

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));	
}

float fbm(vec2 n) {
    float total = 0.0, amplitude = 0.1;
    for (int i = 0; i < 7; i++) {
        total += noise(n) * amplitude;
        n = m * n;
        amplitude *= 0.4;
    }
    return total;
}

void main(void)
{
    vec2 p = f_texcoord;
    vec2 uv = p;

    float time = iTime * speed;
    float q = fbm(uv * cloudscale * 0.5);
    
    //ridged noise shape
    float r = 0.0;
    uv *= cloudscale;
    uv -= q - time;
    float weight = 0.8;
    for (int i=0; i<8; i++){
        r += abs(weight*noise( uv ));
        uv = m*uv + time;
        weight *= 0.7;
    }
    
    //noise shape
    float f = 0.0;
    uv = p;
    uv *= cloudscale;
    uv -= q - time;
    weight = 0.7;
    for (int i=0; i<8; i++){
        f += weight*noise( uv );
        uv = m*uv + time;
        weight *= 0.6;
    }
    
    f *= r + f;
    
    //noise colour
    float c = 0.0;
    time = iTime * speed * 2.0;
    uv = p;
    uv *= cloudscale*2.0;
    uv -= q - time;
    weight = 0.4;
    for (int i=0; i<7; i++){
        c += weight*noise( uv );
        uv = m*uv + time;
        weight *= 0.6;
    }
    
    //noise ridge colour
    float c1 = 0.0;
    time = iTime * speed * 3.0;
    uv = p;
    uv *= cloudscale*3.0;
    uv -= q - time;
    weight = 0.4;
    for (int i=0; i<7; i++){
        c1 += abs(weight*noise( uv ));
        uv = m*uv + time;
        weight *= 0.6;
    }
	
    c += c1;
    
    vec3 skycolour = mix(skycolour2, skycolour1, p.y);
    vec3 cloudcolour = vec3(1.1, 1.1, 0.9) * clamp((clouddark + cloudlight*c), 0.0, 1.0);
   
    f = cloudcover + cloudalpha*f*r;
    
    vec3 result = mix(skycolour, clamp(skytint * skycolour + cloudcolour, 0.0, 1.0), clamp(f + c, 0.0, 1.0));

    gl_FragColor = vec4( result, 1.0 );
}

material

Code: Select all

vertex_program myVertexShader glsl
{
    source example.vert

    default_params
    {
        param_named_auto worldViewProj worldviewproj_matrix
    }
}

fragment_program myFragmentShader glsl
{
    source example.frag
}

material tracks/skyboxcol
{
    technique
    {
        pass
        {
            vertex_program_ref myVertexShader
            {
            }
            fragment_program_ref myFragmentShader
            {
                param_named_auto iTime time
            }
        }
    }
}

plane

Code: Select all

Ogre::Plane plane;
plane.d = 1000;
plane.normal = Ogre::Vector3::NEGATIVE_UNIT_Y;

Ogre::MeshManager::getSingleton().createPlane("sky", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
    plane, 5000, 5000, 1, 1, true, 1, 1, 1, Ogre::Vector3::UNIT_Z); 

Ogre::Entity* entity = App::GetGfxScene()->GetSceneManager()->createEntity("sky");
entity->setMaterialName("tracks/skyboxcol"); 
entity->setCastShadows(false); 

auto node = App::GetGfxScene()->GetSceneManager()->getRootSceneNode()->createChildSceneNode();
node->attachObject(entity); 
tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by tritonas00 »

Made some minimal changes and having fun with it

Now looking for a nice looking water 2d shader surface so i can hook it in our water plane.

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by tritonas00 »

Water tryouts using https://www.shadertoy.com/view/4slBWN and sampler2D texture

Image

Need to figure how to get rid the repeat patterns though. Need to find a better texture probably.

loath
Platinum Sponsor
Platinum Sponsor
Posts: 290
Joined: Tue Jan 17, 2012 5:18 am
x 67

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by loath »

this was really cool to see. thanks for sharing!

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by tritonas00 »

Is it possible someone with shader knowledge to help with this https://www.shadertoy.com/view/MdXyzX ?

Would like to just have the water, to hook it in a plane. I can remove sky/sun but having trouble to project the water as 2d correctly.

User avatar
Crystal Hammer
Gnome
Posts: 317
Joined: Sat Jun 23, 2007 5:16 pm
x 77
Contact:

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by Crystal Hammer »

Looks cool, sure. There are plenty of awesome shaders there.
The only problem I got with them is their license, which is by default CC-BY-NC-SA 3.0. See https://www.shadertoy.com/terms
And most of shaders don't change it, I rarely saw shaders that specify other license like MIT or CC0 etc.
I'm not a lawyer, but from what I understood (years ago) CC-BY-NC-SA is not something we could use in a Free Software project, inside official repositories. I saw there was some bare minimum version of RoR there (1 vehicle, empty track?). So using such shaders in there wouldn't be possible. Am I still right?

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [13.5.3] Porting Shadertoy shaders to Ogre

Post by tritonas00 »

Crystal Hammer wrote: Thu Dec 22, 2022 6:02 pm

Looks cool, sure. There are plenty of awesome shaders there.
The only problem I got with them is their license, which is by default CC-BY-NC-SA 3.0. See https://www.shadertoy.com/terms
And most of shaders don't change it, I rarely saw shaders that specify other license like MIT or CC0 etc.
I'm not a lawyer, but from what I understood (years ago) CC-BY-NC-SA is not something we could use in a Free Software project, inside official repositories.

Hi! I'm not going to use those shaders in game, i did some minimal porting from shadertoy to start learning the basics. What i'm aiming to use though is this nice water:
https://github.com/muckSponge/Optically ... #L205-L415
https://github.com/muckSponge/Optically-Realistic-Water

I think that will fit very nicely in RoR. We are going full ahead with RTSS terrain, RTSS PSSM3, per-pixel lighting, PBR mats so its time to have some nice water and sky also :D

Also ported this shader https://www.shadertoy.com/view/ltdXRS, just for fun.

Crystal Hammer wrote: Thu Dec 22, 2022 6:02 pm

I saw there was some bare minimum version of RoR there (1 vehicle, empty track?). So using such shaders in there wouldn't be possible. Am I still right?

Base RoR installation contains 2-3 vehicles and a simple terrain. Shaders will be included in RoR's codebase replacing current ones, and they work globally, for all terrains.

tritonas00
Halfling
Posts: 87
Joined: Sun Apr 08, 2018 2:21 pm
x 36

Re: [SOLVED] Porting Shadertoy shaders to Ogre

Post by tritonas00 »

Ported one more shadertoy shader to Ogre https://www.shadertoy.com/view/4sKGWt and changed a bit to have moving clouds and some other settings.

Image

Code: https://github.com/tritonas00/rigs-of-rods/commits/sky

Post Reply