vec3 srgbToLinear2(vec3 srgb){ return mix( srgb / 12.92, pow(.947867 * srgb + .0521327, vec3(2.4) ), step( .04045, srgb ) ); } vec3 blackbody2(float Temp) { float t = pow(Temp, -1.5); float lt = log(Temp); vec3 col = vec3(0.0); col.x = 220000.0 * t + 0.58039215686; col.y = 0.39231372549 * lt - 2.44549019608; col.y = Temp > 6500. ? 138039.215686 * t + 0.72156862745 : col.y; col.z = 0.76078431372 * lt - 5.68078431373; col = clamp(col,0.0,1.0); col = Temp < 1000. ? col * Temp * 0.001 : col; return srgbToLinear2(col); } // Integer Hash - II // - Inigo Quilez, Integer Hash - II, 2017 // https://www.shadertoy.com/view/XlXcW4 uvec3 iqint2(uvec3 x) { const uint k = 1103515245u; x = ((x>>8U)^x.yzx)*k; x = ((x>>8U)^x.yzx)*k; x = ((x>>8U)^x.yzx)*k; return x; } uvec3 hash(vec2 s) { uvec4 u = uvec4(s, uint(s.x) ^ uint(s.y), uint(s.x) + uint(s.y)); // Play with different values for 3rd and 4th params. Some hashes are okay with constants, most aren't. return iqint2(u.xyz); } vec3 hash31(float p) { vec3 p3 = fract(vec3(p) * vec3(.1031, .1030, .0973)); p3 += dot(p3, p3.yzx+33.33); return fract((p3.xxy+p3.yzz)*p3.zyx); } ///////////////// POSITION ///////////////// POSITION ///////////////// POSITION vec3 RandomPosition = hash31(frameTimeCounter); vec3 ManualLightPos = vec3(ORB_X, ORB_Y, ORB_Z); float densityAtPosFog(in vec3 pos){ pos /= 18.; pos.xz *= 0.5; vec3 p = floor(pos); vec3 f = fract(pos); f = (f*f) * (3.-2.*f); vec2 uv = p.xz + f.xz + p.y * vec2(0.0,193.0); vec2 coord = uv / 512.0; vec2 xy = texture2D(noisetex, coord).yx; return mix(xy.r,xy.g, f.y); } vec3 LightSourcePosition(vec3 WorldPos, vec3 CameraPos){ vec3 Origin = WorldPos ; // make the swirl only happen within a radius float SwirlBounds = clamp(sqrt(length(vec3(Origin.x,Origin.y-100,Origin.z)) / 150.0 - 1.0) ,0.0,1.0); if( SwirlBounds < 1.0) { Origin.y -= 200; } else { Origin = WorldPos - CameraPos ; #ifdef THE_ORB if(ManualLightPos == 0.0){ #endif float nosie = (densityAtPosFog(Origin / 30 + sin(frameTimeCounter/5)*100)-0.15) * 15 ; Origin.xz += vec2( sin(nosie),-cos(nosie) )*50; Origin.y -= sin(nosie)*100; #ifdef THE_ORB } else { Origin -= ManualLightPos; } #endif float cellSize = 100.0; vec3 cellPos = CameraPos - vec3(0,10,0) ; // cellPos += vec3(frameTimeCounter,0,0)*25.0; Origin += (fract(cellPos/cellSize)*cellSize - cellSize*0.5); } return Origin; } ///////////////// COLOR ///////////////// COLOR ///////////////// COLOR vec3 LightSourceColor(float SwirlBounds){ vec3 Color = vec3(0.5, 0.5, 1.0); #ifndef THE_ORB if( SwirlBounds < 1.0) { // Color = vec3(0.5, 0.5, 1.0); } else { // #ifdef THE_ORB // Color = vec3(ORB_R, ORB_G, ORB_B) * ORB_ColMult; // #endif // Color *= blackbody2(RandomPosition.y*4000 + 1000); float Timing = dot(RandomPosition, vec3(1.0/3.0)); float Flash = max(sin(frameTimeCounter) * cos(Timing) ,0.0); Color *= Flash; } #else Color = vec3(ORB_R, ORB_G, ORB_B) * ORB_ColMult; #endif return Color; } ///////////////// SHAPE ///////////////// SHAPE ///////////////// SHAPE vec3 LightSourceShape(vec3 WorldPos){ vec3 Shapes = vec3(0.0); vec3 Origin = WorldPos ; // make the swirl only happen within a radius float SwirlBounds = clamp(sqrt(length(Origin) / 200.0 - 1.0) ,0.0,1.0); if( SwirlBounds < 1.0) { // vec3 Origin = WorldPos; Origin.y -= 200; vec3 Origin2 = Origin; Origin2.y = (Origin2.y + 100.0) * 0.8; float Center = length(Origin); float AltCenter = length(Origin2); // the max of a sphere is another smaller sphere. this creates a hollow sphere. Shapes.r = max(1.0 - AltCenter / 75.0, max(AltCenter / 150.0 - 1.0, 0.0)); // donut to make the hurricane shape float radius = 200.0; float thickness = 25.0 * radius; Shapes.r = (thickness - clamp( pow( length( vec2(length(Origin2.xz) - radius, Origin2.y*0.75) ),2.0) - radius, 0.0, thickness) ) / thickness; Shapes.r = max(Shapes.r, max(1.0 - AltCenter / 75.0, 0.0)); // debug donut // radius = 50.0; // thickness = 5.0 * radius; // Shapes.b = (thickness - clamp( pow( length( vec2(length(Origin2.xy) - radius, Origin2.z*0.75) ),2.0) - radius, 0.0, thickness) ) / thickness; } return Shapes; } float cloudVol(in vec3 pos, int LOD){ // THE OOOOOOOOOOOOOOOOOOOOOORB vec3 Shapes = LightSourceShape(pos); vec3 samplePos = pos*vec3(1.0,1./32.,1.0); vec3 samplePos2 = pos*vec3(1.0,1./48.,1.0); // #ifndef THE_ORB float radiance = 2.39996 + samplePos.y + frameTimeCounter/10; mat2 rotationMatrix = mat2(vec2(cos(radiance), -sin(radiance)), vec2(sin(radiance), cos(radiance))); // make the swirl only happen within a radius float SwirlBounds = clamp(sqrt(length(vec3(pos.x,pos.y-100,pos.z)) / 200.0 - 1.0) ,0.0,1.0); samplePos.xz = mix(samplePos.xz * rotationMatrix, samplePos.xz, SwirlBounds); samplePos2.xz = mix(samplePos2.xz * rotationMatrix, samplePos2.xz, SwirlBounds); // #endif samplePos2.y -= frameTimeCounter/15; float finalfog = 0.0; finalfog += max(0.6-densityAtPosFog(samplePos * 16.0) * 2,0.0); float smallnoise = max(densityAtPosFog(samplePos2 * (160. - finalfog*3))-0.1,0.0); finalfog -= ((1-smallnoise) - max(0.15 - abs(smallnoise * 2.0 - 0.55) * 0.5,0.0)*1.5) * 0.3; // make the eye of the swirl have no fog, so you can actually see. finalfog = max(finalfog - Shapes.r, 0.0); // finalfog = Shapes.b; return finalfog; } mat2x3 getVolumetricRays(float dither,vec3 fragpos,float dither2) { int SAMPLES = 16; //project pixel position into projected shadowmap space vec3 wpos = mat3(gbufferModelViewInverse) * fragpos + gbufferModelViewInverse[3].xyz; vec3 fragposition = mat3(shadowModelView) * wpos + shadowModelView[3].xyz; fragposition = diagonal3(shadowProjection) * fragposition + shadowProjection[3].xyz; //project view origin into projected shadowmap space vec3 start = vec3(0.0); //rayvector into projected shadow map space //we can use a projected vector because its orthographic projection //however we still have to send it to curved shadow map space every step vec3 dV = (fragposition-start); vec3 dVWorld = (wpos-gbufferModelViewInverse[3].xyz); float maxLength = min(length(dVWorld),32.0 * 12.0)/length(dVWorld); dV *= maxLength; dVWorld *= maxLength; //apply dither vec3 progress = start.xyz; vec3 progressW = gbufferModelViewInverse[3].xyz+cameraPosition; vec3 vL = vec3(0.); float dL = length(dVWorld); vec3 absorbance = vec3(1.0); float expFactor = 11.0; vec3 fogColor = (gl_Fog.color.rgb / pow(dot(gl_Fog.color.rgb,vec3(0.3333)),1.1) ) ; for (int i=0;i