123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- // From http://graphics.cs.aueb.gr/graphics/research_illumination.html
- // "Real-Time Diffuse Global Illumination Using Radiance Hints"
- // paper and shader code
- uniform float R_wcs = 10.; // Rmax: maximum sampling distance (in WCS units)
- uniform vec3 extents;
- uniform mat4 RHMatrix;
- uniform mat4 RSMMatrix;
- uniform sampler2D dtex;
- uniform sampler2D ctex;
- uniform sampler2D ntex;
- uniform vec3 suncol;
- flat in int slice;
- layout (location = 0) out vec4 SHRed;
- layout (location = 1) out vec4 SHGreen;
- layout (location = 2) out vec4 SHBlue;
- vec3 resolution = vec3(32, 16, 32);
- #define SAMPLES 16
- vec4 SHBasis (const in vec3 dir)
- {
- float L00 = 0.282095;
- float L1_1 = 0.488603 * dir.y;
- float L10 = 0.488603 * dir.z;
- float L11 = 0.488603 * dir.x;
- return vec4 (L11, L1_1, L10, L00);
- }
- vec4 DirToSh(vec3 dir, float flux)
- {
- return SHBasis (dir) * flux;
- }
- // We need to manually unroll the loop, otherwise Nvidia driver crashes.
- void loop(in int i,
- in vec3 RHcenter,in vec3 RHCellSize, in vec2 RHuv, in float RHdepth,
- inout vec4 SHr, inout vec4 SHg, inout vec4 SHb)
- {
- // produce a new sample location on the RSM texture
- float alpha = (i + .5) / SAMPLES;
- float theta = 2. * 3.14 * 7. * alpha;
- float h = alpha;
- vec2 offset = h * vec2(cos(theta), sin(theta));
- vec2 uv = RHuv + offset * 0.01;
- // Get world position and normal from the RSM sample
- float depth = texture(dtex, uv).x;
- vec4 RSMPos = inverse(RSMMatrix) * (2. * vec4(uv, depth, 1.) - 1.);
- RSMPos /= RSMPos.w;
- vec3 RSMAlbedo = texture(ctex, uv).xyz;
- vec3 normal = normalize(2. * texture(ntex, uv).xyz - 1.);
- // Sampled location inside the RH cell
- vec3 offset3d = vec3(uv, 0);
- vec3 SamplePos = RHcenter + .5 * offset3d.xzy * RHCellSize;
- // Normalize distance to RSM sample
- float dist = distance(SamplePos, RSMPos.xyz) / R_wcs;
- // Determine the incident direction.
- // Avoid very close samples (and numerical instability problems)
- vec3 RSM_to_RH_dir = (dist <= 0.1) ? vec3(0.) : normalize(SamplePos - RSMPos.xyz);
- float dotprod = max(dot(RSM_to_RH_dir, normal.xyz), 0.);
- float factor = dotprod / (0.1 + dist * dist);
- vec3 color = RSMAlbedo.rgb * factor * suncol.rgb;
- SHr += DirToSh(RSM_to_RH_dir, color.r);
- SHg += DirToSh(RSM_to_RH_dir, color.g);
- SHb += DirToSh(RSM_to_RH_dir, color.b);
- }
- void main(void)
- {
- vec3 normalizedRHCenter = 2. * vec3(gl_FragCoord.xy, slice) / resolution - 1.;
- vec3 RHcenter = (RHMatrix * vec4(normalizedRHCenter * extents, 1.)).xyz;
- vec4 ShadowProjectedRH = RSMMatrix * vec4(RHcenter, 1.);
- vec3 RHCellSize = extents / resolution;
- vec2 RHuv = .5 * ShadowProjectedRH.xy / ShadowProjectedRH.w + .5;
- float RHdepth = .5 * ShadowProjectedRH.z / ShadowProjectedRH.w + .5;
- vec4 SHr = vec4(0.);
- vec4 SHg = vec4(0.);
- vec4 SHb = vec4(0.);
- int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y);
- float phi = 30. * (x ^ y) + 10. * x * y;
- loop(0, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(1, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(2, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(3, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(4, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(5, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(6, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(7, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(8, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(9, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(10, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(11, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(12, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(13, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(14, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- loop(15, RHcenter, RHCellSize, RHuv, RHdepth, SHr, SHg, SHb);
- SHr /= 3.14159 * SAMPLES;
- SHg /= 3.14159 * SAMPLES;
- SHb /= 3.14159 * SAMPLES;
- SHRed = SHr;
- SHGreen = SHg;
- SHBlue = SHb;
- }
|