Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef GL_ES
- precision highp float;
- #endif
- uniform float time;
- uniform vec2 resolution;
- uniform float screenDistance;
- uniform vec3 cameraLocation;
- uniform vec3 cameraForward;
- uniform vec3 cameraUp;
- vec3 mod289(vec3 x) {
- return x - floor(x * (1.0 / 289.0)) * 289.0;
- }
- vec2 mod289(vec2 x) {
- return x - floor(x * (1.0 / 289.0)) * 289.0;
- }
- vec3 permute(vec3 x) {
- return mod289(((x*34.0)+1.0)*x);
- }
- float snoise(vec2 v)
- {
- const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
- 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
- -0.577350269189626, // -1.0 + 2.0 * C.x
- 0.024390243902439); // 1.0 / 41.0
- // First corner
- vec2 i = floor(v + dot(v, C.yy) );
- vec2 x0 = v - i + dot(i, C.xx);
- // Other corners
- vec2 i1;
- //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
- //i1.y = 1.0 - i1.x;
- i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
- // x0 = x0 - 0.0 + 0.0 * C.xx ;
- // x1 = x0 - i1 + 1.0 * C.xx ;
- // x2 = x0 - 1.0 + 2.0 * C.xx ;
- vec4 x12 = x0.xyxy + C.xxzz;
- x12.xy -= i1;
- // Permutations
- i = mod289(i); // Avoid truncation effects in permutation
- vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
- + i.x + vec3(0.0, i1.x, 1.0 ));
- vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
- m = m*m ;
- m = m*m ;
- // Gradients: 41 points uniformly over a line, mapped onto a diamond.
- // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
- vec3 x = 2.0 * fract(p * C.www) - 1.0;
- vec3 h = abs(x) - 0.5;
- vec3 ox = floor(x + 0.5);
- vec3 a0 = x - ox;
- // Normalise gradients implicitly by scaling m
- // Approximation of: m *= inversesqrt( a0*a0 + h*h );
- m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
- // Compute final noise value at P
- vec3 g;
- g.x = a0.x * x0.x + h.x * x0.y;
- g.yz = a0.yz * x12.xz + h.yz * x12.yw;
- return 130.0 * dot(m, g);
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- // Basic random function used in interpolation functions for purlin noise.
- // Inputs:
- // co: The coordinate to generate a random value for.
- // Result:
- // A random value for that coordinate, the same coordinate used again
- // returns the same value.
- /////////////////////////////////////////////////////////////////////////////////////////
- float rand(in vec2 co){
- return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- // Applies cosine interpolation on the interval 'a' to 'b', and returns the
- // result at slice 'x' where 'x' ranges from 0.0 to 1.0.
- /////////////////////////////////////////////////////////////////////////////////////////
- float cosineInterpolation(in float a, in float b, in float x) {
- float ft = x * 3.1415927;
- float f = (1.0 - cos(ft)) * 0.5;
- return a * (1.0 - f) + b * f;
- }
- float linearInterpolation(in float a, in float b, in float x) {
- return a * (1.0 - x) + b * x;
- }
- // a switch for which interpolation to use
- float interpolate(in float a, in float b, in float x) {
- //return linearInterpolation(a, b, x);
- return cosineInterpolation(a, b, x);
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- // A wrapper for rand(in vec2 co) that smoothes out its values.
- /////////////////////////////////////////////////////////////////////////////////////////
- float smoothedNoise2(in vec2 co) {
- float corners = (rand(vec2(co.x-1.0,co.y-1.0)) +
- rand(vec2(co.x+1.0,co.y-1.0)) +
- rand(vec2(co.x-1.0,co.y+1.0)) +
- rand(vec2(co.x+1.0,co.y+1.0))) / 16.0;
- float sides = (rand(vec2(co.x-1.0, co.y)) +
- rand(vec2(co.x, co.y+1.0)) +
- rand(vec2(co.x+1.0, co.y)) +
- rand(vec2(co.x-1.0, co.y-1.0))) / 8.0;
- float centre = rand(vec2(co)) / 4.0;
- return corners + sides + centre;
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- // Cosine interpolation wrapper for the smoothNoise2(in vec2 co) function.
- // This function gives ya the smooth curvy surface.
- /////////////////////////////////////////////////////////////////////////////////////////
- float interpolate2(in vec2 co) {
- float intX = floor(co.x);
- float fractX = fract(co.x);
- float intY = floor(co.y);
- float fractY = fract(co.y);
- float v1 = smoothedNoise2(vec2(intX, intY));
- float v2 = smoothedNoise2(vec2(intX + 1.0, intY));
- float v3 = smoothedNoise2(vec2(intX, intY + 1.0));
- float v4 = smoothedNoise2(vec2(intX + 1.0, intY + 1.0));
- float i1 = interpolate(v1, v2, fractX);
- float i2 = interpolate(v3, v4, fractX);
- return cosineInterpolation(i1, i2, fractY);
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- // Purlin Noise, the star of the show, Purlin Noise can be used for generating
- // many different types of textures, as well as making other effects, such
- // as clouds.
- /////////////////////////////////////////////////////////////////////////////////////////
- float purlinNoise(in vec2 co, in float persistance, in float numOctaves) {
- float total = 0.0;
- float frequency = 1.0;
- float amplitude = 1.0;
- float i;
- for (i = 0.0; i < numOctaves; i = i + 1.0) {
- total += interpolate2(co * frequency) * amplitude;
- frequency *= 2.0;
- amplitude *= persistance;
- }
- return total;
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- // Defines our current terrain as a height map function
- /////////////////////////////////////////////////////////////////////////////////////////
- float noise2f(in float x, in float z) {
- //return rand(vec2(x*0.0001,z*0.0001)) * 2.0 - 1.0;
- //return interpolate2(vec2(x,z)) * 2.0 - 1.0;
- return cos(x) * sin(z);
- //return cos(x + 0.001 * sin(z)) * sin(z);
- //return 0.0;
- //return noise1(vec2(x, z));
- //return fract(snoise(vec2(x, z)));
- //return sin(length(vec2(x,z)));
- //return sin(cos(length(vec2(x,z))) + sin(z));
- //return sin(x * z * 0.001);
- }
- /////////////////////////////////////////////////////////////////////////////////////////
- // Calculates the origin and direction of the ray to use in ray marching for
- // the current fragment coordinate.
- /////////////////////////////////////////////////////////////////////////////////////////
- void calculateRay(out vec3 ro, out vec3 rd) {
- vec3 up = normalize(cameraUp);
- vec3 forward = normalize(cameraForward);
- vec3 right = cross(cameraForward, cameraUp);
- rd.x = (gl_FragCoord.x - resolution.x * 0.5) * right.x;
- rd.x += (gl_FragCoord.y - resolution.y * 0.5) * up.x;
- rd.x += screenDistance * forward.x;
- rd.y = (gl_FragCoord.x - resolution.x * 0.5) * right.y;
- rd.y += (gl_FragCoord.y - resolution.y * 0.5) * up.y;
- rd.y += screenDistance * forward.y;
- rd.z = (gl_FragCoord.x - resolution.x * 0.5) * right.z;
- rd.z += (gl_FragCoord.y - resolution.y * 0.5) * up.z;
- rd.z += screenDistance * forward.z;
- rd = normalize(rd);
- ro = cameraLocation;
- }
- float dSpace(in vec3 p, out float id) {
- // distance to the sphere
- float d1 = length(mod(p,100.0) - vec3(50.0)) - 20.0;
- // distance to cylinder
- float d2 = length(mod(p.xy,100.0) - vec2(50.0)) - 5.0;
- // distance to cylinder
- float d3 = length(mod(p.yz,100.0) - vec2(50.0)) - 5.0;
- // distance to cylinder
- float d4 = length(mod(p.zx,100.0) - vec2(50.0)) - 5.0;
- // find the nearest
- float nearestD = min(min(d1, d2), min(d3, d4));
- id = 1.0;
- if (nearestD == d2) { id = 2.0; }
- if (nearestD == d3) { id = 3.0; }
- if (nearestD == d4) { id = 4.0; }
- return nearestD;
- }
- vec3 nSpace(in vec3 p, in float id) {
- if (id > 0.5 && id < 1.5) {
- return normalize(mod(p,100.0) - vec3(50.0));
- } else if (id > 1.5 && id < 2.5) {
- return normalize(vec3((mod(p,100.0) - vec3(50.0)).xy, 0.0));
- } else if (id > 2.5 && id < 3.5) {
- return normalize(vec3((mod(p,100.0) - vec3(50.0)).zy, 0.0));
- } else {
- return normalize(vec3((mod(p,100.0) - vec3(50.0)).zx, 0.0));
- }
- return normalize(vec3(1.0));
- }
- float castRay(in vec3 ro, in vec3 rd, out float id) {
- float minT = 10.0;
- float maxT = 5000.0;
- float minStep = 5.0;
- float t;
- float dist;
- float dt;
- vec3 p;
- float lastDist = dSpace(ro, id);
- for (t = minT; t < maxT; t += dt) {
- p = ro + t * rd;
- dist = dSpace(p, id);
- if (dist < 0.001) {
- float a = (dist - lastDist) / dt;
- float b = dist - a * t;
- float resT = abs(-b / a);
- return resT;
- }
- dt = max(dist, minStep);
- lastDist = dist;
- }
- return -1.0;
- }
- float intersect(in vec3 ro, in vec3 rd, out float resT) {
- float id = -1.0;
- float t = castRay(ro, rd, id);
- resT = t;
- return id;
- }
- //// FOG /////////////////////////////////
- vec3 applyFog( in vec3 rgb, // original color of the pixel
- in float dist ) // camera to point distance
- {
- float fogAmount = exp( -dist*0.0005 );
- vec3 fogColor = vec3(0.5,0.6,0.7);
- return mix( rgb, fogColor, 1.0 - fogAmount );
- }
- //////////////////////////////////////////
- void main() {
- vec3 light = normalize(vec3(0.57703, 0.57703, -0.57703));
- // uv are the pixel coordinates, from 0 to 1
- vec2 uv = gl_FragCoord.xy / resolution.xy;
- gl_FragColor = vec4(1.0,uv.x,uv.y,1.0);
- // generate a ray with origin ro and direction rd
- vec3 ro;
- vec3 rd;
- calculateRay(ro, rd);
- // intersect the ray with the 3d scene
- float t;
- float id = intersect(ro, rd, t);
- // draw black by default
- vec3 col = vec3(0.0);
- if (id > 0.5) {
- vec3 pos = ro + t * rd;
- vec3 nor = nSpace(pos, id);
- float dif = clamp(dot(nor, light), 0.0, 1.0);
- float amb = 0.5 + 0.5 * nor.y;
- col = vec3(1.0, 0.8, 0.6) * dif + amb * vec3(0.5, 0.6, 0.7);
- }
- if (id > 0.0) {
- col = applyFog(col, t);
- } else {
- col = applyFog(col, 10000.0);
- }
- gl_FragColor = vec4(col, 1.0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement