File: shader_analysis_color.frag

package info (click to toggle)
meshlab 2022.02%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 47,348 kB
  • sloc: cpp: 536,635; ansic: 27,783; sh: 539; makefile: 36
file content (166 lines) | stat: -rw-r--r-- 4,271 bytes parent folder | download | duplicates (10)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* Analysis step */
#version 120

#extension GL_ARB_draw_buffers : enable

// flag for depth test on/off
uniform bool depth_test;

// 2.0*size of current level / size of one level down
uniform vec2 level_ratio;

// current read level
uniform int level;

uniform vec2 offset;

uniform float reconstruction_filter_size;
uniform float prefilter_size;

uniform sampler2D textureA;
uniform sampler2D textureB;
uniform sampler2D textureC;

// tests if a point is inside an ellipse.
// Ellipse is centered at origin and point displaced by d.
// Radius is the half the ellipse's major axis.
// Minor axis is computed by normal direction.
float pointInEllipse(in vec2 d, in float radius, in vec3 normal){
  float len = length(normal.xy);

  if (len == 0.0)
    normal.y = 0.0;
  else
    normal.y /= len;

  // angle between normal and z direction
  float angle = acos(normal.y);
  if (normal.x > 0.0)
    angle *= -1.0;

  float cos_angle = normal.y;
  float sin_angle = sin(angle);

  // rotate point to ellipse coordinate system
  vec2 rotated_pos = vec2(d.x*cos_angle + d.y*sin_angle,
						  -d.x*sin_angle + d.y*cos_angle);

  // major and minor axis
  float a = 1.0*radius;
  float b = a*normal.z;

  // include antialiasing filter
  a += prefilter_size;
  b += prefilter_size;

  // inside ellipse test
  float test = ((rotated_pos.x*rotated_pos.x)/(a*a)) + ((rotated_pos.y*rotated_pos.y)/(b*b));

  if (test <= reconstruction_filter_size)
    return test;
  else return -1.0;
}

void main (void) {

  vec2 tex_coord[4];
  
  vec4 bufferA = vec4(0.0, 0.0, 0.0, 0.0);
  vec4 bufferB = vec4(0.0, 0.0, 0.0, 0.0);
  vec4 bufferC = vec4(0.0, 0.0, 0.0, 0.0);

  float valid_pixels = 0.0;

  vec4 pixelA[4], pixelB[4], pixelC[4];
	
	vec2 center_coord = gl_TexCoord[0].st * level_ratio;

	//up-right
	tex_coord[0].st = center_coord.st + offset.st;
	//up-left
	tex_coord[1].s = center_coord.s - offset.s;
	tex_coord[1].t = center_coord.t + offset.t;
	//down-right
	tex_coord[2].s = center_coord.s + offset.s;
	tex_coord[2].t = center_coord.t - offset.t;
	//down-left
	tex_coord[3].st = center_coord.st - offset.st;

	// Compute the front most pixel from lower level (minimum z
	// coordinate)
	float dist_test = 0.0;
	float zmin = 10000.0;
	float zmax = -10000.0;
	float obj_id = -1.0;
	for (int i = 0; i < 4; ++i) {
		pixelA[i] = texture2DLod (textureA, tex_coord[i].st, float(level-1)).xyzw;   
		if (pixelA[i].w > 0.0) {
			pixelB[i] = texture2DLod (textureB, tex_coord[i].st, float(level-1)).xyzw;
			dist_test = pointInEllipse(pixelB[i].zw - gl_TexCoord[0].st, pixelA[i].w, pixelA[i].xyz);

			if  (dist_test > -10.0)
			{
				// test for minimum depth coordinate of valid ellipses
				if (pixelB[i].x <= zmin) {
					zmin = pixelB[i].x;
					zmax = zmin + pixelB[i].y;
				}
			}
			else {
				// if the ellipse does not reach the center ignore it in the averaging
				pixelA[i].w = -1.0;
			}
		}
  }

  float new_zmax = zmax;

  // Gather pixels values
  for (int i = 0; i < 4; ++i)
    {
      // Check if valid gather pixel or unspecified (or ellipse out of reach set above)
      if (pixelA[i].w > 0.0) 
		{
		  pixelC[i] = texture2DLod (textureC, tex_coord[i].st, float(level-1)).xyzw;
	  	
		  // Depth test between valid in reach ellipses
		  if ((!depth_test) || (pixelB[i].x - pixelB[i].y <= zmin))
			{
			  float w = 1.0;
			  bufferA += pixelA[i] * w;

			  // Increment ellipse total path with distance from gather pixel to center
			  bufferB.xyzw += pixelB[i].xyzw * w;
	      
			  bufferC += pixelC[i] * w;

			  // Take maximum depth range
			  new_zmax = max(pixelB[i].x + pixelB[i].y, new_zmax);
	      
			  valid_pixels += w;
			}
		}
	}
    
  	// average values if there are any valid ellipses
  	// otherwise the pixel will be writen as unspecified  
	if (valid_pixels > 0.0)
	{
		bufferA /= valid_pixels;
		bufferA.xyz = normalize(bufferA.xyz);
		bufferB.x = zmin;
		bufferB.y = new_zmax - zmin;
		bufferB.zw /= valid_pixels;
		//~ bufferB.xyzw /= valid_pixels;
		//~ bufferB.y = 0.0;
		bufferC.rgb /= valid_pixels;
		bufferC.w = 1.0;
	}

	// first buffer = (n.x, n.y, n.z, radius)
	gl_FragData[0] = bufferA;
	// second buffer = (depth, max_depth, dx, dy)
	gl_FragData[1] = bufferB;
	// color value = (r, g, b, obj_id)
	gl_FragData[2] = bufferC;
}