@@ -7,67 +7,84 @@ $define shader fragment
77
88$include ../functions/ common.glsl
99$include ../functions/ hash.glsl
10- $include ssaoParams.glsl
10+ // $include ssaoParams.glsl
11+ 
12+ 
13+ layout (std140, binding =  CAGE_SHADER_UNIBLOCK_CUSTOMDATA) uniform  Ssao
14+ {
15+ 	mat4  proj;
16+ 	mat4  projInv;
17+ 	vec4  params; //  strength, bias, power, radius
18+ 	ivec4  iparams; //  sampleCount, hashSeed
19+ };
20+ 
1121
1222layout (std140, binding =  3 ) uniform  SsaoPoints
1323{
24+ 	//  unit sphere samples; .w is [0,1] random scalar
1425	vec4  pointsOnSphere[256 ];
1526};
1627
17- layout (binding =  0 ) uniform  sampler2D  texDepth;
28+ layout (binding =  0 ) uniform  sampler2D  texDepth;  //  NDC depth [0,1] 
1829
1930out  float  outAo;
2031
21- vec3  reconstructNormal(vec3  position)
22- {
23- 	return  normalize (cross (dFdx (position), dFdy (position)));
24- }
25- 
26- vec3  s2w(vec2  p, float  d)
32+ //  inputs in NDC [-1,1]
33+ vec3  ndcToView(vec2  p, float  d)
2734{
2835	vec4  p4 =  vec4 (p, d, 1 );
2936	p4 =  projInv *  p4;
3037	return  p4.xyz /  p4.w;
3138}
3239
40+ //  all view-space
41+ vec3  reconstructNormal(vec3  position)
42+ {
43+ 	return  normalize (cross (dFdx (position), dFdy (position)));
44+ }
45+ 
3346void  main()
3447{
3548	vec2  resolution =  vec2 (textureSize(texDepth, 0 ));
36- 	vec2  myUv =  gl_FragCoord .xy /  resolution;
37- 	float  myDepth =  textureLod(texDepth, myUv, 0 ).x *  2.0   -  1.0  ; 
49+ 	vec2  myUv =  gl_FragCoord .xy /  resolution;  //  screen-space [0,1] 
50+ 	float  myDepth =  textureLod(texDepth, myUv, 0 ).x *  2  -  1 ;  //  NDC depth [-1,1] 
3851	if  (myDepth >  0.999 )
3952	{ //  no occlusion on skybox
4053		outAo =  0 ;
4154		return ;
4255	}
43- 	vec3  myPos =  s2w (myUv, myDepth);
44- 	vec3  myNormal =  reconstructNormal(myPos);
56+ 	vec3  myPos =  ndcToView (myUv  *   2   -   1 , myDepth);  //  view-space position 
57+ 	vec3  myNormal =  reconstructNormal(myPos);  //  view-space normal 
4558
4659	//  sampling
47- 	int  n =  int ( hash(uint (gl_FragCoord .x) ^  hash(uint (gl_FragCoord .y)) ^  uint (iparams[1 ]))); 
60+ 	uint  n =  hash(uint (gl_FragCoord .x) ^  hash(uint (gl_FragCoord .y)) ^  uint (iparams[1 ]));  //  per-pixel seed 
4861	float  ssaoRadius =  params[3 ];
49- 	float  occ =  0.0  ;
50- 	float  total =  0.0  ;
62+ 	float  occ =  0 ;
63+ 	float  total =  0 ;
5164	for  (int  i =  0 ; i <  iparams[0 ]; i++ )
5265	{
53- 		vec3  dir =  pointsOnSphere[hash(uint (n *  17  +  i)) %  256 ].xyz;
54- 		float  d =  dot (myNormal, dir);
66+ 		//  view-space ray direction
67+ 		vec3  rayDir =  pointsOnSphere[hash(uint (n *  17  +  i)) %  256 ].xyz;
68+ 		float  d =  dot (myNormal, rayDir);
5569		if  (abs (d) <  0.1 )
5670			continue ; //  the direction is close to the surface and susceptible to noise
57- 		dir =  sign (d) *  dir; //  move the direction into front hemisphere
58- 		float  r =  (sqr(pointsOnSphere[hash(uint (n *  13  +  i)) %  256 ].w) *  0.9  +  0.1 ) *  ssaoRadius;
59- 		vec3  sw =  myPos +  dir *  r;
60- 		vec4  s4 =  proj *  vec4 (sw, 1.0 );
61- 		vec3  ss =  s4.xyz /  s4.w;
62- 		float  sampleDepth =  textureLod(texDepth, ss.xy, 0 ).x *  2.0  -  1.0 ;
63- 		if  (sampleDepth <  ss.z)
71+ 		rayDir =  sign (d) *  rayDir; //  move the direction into front hemisphere
72+ 		rayDir *=  (sqr(pointsOnSphere[hash(uint (n *  13  +  i)) %  256 ].w) *  0.9  +  0.1 ) *  ssaoRadius;
73+ 
74+ 		vec3  rayPos =  myPos +  rayDir; //  view-space ray position
75+ 		vec4  r4 =  proj *  vec4 (rayPos, 1 ); //  clip space
76+ 		vec3  rayNdc =  r4.xyz /  r4.w; //  NDC [-1,1]
77+ 
78+ 		float  sampleDepth =  textureLod(texDepth, rayNdc.xy *  0.5  +  0.5 , 0 ).x *  2  -  1 ; //  NDC depth [-1,1]
79+ 		if  (sampleDepth <  rayNdc.z)
6480		{
65- 			vec3  otherPos  =  s2w(ss .xy, sampleDepth);
66- 			float  diff =  length (sw  -  otherPos );
67- 			occ +=  smoothstep (1.0  ,  0. 0 , diff /  ssaoRadius);
81+ 			vec3  samplePos  =  ndcToView(rayNdc .xy, sampleDepth);  //  view-space sample position 
82+ 			float  diff =  length (rayPos  -  samplePos );
83+ 			occ +=  smoothstep (1 ,  0 , diff /  ssaoRadius);
6884		}
69- 		total +=  1.0  ;
85+ 		total +=  1 ;
7086	}
87+ 
7188	if  (total >  0 )
7289		outAo =  occ /  total;
7390	else 
0 commit comments