diff --git a/shaders/composite1.fsh b/shaders/composite1.fsh index 1abbcee..b92cf20 100644 --- a/shaders/composite1.fsh +++ b/shaders/composite1.fsh @@ -169,7 +169,7 @@ float triangularize(float dither) float interleaved_gradientNoise(){ // vec2 coord = gl_FragCoord.xy + (frameCounter%40000); - vec2 coord = gl_FragCoord.xy + frameTimeCounter; + vec2 coord = gl_FragCoord.xy + (frameCounter%40000); // vec2 coord = gl_FragCoord.xy; float noise = fract( 52.9829189 * fract( (coord.x * 0.06711056) + (coord.y * 0.00583715)) ); return noise ; @@ -177,13 +177,13 @@ float interleaved_gradientNoise(){ vec2 R2_dither(){ vec2 alpha = vec2(0.75487765, 0.56984026); - return vec2(fract(alpha.x * gl_FragCoord.x + alpha.y * gl_FragCoord.y + 1.0/1.6180339887 * frameCounter), fract((1.0-alpha.x) * gl_FragCoord.x + (1.0-alpha.y) * gl_FragCoord.y + 1.0/1.6180339887 * frameCounter)); + return vec2(fract(alpha.x * gl_FragCoord.x + alpha.y * gl_FragCoord.y + 1.0/1.6180339887 * (frameCounter%40000)), fract((1.0-alpha.x) * gl_FragCoord.x + (1.0-alpha.y) * gl_FragCoord.y + 1.0/1.6180339887 * frameCounter)); } float blueNoise(){ - return fract(texelFetch2D(noisetex, ivec2(gl_FragCoord.xy)%512, 0).a + 1.0/1.6180339887 * (frameCounter*0.5+0.5) ); + return fract(texelFetch2D(noisetex, ivec2(gl_FragCoord.xy)%512, 0).a + 1.0/1.6180339887 * (frameCounter%40000) ); } vec4 blueNoise(vec2 coord){ - return texelFetch2D(colortex6, ivec2(coord )%512, 0) ; + return texelFetch2D(colortex6, ivec2(coord)%512, 0) ; } vec3 fp10Dither(vec3 color,float dither){ const vec3 mantissaBits = vec3(6.,6.,5.); @@ -590,7 +590,7 @@ void ApplySSRT(inout vec3 lighting, vec3 normal,vec2 noise,vec3 fragpos, vec2 li skycontribution = (skyCloudsFromTex(rayDir, colortex4).rgb / 15.0) * skyLM + torchlight; #else if(isGrass) rayDir.y = clamp(rayDir.y + 0.25,-1,1); - skycontribution = (skylightcolor * skyLM) * max(rayDir.y * min(AO_Strength,1.0), 0.05) + torchlight; + skycontribution = skylightcolor * max(rayDir.y * min(AO_Strength,1.0), 0.05) + torchlight; #endif if (rayHit.z < 1.){ @@ -601,9 +601,10 @@ void ApplySSRT(inout vec3 lighting, vec3 normal,vec2 noise,vec3 fragpos, vec2 li previousPosition.xy = projMAD(gbufferPreviousProjection, previousPosition).xy / -previousPosition.z * 0.5 + 0.5; if (previousPosition.x > 0.0 && previousPosition.y > 0.0 && previousPosition.x < 1.0 && previousPosition.x < 1.0){ radiance += (texture2D(colortex5,previousPosition.xy).rgb + skycontribution) * GI_Strength; - } else { + }else{ radiance += skycontribution; } + #else radiance += skycontribution; #endif @@ -615,11 +616,9 @@ void ApplySSRT(inout vec3 lighting, vec3 normal,vec2 noise,vec3 fragpos, vec2 li } } - // #ifdef SKY_CONTRIBUTION_IN_SSRT - occlusion *= AO_Strength; - // #endif + occlusion *= AO_Strength; - lighting = max(radiance - occlusion,0.0)/nrays; + lighting = max(radiance/nrays - occlusion/nrays, 0.0); } @@ -765,7 +764,9 @@ vec3 Moon(vec3 PlayerPos, vec3 WorldSunVec, vec3 Color, inout vec3 occludeStars) return Shape * pow(clamp(dot(sunNormal,LightDir)/5,0.0,1.5),5) * Color + clamp(Shape * 4.0 * pow(shape2/200,2.0),0.0,1.0)*0.004; } - +vec3 applyContrast(vec3 color, float contrast){ + return (color - 0.5) * contrast + 0.5; +} #include "/lib/PhotonGTAO.glsl" @@ -1235,6 +1236,8 @@ void main() { if (isEyeInWater == 0) waterVolumetrics(gl_FragData[0].rgb, fragpos0, fragpos, estimatedDepth , estimatedSunDepth, Vdiff, noise, totEpsilon, scatterCoef, ambientColVol, lightColVol, dot(np3, WsunVec)); } + + #if DOF_QUALITY == 5 vec3 laserColor; #if FOCUS_LASER_COLOR == 0 // Red diff --git a/shaders/composite1.vsh b/shaders/composite1.vsh index 26060e5..9c984cd 100644 --- a/shaders/composite1.vsh +++ b/shaders/composite1.vsh @@ -57,8 +57,10 @@ void main() { gl_Position = ftransform(); +// if (gl_FragCoord.x < 1. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 ) averageSkyCol_Clouds = texelFetch2D(colortex4,ivec2(0,37),0).rgb; + // averageSkyCol = texelFetch2D(colortex4,ivec2(1,37),0).rgb; // averageSkyCol_Clouds = texelFetch2D(colortex4,ivec2(1,37),0).rgb;; // sunColor = texelFetch2D(colortex4,ivec2(6,37),0).rgb; diff --git a/shaders/deferred.fsh b/shaders/deferred.fsh index e7904ff..f146556 100644 --- a/shaders/deferred.fsh +++ b/shaders/deferred.fsh @@ -125,6 +125,9 @@ gl_FragData[0] = vec4(sunColor,1.0); if (gl_FragCoord.x > 13. && gl_FragCoord.x < 14. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 ) gl_FragData[0] = vec4(moonColor,1.0); + + + const float pi = 3.141592653589793238462643383279502884197169; //Sky gradient (no clouds) @@ -163,7 +166,7 @@ if (gl_FragCoord.x > 18.+257. && gl_FragCoord.y > 1. && gl_FragCoord.x < 18+257+ vec4 VL_Fog = getVolumetricRays(mat3(gbufferModelView)*viewVector*1024., fract(frameCounter/1.6180339887), averageSkyCol); if(viewVector.y < -0.025) VL_Fog.rgb *= clamp( exp(viewVector.y) - 1.0,0.25,1.0) ; - + sky = sky*VL_Fog.a + VL_Fog.rgb*20; gl_FragData[0] = vec4(sky,1.0); @@ -173,7 +176,7 @@ if (gl_FragCoord.x > 18.+257. && gl_FragCoord.y > 1. && gl_FragCoord.x < 18+257+ vec3 temp = texelFetch2D(colortex4,ivec2(gl_FragCoord.xy),0).rgb; vec3 curr = gl_FragData[0].rgb*150.; -float flashtiming = pow(clamp((0.01-lightningFlash)*100,0,1),25); +float flashtiming = pow(clamp((0.01-lightningFlash)*100,0,1),25); gl_FragData[0].rgb = clamp(mix(temp,curr, 0.07 * flashtiming),0.0,65000.); diff --git a/shaders/lib/diffuse_lighting.glsl b/shaders/lib/diffuse_lighting.glsl index 97fca9b..3c6c5fd 100644 --- a/shaders/lib/diffuse_lighting.glsl +++ b/shaders/lib/diffuse_lighting.glsl @@ -2,6 +2,19 @@ uniform float nightVision; +void DoRTAmbientLighting (vec3 TorchColor, vec2 Lightmap, inout float SkyLM, inout vec3 TorchLight, inout vec3 SkyLight){ + + float TorchLM = 10.0 - ( 1.0 / (pow(exp(-0.5*inversesqrt(Lightmap.x)),5.0)+0.1)); + TorchLM = pow(TorchLM/4,10) + pow(Lightmap.x,1.5)*0.5; + TorchLight = (TorchColor * TorchLM * 0.75) * TORCH_AMOUNT; + + + SkyLM = (pow(Lightmap.y,15.0)*2.0 + pow(Lightmap.y,2.5))*0.5; + + SkyLight = (SkyLight * ambient_brightness) / 10.0; + SkyLight = max(SkyLight * SkyLM, vec3(0.2,0.4,1.0) * (MIN_LIGHT_AMOUNT*0.025 + nightVision)); +} + //// OVERWORLD //// #ifdef OVERWORLD vec3 DoAmbientLighting (vec3 SkyColor, vec3 TorchColor, vec2 Lightmap, float skyLightDir){ @@ -18,20 +31,8 @@ vec3 DoAmbientLighting (vec3 SkyColor, vec3 TorchColor, vec2 Lightmap, float sky float skyLM = (pow(Lightmap.y,15.0)*2.0 + pow(Lightmap.y,2.5))*0.5; vec3 SkyLight = max(SkyColor * skyLM, vec3(0.2,0.4,1.0) * (MIN_LIGHT_AMOUNT*0.01 + nightVision) ); - return SkyLight * skyLightDir + TorchLight; + return SkyLight * skyLightDir + TorchLight; } - -void DoRTAmbientLighting (vec3 TorchColor, vec2 Lightmap, inout float SkyLM, inout vec3 TorchLight, inout vec3 SkyLight){ - - float TorchLM = 10.0 - ( 1.0 / (pow(exp(-0.5*inversesqrt(Lightmap.x)),5.0)+0.1)); - TorchLM = pow(TorchLM/4,10) + pow(Lightmap.x,1.5)*0.5; - TorchLight = (TorchColor * TorchLM * 0.75) * TORCH_AMOUNT; - - SkyLM = (pow(Lightmap.y,15.0)*2.0 + pow(Lightmap.y,2.5))*0.5; - - SkyLight = max((SkyLight * ambient_brightness) / 10.0, vec3(0.2,0.4,1.0) * (MIN_LIGHT_AMOUNT*0.01 + nightVision)); -} - vec3 DoDirectLighting(vec3 SunColor, float Shadow, float NdotL, float SubsurfaceScattering){ // vec3 SunLight = max(NdotL * Shadow, SubsurfaceScattering) * SunColor; diff --git a/shaders/world-1/composite2.fsh b/shaders/world-1/composite2.fsh index 4e6039c..84fb235 100644 --- a/shaders/world-1/composite2.fsh +++ b/shaders/world-1/composite2.fsh @@ -101,21 +101,25 @@ float triangularize(float dither) dither = center*inversesqrt(abs(center)); return clamp(dither-fsign(center),0.0,1.0); } -// float interleaved_gradientNoise(float temp){ -// return fract(52.9829189*fract(0.06711056*gl_FragCoord.x + 0.00583715*gl_FragCoord.y)+temp); -// } -// float interleaved_gradientNoise(){ -// vec2 coord = gl_FragCoord.xy; -// float noise = fract(52.9829189*fract(0.06711056*coord.x + 0.00583715*coord.y)); -// return noise; -// } + float interleaved_gradientNoise(){ - vec2 coord = gl_FragCoord.xy + (frameCounter%40000); - // vec2 coord = gl_FragCoord.xy + frameTimeCounter; + // vec2 coord = gl_FragCoord.xy + (frameCounter%40000); + vec2 coord = gl_FragCoord.xy + frameTimeCounter; // vec2 coord = gl_FragCoord.xy; float noise = fract( 52.9829189 * fract( (coord.x * 0.06711056) + (coord.y * 0.00583715)) ); return noise ; } + +vec2 R2_dither(){ + vec2 alpha = vec2(0.75487765, 0.56984026); + return vec2(fract(alpha.x * gl_FragCoord.x + alpha.y * gl_FragCoord.y + 1.0/1.6180339887 * frameCounter), fract((1.0-alpha.x) * gl_FragCoord.x + (1.0-alpha.y) * gl_FragCoord.y + 1.0/1.6180339887 * frameCounter)); +} +float blueNoise(){ + return fract(texelFetch2D(noisetex, ivec2(gl_FragCoord.xy)%512, 0).a + 1.0/1.6180339887 * (frameCounter*0.5+0.5) ); +} +vec4 blueNoise(vec2 coord){ + return texelFetch2D(colortex6, ivec2(coord)%512 , 0) ; +} vec3 fp10Dither(vec3 color,float dither){ const vec3 mantissaBits = vec3(6.,6.,5.); vec3 exponent = floor(log2(color)); @@ -141,22 +145,6 @@ vec2 decodeVec2(float a){ const float constant2 = 256. / 255.; return fract( a * constant1 ) * constant2 ; } -// float linZ(float depth) { -// return (2.0 * near) / (far + near - depth * (far - near)); -// // l = (2*n)/(f+n-d(f-n)) -// // f+n-d(f-n) = 2n/l -// // -d(f-n) = ((2n/l)-f-n) -// // d = -((2n/l)-f-n)/(f-n) - -// } -// float invLinZ (float lindepth){ -// return -((2.0*near/lindepth)-far-near)/(far-near); -// } - -// vec3 toClipSpace3(vec3 viewSpacePosition) { -// return projMAD(gbufferProjection, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5; -// } - @@ -181,13 +169,7 @@ vec3 BilateralFiltering(sampler2D tex, sampler2D depth,vec2 coord,float frDepth, return vec3(sampled.x,sampled.yz/sampled.w); } -float blueNoise(){ - return fract(texelFetch2D(noisetex, ivec2(gl_FragCoord.xy)%512, 0).a + 1.0/1.6180339887 * frameCounter); -} -float R2_dither(){ - vec2 alpha = vec2(0.75487765, 0.56984026); - return fract(alpha.x * gl_FragCoord.x + alpha.y * gl_FragCoord.y); -} + vec3 toShadowSpaceProjected(vec3 p3){ p3 = mat3(gbufferModelViewInverse) * p3 + gbufferModelViewInverse[3].xyz; p3 = mat3(shadowModelView) * p3 + shadowModelView[3].xyz; @@ -307,10 +289,6 @@ void waterVolumetrics(inout vec3 inColor, vec3 rayStart, vec3 rayEnd, float estE inColor += vL; } -vec4 blueNoise(vec2 coord){ - return texelFetch2D(colortex6, ivec2(coord )%512 , 0); -} - void Emission( inout vec3 Lighting, vec3 Albedo, @@ -383,6 +361,81 @@ void ScreenSpace_SSS(inout float sss, vec3 fragpos, vec2 noise, vec3 normal){ +vec3 rayTrace_GI(vec3 dir,vec3 position,float dither, float quality){ + + vec3 clipPosition = toClipSpace3(position); + float rayLength = ((position.z + dir.z * far*sqrt(3.)) > -near) ? + (-near -position.z) / dir.z : far*sqrt(3.); + vec3 direction = normalize(toClipSpace3(position+dir*rayLength)-clipPosition); //convert to clip space + direction.xy = normalize(direction.xy); + + //get at which length the ray intersects with the edge of the screen + vec3 maxLengths = (step(0.,direction)-clipPosition) / direction; + float mult = maxLengths.y; + + vec3 stepv = direction * mult / quality*vec3(RENDER_SCALE,1.0) * dither; + vec3 spos = clipPosition*vec3(RENDER_SCALE,1.0) ; + + spos.xy += TAA_Offset*texelSize*0.5/RENDER_SCALE; + + float biasdist = clamp(position.z*position.z/50.0,1,2); // shrink sample size as distance increases + + for(int i = 0; i < int(quality); i++){ + spos += stepv; + float sp = sqrt(texelFetch2D(colortex4,ivec2(spos.xy/texelSize/4),0).w/65000.0); + float currZ = linZ(spos.z); + + if( sp < currZ) { + float dist = abs(sp-currZ)/currZ; + if (abs(dist) < biasdist*0.05) return vec3(spos.xy, invLinZ(sp))/vec3(RENDER_SCALE,1.0); + } + spos += stepv; + } + return vec3(1.1); +} +vec3 RT(vec3 dir, vec3 position, float noise, float stepsizes){ + float dist = 1.0 + clamp(position.z*position.z/50.0,0,2); // shrink sample size as distance increases + + float stepSize = stepsizes / dist; + int maxSteps = STEPS; + vec3 clipPosition = toClipSpace3(position); + float rayLength = ((position.z + dir.z * sqrt(3.0)*far) > -sqrt(3.0)*near) ? + (-sqrt(3.0)*near -position.z) / dir.z : sqrt(3.0)*far; + vec3 end = toClipSpace3(position+dir*rayLength) ; + vec3 direction = end-clipPosition ; //convert to clip space + + float len = max(abs(direction.x)/texelSize.x,abs(direction.y)/texelSize.y)/stepSize; + //get at which length the ray intersects with the edge of the screen + vec3 maxLengths = (step(0.,direction)-clipPosition) / direction; + + float mult = min(min(maxLengths.x,maxLengths.y),maxLengths.z)*2000.0; + + vec3 stepv = direction/len; + + int iterations = min(int(min(len, mult*len)-2), maxSteps); + + //Do one iteration for closest texel (good contact shadows) + vec3 spos = clipPosition*vec3(RENDER_SCALE,1.0) ; + spos.xy += TAA_Offset*texelSize*0.5*RENDER_SCALE; + spos += stepv/(stepSize/2); + + float distancered = 1.0 + clamp(position.z*position.z/50.0,0,2); // shrink sample size as distance increases + + for(int i = 0; i < iterations; i++){ + if (spos.x < 0.0 || spos.y < 0.0 || spos.z < 0.0 || spos.x > 1.0 || spos.y > 1.0 || spos.z > 1.0) return vec3(1.1); + spos += stepv*noise; + + float sp = sqrt(texelFetch2D(colortex4,ivec2(spos.xy/ texelSize/4),0).w/65000.0); + float currZ = linZ(spos.z); + + if( sp < currZ) { + float dist = abs(sp-currZ)/currZ; + if (dist <= 0.1) return vec3(spos.xy, invLinZ(sp))/vec3(RENDER_SCALE,1.0); + } + } + return vec3(1.1); +} + vec3 cosineHemisphereSample(vec2 Xi, float roughness){ float r = sqrt(Xi.x); float theta = 2.0 * 3.14159265359 * Xi.y; @@ -392,6 +445,7 @@ vec3 cosineHemisphereSample(vec2 Xi, float roughness){ return vec3(x, y, sqrt(clamp(1.0 - Xi.x,0.,1.))); } + vec3 TangentToWorld(vec3 N, vec3 H, float roughness){ vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); vec3 T = normalize(cross(UpVector, N)); @@ -399,7 +453,59 @@ vec3 TangentToWorld(vec3 N, vec3 H, float roughness){ return vec3((T * H.x) + (B * H.y) + (N * H.z)); } +vec2 R2_samples(int n){ + vec2 alpha = vec2(0.75487765, 0.56984026); + return fract(alpha * n); +} +void ApplySSRT(inout vec3 lighting, vec3 normal,vec2 noise,vec3 fragpos, float lightmaps, vec3 torchcolor){ + int nrays = RAY_COUNT; + + vec3 radiance = vec3(0.0); + vec3 occlusion = vec3(0.0); + vec3 skycontribution = vec3(0.0); + + for (int i = 0; i < nrays; i++){ + int seed = (frameCounter%40000)*nrays+i; + vec2 ij = fract(R2_samples(seed) + noise ); + + vec3 rayDir = TangentToWorld(normal, normalize(cosineHemisphereSample(ij,1.0)) ,1.0); + + #ifdef HQ_SSGI + vec3 rayHit = rayTrace_GI( mat3(gbufferModelView) * rayDir, fragpos, blueNoise(), 50.); // ssr rt + #else + vec3 rayHit = RT(mat3(gbufferModelView)*rayDir, fragpos, blueNoise(), 30.); // choc sspt + #endif + + skycontribution = lighting; + + if (rayHit.z < 1.){ + + #if indirect_effect == 4 + vec3 previousPosition = mat3(gbufferModelViewInverse) * toScreenSpace(rayHit) + gbufferModelViewInverse[3].xyz + cameraPosition-previousCameraPosition; + previousPosition = mat3(gbufferPreviousModelView) * previousPosition + gbufferPreviousModelView[3].xyz; + previousPosition.xy = projMAD(gbufferPreviousProjection, previousPosition).xy / -previousPosition.z * 0.5 + 0.5; + if (previousPosition.x > 0.0 && previousPosition.y > 0.0 && previousPosition.x < 1.0 && previousPosition.x < 1.0){ + radiance += (texture2D(colortex5,previousPosition.xy).rgb + skycontribution) * GI_Strength; + }else{ + radiance += skycontribution; + } + + #else + radiance += skycontribution; + #endif + + occlusion += skycontribution * GI_Strength; + + } else { + radiance += skycontribution; + } + } + + occlusion *= AO_Strength; + + lighting = max(radiance/nrays - occlusion/nrays, 0.0); +} void main() { float dirtAmount = Dirt_Amount; vec3 waterEpsilon = vec3(Water_Absorb_R, Water_Absorb_G, Water_Absorb_B); @@ -481,9 +587,21 @@ void main() { // do all ambient lighting stuff vec3 Indirect_lighting = DoAmbientLighting_Nether(AmbientLightColor, vec3(TORCH_R,TORCH_G,TORCH_B), lightmap.x, normal, np3, p3 ); - vec3 AO = vec3( exp( (vanilla_AO*vanilla_AO) * -5) ) ; - if(!hand) Indirect_lighting *= ssao(fragpos,noise,FlatNormals) * AO; + #if indirect_effect == 0 + vec3 AO = vec3( exp( (vanilla_AO*vanilla_AO) * -5) ) ; + if(!hand) Indirect_lighting *= AO; + #endif + + #if indirect_effect == 1 + vec3 AO = vec3( exp( (vanilla_AO*vanilla_AO) * -5) ) ; + if(!hand) Indirect_lighting *= ssao(fragpos,noise,FlatNormals) * AO; + #endif + + // RTAO and/or SSGI + #if indirect_effect == 3 || indirect_effect == 4 + if (!hand) ApplySSRT(Indirect_lighting, normal, blueNoise(gl_FragCoord.xy).rg, fragpos, lightmap.x,vec3(TORCH_R,TORCH_G,TORCH_B)); + #endif // finalize gl_FragData[0].rgb = Indirect_lighting * albedo; diff --git a/shaders/world1/composite.fsh b/shaders/world1/composite.fsh index 370ebd8..7a7313e 100644 --- a/shaders/world1/composite.fsh +++ b/shaders/world1/composite.fsh @@ -102,21 +102,7 @@ float triangularize(float dither) dither = center*inversesqrt(abs(center)); return clamp(dither-fsign(center),0.0,1.0); } -// float interleaved_gradientNoise(float temp){ -// return fract(52.9829189*fract(0.06711056*gl_FragCoord.x + 0.00583715*gl_FragCoord.y)+temp); -// } -// float interleaved_gradientNoise(){ -// vec2 coord = gl_FragCoord.xy; -// float noise = fract(52.9829189*fract(0.06711056*coord.x + 0.00583715*coord.y)); -// return noise; -// } -float interleaved_gradientNoise(){ - vec2 coord = gl_FragCoord.xy + (frameCounter%40000); - // vec2 coord = gl_FragCoord.xy + frameTimeCounter; - // vec2 coord = gl_FragCoord.xy; - float noise = fract( 52.9829189 * fract( (coord.x * 0.06711056) + (coord.y * 0.00583715)) ); - return noise ; -} + vec3 fp10Dither(vec3 color,float dither){ const vec3 mantissaBits = vec3(6.,6.,5.); vec3 exponent = floor(log2(color)); @@ -182,12 +168,23 @@ vec3 BilateralFiltering(sampler2D tex, sampler2D depth,vec2 coord,float frDepth, return vec3(sampled.x,sampled.yz/sampled.w); } -float blueNoise(){ - return fract(texelFetch2D(noisetex, ivec2(gl_FragCoord.xy)%512, 0).a + 1.0/1.6180339887 * frameCounter); +float interleaved_gradientNoise(){ + // vec2 coord = gl_FragCoord.xy + (frameCounter%40000); + vec2 coord = gl_FragCoord.xy + frameTimeCounter; + // vec2 coord = gl_FragCoord.xy; + float noise = fract( 52.9829189 * fract( (coord.x * 0.06711056) + (coord.y * 0.00583715)) ); + return noise ; } -float R2_dither(){ + +vec2 R2_dither(){ vec2 alpha = vec2(0.75487765, 0.56984026); - return fract(alpha.x * gl_FragCoord.x + alpha.y * gl_FragCoord.y); + return vec2(fract(alpha.x * gl_FragCoord.x + alpha.y * gl_FragCoord.y + 1.0/1.6180339887 * frameCounter), fract((1.0-alpha.x) * gl_FragCoord.x + (1.0-alpha.y) * gl_FragCoord.y + 1.0/1.6180339887 * frameCounter)); +} +float blueNoise(){ + return fract(texelFetch2D(noisetex, ivec2(gl_FragCoord.xy)%512, 0).a + 1.0/1.6180339887 * (frameCounter*0.5+0.5) ); +} +vec4 blueNoise(vec2 coord){ + return texelFetch2D(colortex6, ivec2(coord)%512 , 0) ; } vec3 toShadowSpaceProjected(vec3 p3){ p3 = mat3(gbufferModelViewInverse) * p3 + gbufferModelViewInverse[3].xyz; @@ -308,10 +305,6 @@ void waterVolumetrics(inout vec3 inColor, vec3 rayStart, vec3 rayEnd, float estE inColor += vL; } -vec4 blueNoise(vec2 coord){ - return texelFetch2D(colortex6, ivec2(coord )%512 , 0); -} - void Emission( inout vec3 Lighting, vec3 Albedo, @@ -348,6 +341,156 @@ float rayTraceShadow(vec3 dir,vec3 position,float dither){ } + +vec3 rayTrace_GI(vec3 dir,vec3 position,float dither, float quality){ + + vec3 clipPosition = toClipSpace3(position); + float rayLength = ((position.z + dir.z * far*sqrt(3.)) > -near) ? + (-near -position.z) / dir.z : far*sqrt(3.); + vec3 direction = normalize(toClipSpace3(position+dir*rayLength)-clipPosition); //convert to clip space + direction.xy = normalize(direction.xy); + + //get at which length the ray intersects with the edge of the screen + vec3 maxLengths = (step(0.,direction)-clipPosition) / direction; + float mult = maxLengths.y; + + vec3 stepv = direction * mult / quality*vec3(RENDER_SCALE,1.0) * dither; + vec3 spos = clipPosition*vec3(RENDER_SCALE,1.0) ; + + spos.xy += TAA_Offset*texelSize*0.5/RENDER_SCALE; + + float biasdist = clamp(position.z*position.z/50.0,1,2); // shrink sample size as distance increases + + for(int i = 0; i < int(quality); i++){ + spos += stepv; + float sp = sqrt(texelFetch2D(colortex4,ivec2(spos.xy/texelSize/4),0).w/65000.0); + float currZ = linZ(spos.z); + + if( sp < currZ) { + float dist = abs(sp-currZ)/currZ; + if (abs(dist) < biasdist*0.05) return vec3(spos.xy, invLinZ(sp))/vec3(RENDER_SCALE,1.0); + } + spos += stepv; + } + return vec3(1.1); +} +vec3 RT(vec3 dir, vec3 position, float noise, float stepsizes){ + float dist = 1.0 + clamp(position.z*position.z/50.0,0,2); // shrink sample size as distance increases + + float stepSize = stepsizes / dist; + int maxSteps = STEPS; + vec3 clipPosition = toClipSpace3(position); + float rayLength = ((position.z + dir.z * sqrt(3.0)*far) > -sqrt(3.0)*near) ? + (-sqrt(3.0)*near -position.z) / dir.z : sqrt(3.0)*far; + vec3 end = toClipSpace3(position+dir*rayLength) ; + vec3 direction = end-clipPosition ; //convert to clip space + + float len = max(abs(direction.x)/texelSize.x,abs(direction.y)/texelSize.y)/stepSize; + //get at which length the ray intersects with the edge of the screen + vec3 maxLengths = (step(0.,direction)-clipPosition) / direction; + + float mult = min(min(maxLengths.x,maxLengths.y),maxLengths.z)*2000.0; + + vec3 stepv = direction/len; + + int iterations = min(int(min(len, mult*len)-2), maxSteps); + + //Do one iteration for closest texel (good contact shadows) + vec3 spos = clipPosition*vec3(RENDER_SCALE,1.0) ; + spos.xy += TAA_Offset*texelSize*0.5*RENDER_SCALE; + spos += stepv/(stepSize/2); + + float distancered = 1.0 + clamp(position.z*position.z/50.0,0,2); // shrink sample size as distance increases + + for(int i = 0; i < iterations; i++){ + if (spos.x < 0.0 || spos.y < 0.0 || spos.z < 0.0 || spos.x > 1.0 || spos.y > 1.0 || spos.z > 1.0) return vec3(1.1); + spos += stepv*noise; + + float sp = sqrt(texelFetch2D(colortex4,ivec2(spos.xy/ texelSize/4),0).w/65000.0); + float currZ = linZ(spos.z); + + if( sp < currZ) { + float dist = abs(sp-currZ)/currZ; + if (dist <= 0.1) return vec3(spos.xy, invLinZ(sp))/vec3(RENDER_SCALE,1.0); + } + } + return vec3(1.1); +} + +vec3 cosineHemisphereSample(vec2 Xi, float roughness){ + float r = sqrt(Xi.x); + float theta = 2.0 * 3.14159265359 * Xi.y; + + float x = r * cos(theta); + float y = r * sin(theta); + + return vec3(x, y, sqrt(clamp(1.0 - Xi.x,0.,1.))); +} + +vec3 TangentToWorld(vec3 N, vec3 H, float roughness){ + vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + vec3 T = normalize(cross(UpVector, N)); + vec3 B = cross(N, T); + + return vec3((T * H.x) + (B * H.y) + (N * H.z)); +} +vec2 R2_samples(int n){ + vec2 alpha = vec2(0.75487765, 0.56984026); + return fract(alpha * n); +} + +void ApplySSRT(inout vec3 lighting, vec3 normal,vec2 noise,vec3 fragpos, float lightmaps, vec3 torchcolor){ + int nrays = RAY_COUNT; + + vec3 radiance = vec3(0.0); + vec3 occlusion = vec3(0.0); + vec3 skycontribution = vec3(0.0); + + // float skyLM = 0.0; + // vec3 torchlight = vec3(0.0); + // vec3 blank = vec3(0.0); + // DoRTAmbientLighting(torchcolor, vec2(lightmaps,1.0), skyLM, torchlight, blank); + + for (int i = 0; i < nrays; i++){ + int seed = (frameCounter%40000)*nrays+i; + vec2 ij = fract(R2_samples(seed) + noise ); + + vec3 rayDir = TangentToWorld(normal, normalize(cosineHemisphereSample(ij,1.0)) ,1.0); + + #ifdef HQ_SSGI + vec3 rayHit = rayTrace_GI( mat3(gbufferModelView) * rayDir, fragpos, blueNoise(), 50.); // ssr rt + #else + vec3 rayHit = RT(mat3(gbufferModelView)*rayDir, fragpos, blueNoise(), 30.); // choc sspt + #endif + + skycontribution = lighting; + + if (rayHit.z < 1.){ + + #if indirect_effect == 4 + vec3 previousPosition = mat3(gbufferModelViewInverse) * toScreenSpace(rayHit) + gbufferModelViewInverse[3].xyz + cameraPosition-previousCameraPosition; + previousPosition = mat3(gbufferPreviousModelView) * previousPosition + gbufferPreviousModelView[3].xyz; + previousPosition.xy = projMAD(gbufferPreviousProjection, previousPosition).xy / -previousPosition.z * 0.5 + 0.5; + if (previousPosition.x > 0.0 && previousPosition.y > 0.0 && previousPosition.x < 1.0 && previousPosition.x < 1.0){ + radiance += (texture2D(colortex5,previousPosition.xy).rgb + skycontribution) * GI_Strength; + }else{ + radiance += skycontribution; + } + #else + radiance += skycontribution; + #endif + + occlusion += skycontribution * GI_Strength; + + } else { + radiance += skycontribution; + } + } + + occlusion *= AO_Strength; + + lighting = max(radiance/nrays - occlusion/nrays, 0.0); +} void main() { float dirtAmount = Dirt_Amount; vec3 waterEpsilon = vec3(Water_Absorb_R, Water_Absorb_G, Water_Absorb_B); @@ -415,7 +558,6 @@ void main() { p3 += gbufferModelViewInverse[3].xyz; // do all ambient lighting stuff - vec3 AO = vec3( exp( (vanilla_AO*vanilla_AO) * -5) ) ; vec3 Indirect_lighting = DoAmbientLighting_End(gl_Fog.color.rgb, vec3(TORCH_R,TORCH_G,TORCH_B), lightmap.x, normal, np3); vec3 LightColor = LightSourceColor(clamp(sqrt(length(p3+cameraPosition) / 150.0 - 1.0) ,0.0,1.0)); @@ -442,6 +584,22 @@ void main() { // if(!hand) LightSource *= RT_Shadows*RT_Shadows; + + #if indirect_effect == 0 + vec3 AO = vec3( exp( (vanilla_AO*vanilla_AO) * -5) ) ; + if(!hand) Indirect_lighting *= AO; + #endif + + #if indirect_effect == 1 + vec3 AO = vec3( exp( (vanilla_AO*vanilla_AO) * -5) ) ; + if(!hand) Indirect_lighting *= ssao(fragpos,noise,FlatNormals) * AO; + #endif + + // RTAO and/or SSGI + #if indirect_effect == 3 || indirect_effect == 4 + if (!hand) ApplySSRT(Indirect_lighting, normal, blueNoise(gl_FragCoord.xy).rg, fragpos, lightmap.x,vec3(TORCH_R,TORCH_G,TORCH_B)); + #endif + // finalize gl_FragData[0].rgb = (Indirect_lighting + LightSource) * albedo; @@ -454,7 +612,7 @@ void main() { DoSpecularReflections(gl_FragData[0].rgb, fragpos, np3, vec3(0.0), specNoise, normal, SpecularTex.r, SpecularTex.g, albedo, vec3(0.0), 1.0, hand); #endif - if(!hand) gl_FragData[0].rgb *= ssao(fragpos,noise,FlatNormals) * AO; + Emission(gl_FragData[0].rgb, albedo, SpecularTex.a);