1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <string>
18 
19 std::string g_shader = R"(
20 
21 // various noise functions
22 float Hash2d(vec2 uv)
23 {
24     float f = uv.x + uv.y * 47.0;
25     return fract(cos(f*3.333)*100003.9);
26 }
27 float Hash3d(vec3 uv)
28 {
29     float f = uv.x + uv.y * 37.0 + uv.z * 521.0;
30     return fract(cos(f*3.333)*100003.9);
31 }
32 float mixP(float f0, float f1, float a)
33 {
34     return mix(f0, f1, a*a*(3.0-2.0*a));
35 }
36 const vec2 zeroOne = vec2(0.0, 1.0);
37 float noise2d(vec2 uv)
38 {
39     vec2 fr = fract(uv.xy);
40     vec2 fl = floor(uv.xy);
41     float h00 = Hash2d(fl);
42     float h10 = Hash2d(fl + zeroOne.yx);
43     float h01 = Hash2d(fl + zeroOne);
44     float h11 = Hash2d(fl + zeroOne.yy);
45     return mixP(mixP(h00, h10, fr.x), mixP(h01, h11, fr.x), fr.y);
46 }
47 float noise2dT(vec2 uv)
48 {
49     vec2 fr = fract(uv);
50     vec2 smooth = fr*fr*(3.0-2.0*fr);
51     vec2 fl = floor(uv);
52     uv = smooth + fl;
53     return texture2D(iChannel0, (uv + 0.5)/iChannelResolution[0].xy).y; // use constant here instead?
54 }
55 float noise(vec3 uv)
56 {
57     vec3 fr = fract(uv.xyz);
58     vec3 fl = floor(uv.xyz);
59     float h000 = Hash3d(fl);
60     float h100 = Hash3d(fl + zeroOne.yxx);
61     float h010 = Hash3d(fl + zeroOne.xyx);
62     float h110 = Hash3d(fl + zeroOne.yyx);
63     float h001 = Hash3d(fl + zeroOne.xxy);
64     float h101 = Hash3d(fl + zeroOne.yxy);
65     float h011 = Hash3d(fl + zeroOne.xyy);
66     float h111 = Hash3d(fl + zeroOne.yyy);
67     return mixP(
68         mixP(mixP(h000, h100, fr.x), mixP(h010, h110, fr.x), fr.y),
69         mixP(mixP(h001, h101, fr.x), mixP(h011, h111, fr.x), fr.y)
70         , fr.z);
71 }
72 
73 float PI=3.14159265;
74 
75 vec3 saturate(vec3 a)
76 {
77     return clamp(a, 0.0, 1.0);
78 }
79 vec2 saturate(vec2 a)
80 {
81     return clamp(a, 0.0, 1.0);
82 }
83 float saturate(float a)
84 {
85     return clamp(a, 0.0, 1.0);
86 }
87 
88 float Density(vec3 p)
89 {
90     //float ws = 0.06125*0.125;
91     //vec3 warp = vec3(noise(p*ws), noise(p*ws + 111.11), noise(p*ws + 7111.11));
92     float final = noise(p*0.06125);// + sin(iGlobalTime)*0.5-1.95 + warp.x*4.0;
93     float other = noise(p*0.06125 + 1234.567);
94     other -= 0.5;
95     final -= 0.5;
96     final = 0.1/(abs(final*final*other));
97     final += 0.5;
98     return final*0.0001;
99 }
100 
101 void mainImage( out vec4 fragColor, in vec2 fragCoord )
102 {
103     // ---------------- First, set up the camera rays for ray marching ----------------
104     vec2 uv = fragCoord.xy/iResolution.xy * 2.0 - 1.0;// - 0.5;
105 
106     // Camera up vector.
107     vec3 camUp=vec3(0,1,0); // vuv
108 
109     // Camera lookat.
110     vec3 camLookat=vec3(0,0.0,0);   // vrp
111 
112     float mx=iMouse.x/iResolution.x*PI*2.0 + iGlobalTime * 0.01;
113     float my=-iMouse.y/iResolution.y*10.0 + sin(iGlobalTime * 0.03)*0.2+0.2;//*PI/2.01;
114     vec3 camPos=vec3(cos(my)*cos(mx),sin(my),cos(my)*sin(mx))*(200.2);  // prp
115 
116     // Camera setup.
117     vec3 camVec=normalize(camLookat - camPos);//vpn
118     vec3 sideNorm=normalize(cross(camUp, camVec));  // u
119     vec3 upNorm=cross(camVec, sideNorm);//v
120     vec3 worldFacing=(camPos + camVec);//vcv
121     vec3 worldPix = worldFacing + uv.x * sideNorm * (iResolution.x/iResolution.y) + uv.y * upNorm;//scrCoord
122     vec3 relVec = normalize(worldPix - camPos);//scp
123 
124     // --------------------------------------------------------------------------------
125     float t = 0.0;
126     float inc = 0.02;
127     float maxDepth = 70.0;
128     vec3 pos = vec3(0,0,0);
129     float density = 0.0;
130     // ray marching time
131     for (int i = 0; i < 37; i++)    // This is the count of how many times the ray actually marches.
132     {
133         if ((t > maxDepth)) break;
134         pos = camPos + relVec * t;
135         float temp = Density(pos);
136         //temp *= saturate(t-1.0);
137 
138         inc = 1.9 + temp*0.05;  // add temp because this makes it look extra crazy!
139         density += temp * inc;
140         t += inc;
141     }
142 
143     // --------------------------------------------------------------------------------
144     // Now that we have done our ray marching, let's put some color on this.
145     vec3 finalColor = vec3(0.01,0.1,1.0)* density*0.2;
146 
147     // output the final color with sqrt for "gamma correction"
148     fragColor = vec4(sqrt(clamp(finalColor, 0.0, 1.0)),1.0);
149 }
150 
151 
152 )";
153