-
Notifications
You must be signed in to change notification settings - Fork 1
/
ssgi.frag
110 lines (100 loc) · 3.6 KB
/
ssgi.frag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#version 440
uniform sampler2D litcolor;;
uniform sampler2D normal;
uniform sampler2D diffuse;
out vec4 color;
in vec2 texcoord;
uniform vec2 texturesize = vec2(10, 10);
uniform float useed = 0;
uniform mat4 invpersp;
uniform bool enablegi = true;
uniform float indirectstr = 1;
vec2 mod_dither3(vec2 u)
{
float noiseX = mod(u.x + u.y + mod(208. + u.x * 3.58, 13. + mod(u.y * 22.9, 9.)), 7.) * .143;
float noiseY = mod(u.y + u.x + mod(203. + u.y * 3.18, 12. + mod(u.x * 27.4, 8.)), 6.) * .139;
return vec2(noiseX, noiseY) * 2.0 - 1.0;
}
vec2 dither(vec2 coord, float seed, vec2 size)
{
float noiseX = ((fract(1.0 - (coord.x + seed * 1.0) * (size.x / 2.0)) * 0.25) + (fract((coord.y + seed * 2.0) * (size.y / 2.0)) * 0.75)) * 2.0 - 1.0;
float noiseY = ((fract(1.0 - (coord.x + seed * 3.0) * (size.x / 2.0)) * 0.75) + (fract((coord.y + seed * 4.0) * (size.y / 2.0)) * 0.25)) * 2.0 - 1.0;
return vec2(noiseX, noiseY);
}
vec3 depthtoworldpos(vec2 screenpos, float d)
{
vec4 pos;
pos.xy = (screenpos * 2.0 - 1.0);
pos.z = d;
pos.w = 1;
pos = invpersp * pos;
pos.xyz /= pos.w;
return pos.xyz ;
}
float lenSq(vec3 vector)
{
return pow(vector.x, 2.0) + pow(vector.y, 2.0) + pow(vector.z, 2.0);
}
uniform int SAMPLES = 8;
uniform float tracesteps = 1.0 / 10.0;
vec3 lightSample(vec2 samplecoord, vec3 innormal, vec3 pos, float d)
{
vec3 tracedcoordend = vec3(samplecoord.xy, texture(normal, samplecoord.xy).w);
vec3 tracedcoord = tracedcoordend;
for(float i = 1; i > 0; i -= tracesteps)
{
vec3 interp = mix(tracedcoordend, vec3(texcoord.xy, d), i);
if(interp.z > texture(normal, interp.xy).w)
{
tracedcoord = interp;
}
}
vec3 lightsample = texture(litcolor, tracedcoord.xy).xyz;
vec4 nbuf = texture(normal, tracedcoord.xy);
vec3 samplepos = depthtoworldpos(tracedcoord.xy, nbuf.w);
vec3 lightpath = samplepos - pos;
vec3 lightdir = normalize(lightpath);
//falloff calculations
float cosemit = clamp(dot(lightdir, -nbuf.xyz), 0.0, 1.0); //emit only in one direction
float coscatch = clamp(dot(lightdir, innormal), 0.0, 1.0); //recieve light from one direction
float distfall = pow(lenSq(lightpath), 0.1) + 1.0; //fall off with distance
float occlusion = 1;
return lightsample * coscatch * cosemit * distfall * occlusion;
}
void main()
{
vec4 incolor = texture(litcolor, texcoord.xy) ;
if(!enablegi)
{
color = incolor;
}
else
{
vec4 nbuf = texture(normal, vec2(texcoord.x, texcoord.y));
vec4 diffuse = texture(diffuse, vec2(texcoord.x, texcoord.y));
vec3 centerpos = depthtoworldpos(texcoord.xy, nbuf.w);
vec3 indirect = vec3(0);
float dlong = 3.1415 * (3.0 - sqrt(5.0));
float dz = 1.0 / float(SAMPLES);
float Long = 0.0;
float z = 1.0 - dz / 2.0;
for(int i = 0; i < SAMPLES; i++)
{
float r = sqrt(1.0 - z);
vec2 point = vec2((cos(Long) * r), (sin(Long) * r)) ;
z = z - dz;
Long = Long + dlong;
vec2 doffset = dither(texcoord.xy, (i * 20 + useed * 0.2512123) / 100, texturesize) * 0.5;
//doffset*=0;
//vec2 doffset = point+nbuf.xy;
//doffset += nbuf.xy;
doffset *= 0.5;
doffset += point.xy;
//doffset += nbuf.xy;
indirect += lightSample(doffset + texcoord.xy, nbuf.xyz, centerpos, nbuf.w);
}
color.xyz = indirect / SAMPLES;
color.xyz = (diffuse.xyz * indirect / SAMPLES * indirectstr) + incolor.xyz;
color.w = incolor.w;
}
}