Adapted Cloud shaders


This page is really a good source for shader examples. I have adapted a couple of shaders at Hifi. But first, look at the picture please, which show, why I want only cloud shaders.

[PS: I did but then changed my mind later. The terrain slightly smaller than the buildable area, and penetrated by a plane with the same Ocean shader as the skybox.]

Now here the URLs to the adapted shaders:

I do not like really this shaders. Any problem have all. Most, the clouds are too big, or you see a significant curvature. But I do not know GLSL, perhaps you can improve the adaption.

I think it would be better, if iChannel0/1 would be supports, and so you would can use images as noise source. Corresponding shaders on “shadertoy” looked interesting.

How do shaders like 'Ocean Skybox' work?

I’m the co-manager of the domain “Music” and on behalf of @KevinMThomas I should ask you how the workflow of downloading and converting the skyboxes from shaderthoys to hifi is.
Kevin and his team, consisting of Kevin and his 3 minions, tried to download a skybox from shadertoy the whole afternoon.


Sea/Water rendering

@Konstantin (look to cloudy_sunset.fs ;-))
In other posts to shaders I collected the following steps:

  1. create this line at the begin of the shader, so you get error messages with line numbers. (without quotation marks)
    "#line 2"

  2. undefine variables: define it. par example iResolution and iMouse.
    vec3 iResolution =;
    vec2 iMouse = vec2(0);
    vec3 iMouse = vec3(0);

  3. create the function getSkyboxColor() and call mainImage():
    vec3 getSkyboxColor()
        vec3 rayDirection = normalize(_normal);
        vec2 position = rayDirection.xy;
        position += 0.5;
        position.y = 1.0 - position.y;
        //position.y = 0 + position.y; //180° turn
        vec4 result;
        mainImage(result, position * iWorldScale.xy);

That was all. More I have not changed at the original shaders. To step 3, entities need the function getProceduralColor() instead of getSkyboxColor(). But at this topic I am working now. I need an ocean shader. :wink:

PS: iChannel is not supported in Hifi. So you can not use images as noise source. Correspondig shaders from shadertoy I could not adapt.


You don’t download the skybox. You apply the shader to it.


Ok, AlphaVersionD was faster. :slight_smile:


I would like to make this one into HiFi


I think, the function snoise() and the called subfuntions are defined in Hifi. Please little moment, I try it out.


Yes, you do not need snoise() and the called subfunctions. This functions are defined in Hifi. But it is an unsatisfactory result again. Unfortunately I do not know the shader language GLSL, and so I can not resolve it.


Thank you @JuelsDreki I really appreciate it.


Unfortunately, So it looks at my domain too. i search self help with the adapted shaders. :wink:


Ok, iChannel0 is still supported. I must have misunderstood something. Into the user data field of the skybox zone I wrote this:


The noise images you can find here:

So I could use the variable iChannel0 in the shader 2d_fast_clouds.fs. But one problem remains. The shaders of shadertoy behave in Hifi different. Where is the cause? What needs to be changed?

shader 2d_fast_clouds.fs: you can see works it at my domain hifi://juels-craft-hut/0,10,0.
at shadertoys:


Ok, the theme overwhelmed me. GLSL self is as C similar language not the problem. But I do not understand the mathematical background. I found only very scientific publications and not any step by step instructions. I think, I’ll continue to use static skyboxes, until usable solutions are accessible for natural skyboxes.


Skybox shaders tend to look best when the original author has accounted for 3D space. See also my adaptation of an ocean shader.



Nice ocean. :slight_smile:

Yes exactly that is the problem. The shaders are not intended for 3D. And without understanding the mathematical background you can not change that.


If I added commenting to the walk-through “ID” performed, would you find it helpful?

Try adding this shader to a regular Sphere Entity… the commenting should assist in helping diagnose what part of the maths does what.

For example, examine the shape of a Sine wave. It goes up and down up and down up and down forever. You as a programmer can leverage this. Arctangents can be used for radial effects… etc etc… too much information to put here, but what I can tell you is the “ocean” that I took from shadertoy and applied to HiFi, uses 3D Wave form functions.

Anyway, here is the code for a neat “eyeball” effect. Enjoy!

vec3 iResolution = vec3(iWorldScale.xz, 1.0);
vec3 col=vec3(1.0);
float hash( float n ) { return fract(sin(n)753.5453123); }
float noise( in vec2 x )
vec2 p = floor(x);
vec2 f = fract(x);
f = 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.x
					mix( hash(n+113.0),	hash(n+114.0),f.x),     mix( hash(n+270.0), hash(n+271.0),f.x),		f.y

					mix( hash(n+337.0),	hash(n+339.0),f.y),     mix( hash(n+559.0), hash(n+559.0),f.y),		f.x


mat2 m = mat2( 0.8, 0.6, -0.6, 0.8);
float fbm( vec2 p )
float f = 0.0;
f += 0.5000noise( p );
f += 0.2500
noise( p );
f += 0.1250
noise( p );
f+= 0.0625
noise( p );
f /= 0.9375;
return f;

void mainImage( out vec4 fragColor, in vec2 fragCoord )
vec2 q = fragCoord.xy / iResolution.xy;
vec2 p = -1.0 + 2.0*q;
//aspect ratio fix… divide the width by the height (landscape mode)
// p.x *= iResolution.x/iResolution.y;

//draw a circle with polar coordinates
float r = sqrt( dot(p,p)/2.6 );
float a = atan(p.y,p.x);

float ss = 0.5 + 0.5*sin(8.0*iGlobalTime);
float anim =  1.0 + 0.1*ss*clamp(1.0-r,0.0,1.0);
r *= anim;

if( r<0.9 )
    //set the color of the eye
 	col = vec3( 0.2, 0.3, 0.4) ;

    //add variation
    float f = fbm( 1.173*p );

    //mix the color into the variation
    col = mix( col, vec3(0.2,0.5,0.4), f );

    //add a new ring of color (this is a variation of the base color, so use f)
    f = 1.0 - smoothstep(0.2, 0.5, r);
    col = mix( col, vec3(0.9, 0.6, 0.2), f);

    //apply some domain distortion (helps make things look organic and natural)
    //adjust the amplitude and frequency to suit.
    a += 0.1*fbm( 20.0 * p );        

    //add some white into it... (use polar coordinates so radiates from center)
    //add some contrast by smoothstepping the fbm
    f = smoothstep( 0.3, 1.0, fbm( vec2(5.0*r,20.0*a) ) );
    col = mix(col, vec3(1.0), f);

    //add different colors by copying the white addition...
    //change the frequency of the fbm so they do not completely overlayp
    f = smoothstep( 0.4, 0.9, fbm( vec2(10.0*r,15.0*a) ) );
    //modulate the color by multiplying by f
    col *= 1.0 - 0.5*f; 

    //add a volume effect to the eyeball
    f = smoothstep( 0.5, 0.8, r);
    col *= 1.0 - 0.5*f;

	//add the pupil on top of the previously added iris
    f = smoothstep ( 0.2, 0.23, r);
	col *= f;

    //anit-alias the edges
    f = smoothstep( 0.75, 0.8, r);
    col = mix( col, vec3(1.0), f );

fragColor = vec4(col,1.0);


vec4 getProceduralColor() {
vec2 position = _position.xz;
position += 0.5;
position.y = 1.0 - position.y;
vec4 result;
mainImage(result, position * iWorldScale.xz);
return result;


Thank you very much for that example. I’ve recreated it step by step.

I indicate 3 main steps:

  1. Generate dimensional noise with the function noise().
  2. Generate multidimensional noise with the function fbm();
  3. Create the procedural picture with the function mainImage();

The noise method I could not recognize.

fbm() method is the Fractional Brownian motion:
"- FBM is a class of centered Gaussian processes.

  • A Gaussian process is in probability theory a stochastic process
    in which every finite subset of random variables multidimensional
    normal distribution (Gaussian distribution) is.
  • A Gaussian process describes the Gaussian distribution of a continuum
      of random variables and in particular a Gaussian distribution of functions."

In other words: The function noise() generate dimensional random values.
This result be used through the function fbm(). The new result is a multidimensional
noise. The parameter p affect the noise density/frequency.

For all steps there are different methods, and it determine the look of the procedural texture. An now my steps:

I hope, this will help me, to write an own shader. :slight_smile:


I would rotate the eyeball to an other place, but it does nothing.

I think the vector to its place is (x;y;z) = (0;1;?). The new place should be the horizon, but the changing of x and y does not works.

    vec2 q = fragCoord.xy / iResolution.xy;    
    vec2 p = -1.0 + 2.0*q;

    vec2 q = fragCoord.xy / iResolution.xy;    
vec2 p = -1.0 + 2.0*q;
    float temp;
    temp = p.x;
    p.x = p.y;
    p.y = temp;

The multiplication with the rotation matrix (90°) was not the solution too.

    vec2 q = fragCoord.xy / iResolution.xy;    
    vec2 p = -1.0 + 2.0*q;
    mat2 m = mat2(
        0, -1,
        1, 0
    p *= m;

Something I have fundamentally misunderstand. :frowning:


Is this book recommended?


Ok. I think, I understand the basic operation now. The skybox shader is not a sphere, in wich I can move or rotate objects. The shader is executed repeatedly, you get in every pass new world coordinates. For the actually coordinates you must calculate the fragment/“pixel” color.

I recreate the first skybox shader of @AlphaVersionD. Sure mathematically not so elegant. :wink:

#line 2”

#define SKYCOLOR    vec3(0.29, 0.68, 0.98)”
#define FOGCOLOR    vec3(0.68, 0.85, 0.98)”
#define OCEANCOLOR    vec3(0.07, 0.05, 0.98)”

//Resolution X, Y, Z (ratio , by default 1.0)
vec3 iResolution = vec3(iWorldScale.xz, 1.0);

// We set the seconds (iDate.w) of iDate to iGlobalTime, which contains the current date in seconds
//vec4 iDate = vec4(0, 0, 0, iGlobalTime);

vec3 getSkyboxColor()
    vec3 rayDir = normalize(_normal);
    float pos = rayDir.y;
    vec3 col = SKYCOLOR;
    float r = sqrt( dot(pos,pos) );    //vector length = radius
    float smooth_to_fog = 0.0;
    /***** Calculate Sky /
    if( pos > 0.0 )
        col = SKYCOLOR;
        smooth_to_fog = 1.0 - smoothstep(0.025, 0.2, r);
Calculate Ocean *****/
    else if( pos <= 0.0 )
        col = OCEANCOLOR;
        smooth_to_fog = 1.0 - smoothstep(0.01, 0.05, r);

/***** Mix sky or ocean with fog *****/
    col = mix( col, FOGCOLOR, smooth_to_fog);
    return col;


Fast you are on your way to shader excellence. I wish I could claim ownership of the “eyeball” shader it is not one of my own. Only one that I have replicated and add comment to the code. Yes, you have the basic concept of what the shader “is” meaning you will decide upon the “color” of the “pixel” at runtime.

There have been discussions about rendering the shader used for skybox in a different manner, in order to accelerate the runtime / frames per second within the pipeline.

If you desire to eliminate all color from a pixel, remember to use discard and the pixel will vanish. See also Quarroball in Marketplace.