summaryrefslogtreecommitdiff
path: root/shaders/clouds.kage
blob: 26597e5ba24528ee124c99512e851c6ef1e8fc4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//go:build ignore

//kage:unit pixels

package main

var Time float

const cloudscale = 0.8
const speed = 0.01
const clouddark = 0.6
const cloudlight = 0.3
const cloudcover = 0.2
const cloudalpha = 8.0
const skytint = 0.5

func rand(co vec2) float {
    return fract(sin(dot(co.xy, vec2(12.9898,-78.233))) * 43758.5453)
}

func hash( p vec2  ) vec2 {
	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)
}

func noise( p vec2  ) float {
    const K1 = 0.366025404
    const K2 = 0.211324865
	i := floor(p + (p.x+p.y)*K1);	
    a := p - i + (i.x+i.y)*K2

    var o vec2
    if (a.x>a.y) {
      o = vec2(1.0,0.0)
    } else {
      o = vec2(0.0,1.0)
    }

    b := a - o + K2
	c := a - 1.0 + 2.0*K2
    h := max(0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0)
	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))
}



func fbm(n vec2) float {
    v := n
	total := 0.0
    amplitude := 0.1
	for i := 0; i < 7; i++ {
		total += noise(v) * amplitude
		v = mat2(1.6,  1.2, -1.2,  1.6)  * v
		amplitude *= 0.4
	}
	return total
}

func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
    m := mat2(1.6,  1.2, -1.2,  1.6)
    skycolour1 := vec3(0.45, 0.57, 0.66)
    skycolour2 := vec3(0.55, 0.77, 0.86)

    p := srcPos.xy / imageSrc0Size().xy;
	uv := p*vec2(imageSrc0Size().x/imageSrc0Size().y,1.0);    
    time := Time * speed
    q := fbm(uv * cloudscale * 0.5)

    //ridged noise shape
	r := 0.0
	uv *= cloudscale
    uv.x -= q - time
    weight := 0.8
    for i:=0; i<8; i++{
		r += abs(weight*noise( uv ))
        uv = m*uv + time
		weight *= 0.7
    }

    //noise shape
	f := 0.0
	uv = p*vec2(imageSrc0Size().x/imageSrc0Size().y,1.0);    
	uv *= cloudscale
    uv.x -= q - time
    weight = 0.7
    for i:=0;i<8;i++{
		f += weight*noise( uv )
        uv = m*uv + time
		weight *= 0.6
    }
    
    f *= r + f

    //noise colour
    c := 0.0
    time = Time * speed * 2.0
    uv = p*vec2(imageSrc0Size().x/imageSrc0Size().y,1.0)
	uv *= cloudscale*2.0
    uv.x -= q - time
    weight = 0.4
    for i:=0;i<7;i++{
		c += weight*noise( uv )
        uv = m*uv + time
		weight *= 0.6
    }

    //noise ridge colour
    c1 := 0.0
    time = Time * speed * 3.0
    uv = p*vec2(imageSrc0Size().x/imageSrc0Size().y,1.0)
	uv *= cloudscale*3.0
    uv.x -= q - time
    weight = 0.4
    for i:=0; i<7; i++{
		c1 += abs(weight*noise( uv ))
        uv = m*uv + time
		weight *= 0.6
    }
	
    c += c1

    skycolour := mix(skycolour2, skycolour1, p.y);
    cloudcolour := vec3(1.1, 1.1, 0.9) * clamp((clouddark + cloudlight*c), 0.0, 1.0);
   
    f = cloudcover + cloudalpha*f*r;
    
    result := mix(skycolour, clamp(skytint * skycolour + cloudcolour, 0.0, 1.0), clamp(f + c, 0.0, 1.0));
    
	return vec4( result, 1.0 );
}