/* | |
* Copyright (C) 2016 The Android Open Source Project | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
#include <string> | |
std::string g_shader = R"( | |
// various noise functions | |
float Hash2d(vec2 uv) | |
{ | |
float f = uv.x + uv.y * 47.0; | |
return fract(cos(f*3.333)*100003.9); | |
} | |
float Hash3d(vec3 uv) | |
{ | |
float f = uv.x + uv.y * 37.0 + uv.z * 521.0; | |
return fract(cos(f*3.333)*100003.9); | |
} | |
float mixP(float f0, float f1, float a) | |
{ | |
return mix(f0, f1, a*a*(3.0-2.0*a)); | |
} | |
const vec2 zeroOne = vec2(0.0, 1.0); | |
float noise2d(vec2 uv) | |
{ | |
vec2 fr = fract(uv.xy); | |
vec2 fl = floor(uv.xy); | |
float h00 = Hash2d(fl); | |
float h10 = Hash2d(fl + zeroOne.yx); | |
float h01 = Hash2d(fl + zeroOne); | |
float h11 = Hash2d(fl + zeroOne.yy); | |
return mixP(mixP(h00, h10, fr.x), mixP(h01, h11, fr.x), fr.y); | |
} | |
float noise2dT(vec2 uv) | |
{ | |
vec2 fr = fract(uv); | |
vec2 smooth = fr*fr*(3.0-2.0*fr); | |
vec2 fl = floor(uv); | |
uv = smooth + fl; | |
return texture2D(iChannel0, (uv + 0.5)/iChannelResolution[0].xy).y; // use constant here instead? | |
} | |
float noise(vec3 uv) | |
{ | |
vec3 fr = fract(uv.xyz); | |
vec3 fl = floor(uv.xyz); | |
float h000 = Hash3d(fl); | |
float h100 = Hash3d(fl + zeroOne.yxx); | |
float h010 = Hash3d(fl + zeroOne.xyx); | |
float h110 = Hash3d(fl + zeroOne.yyx); | |
float h001 = Hash3d(fl + zeroOne.xxy); | |
float h101 = Hash3d(fl + zeroOne.yxy); | |
float h011 = Hash3d(fl + zeroOne.xyy); | |
float h111 = Hash3d(fl + zeroOne.yyy); | |
return mixP( | |
mixP(mixP(h000, h100, fr.x), mixP(h010, h110, fr.x), fr.y), | |
mixP(mixP(h001, h101, fr.x), mixP(h011, h111, fr.x), fr.y) | |
, fr.z); | |
} | |
float PI=3.14159265; | |
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); | |
} | |
float Density(vec3 p) | |
{ | |
//float ws = 0.06125*0.125; | |
//vec3 warp = vec3(noise(p*ws), noise(p*ws + 111.11), noise(p*ws + 7111.11)); | |
float final = noise(p*0.06125);// + sin(iGlobalTime)*0.5-1.95 + warp.x*4.0; | |
float other = noise(p*0.06125 + 1234.567); | |
other -= 0.5; | |
final -= 0.5; | |
final = 0.1/(abs(final*final*other)); | |
final += 0.5; | |
return final*0.0001; | |
} | |
void mainImage( out vec4 fragColor, in vec2 fragCoord ) | |
{ | |
// ---------------- First, set up the camera rays for ray marching ---------------- | |
vec2 uv = fragCoord.xy/iResolution.xy * 2.0 - 1.0;// - 0.5; | |
// Camera up vector. | |
vec3 camUp=vec3(0,1,0); // vuv | |
// Camera lookat. | |
vec3 camLookat=vec3(0,0.0,0); // vrp | |
float mx=iMouse.x/iResolution.x*PI*2.0 + iGlobalTime * 0.01; | |
float my=-iMouse.y/iResolution.y*10.0 + sin(iGlobalTime * 0.03)*0.2+0.2;//*PI/2.01; | |
vec3 camPos=vec3(cos(my)*cos(mx),sin(my),cos(my)*sin(mx))*(200.2); // 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 | |
// -------------------------------------------------------------------------------- | |
float t = 0.0; | |
float inc = 0.02; | |
float maxDepth = 70.0; | |
vec3 pos = vec3(0,0,0); | |
float density = 0.0; | |
// ray marching time | |
for (int i = 0; i < 37; i++) // This is the count of how many times the ray actually marches. | |
{ | |
if ((t > maxDepth)) break; | |
pos = camPos + relVec * t; | |
float temp = Density(pos); | |
//temp *= saturate(t-1.0); | |
inc = 1.9 + temp*0.05; // add temp because this makes it look extra crazy! | |
density += temp * inc; | |
t += inc; | |
} | |
// -------------------------------------------------------------------------------- | |
// Now that we have done our ray marching, let's put some color on this. | |
vec3 finalColor = vec3(0.01,0.1,1.0)* density*0.2; | |
// output the final color with sqrt for "gamma correction" | |
fragColor = vec4(sqrt(clamp(finalColor, 0.0, 1.0)),1.0); | |
} | |
)"; |