Example #1
0
float inner_tesslevel()
{
	vec4 bbox_min = texelFetch(attribute_texture, int(vIndex[ID]) * 5 + 2);
	vec4 bbox_max = texelFetch(attribute_texture, int(vIndex[ID]) * 5 + 3);
	vec3 combin[8];
	int i, j;
	float max_length = 0.0;

	combin[0] = to_screen_space(vec3(bbox_min.x, bbox_min.y, bbox_min.z)).xyz;
	combin[1] = to_screen_space(vec3(bbox_min.x, bbox_min.y, bbox_max.z)).xyz;
	combin[2] = to_screen_space(vec3(bbox_min.x, bbox_max.y, bbox_min.z)).xyz;
	combin[3] = to_screen_space(vec3(bbox_min.x, bbox_max.y, bbox_max.z)).xyz;
	combin[4] = to_screen_space(vec3(bbox_max.x, bbox_min.y, bbox_min.z)).xyz;
	combin[5] = to_screen_space(vec3(bbox_max.x, bbox_min.y, bbox_max.z)).xyz;
	combin[6] = to_screen_space(vec3(bbox_max.x, bbox_max.y, bbox_min.z)).xyz;
	combin[7] = to_screen_space(vec3(bbox_max.x, bbox_max.y, bbox_max.z)).xyz;

	for ( i = 0; i < 7; i++ ) {
		for ( j = i + 1; j < 8; j++ ) {
			float temp_length = length(combin[i].xy - combin[j].xy);

			if ( temp_length > max_length ) {
				max_length = temp_length;
			}
		}
	}

	max_length = clamp(max_length, 0, 900);

	return clamp(ceil(max_length / 8.0), 2.0, 64.0);
}
Example #2
0
	vec4 gradient_color(int stop_start, int stop_end, float t)
	{
		vec4 color = texelFetch(instance_data, ivec2(instance_offset.x + stop_start, instance_offset.y), 0);
		float last_stop_pos = texelFetch(instance_data, ivec2(instance_offset.x + stop_start + 1, instance_offset.y), 0).x;
		for (int i = stop_start; i < stop_end; i+=2)
		{
			vec4 stop_color = texelFetch(instance_data, ivec2(instance_offset.x + i, instance_offset.y), 0);
			float stop_pos = texelFetch(instance_data, ivec2(instance_offset.x + i + 1, instance_offset.y), 0).x;
			float tt = clamp((t - last_stop_pos)/(stop_pos - last_stop_pos), 0.0, 1.0);
			color = mix(color, stop_color, tt);
			last_stop_pos = stop_pos;
		}
		return color;
	}
Example #3
0
int GetVoxel(vec3 voxel)
{
	ivec3 arrayIndex;
	if(GetArrayIndex(voxel, arrayIndex))
	{
		return int(floor(texelFetch(data, arrayIndex, 0).g * 255));
	}

	return 255; // Return vacuum if block is invalid
}
Example #4
0
vec4 control_polygon_length(in samplerBuffer	data,
			    in int		offset,
			    in int 		u,
			    in int		v)
{
	int i, j;
	vec4 output = vec4(0.0);
	vec4 first, second;
	mat4 mvp = projection_matrix * view_matrix * model_matrix;

//	2------3
//	|      |
//      |      |
//      0------1

	/*For Edge 01*/
	for ( i = 1; i < u; ++i ) {
		output[0] += edge_length(texelFetch(data, offset + i).xyz, texelFetch(data, offset + i - 1).xyz);
	}

	/*For Edge 13*/
	for ( i = 2 * u - 1; i < u * v; i += u ) {
		output[1] += edge_length(texelFetch(data, offset + i).xyz, texelFetch(data, offset + i - u).xyz);
	}

	/*For Edge 23*/
	for ( i = u * v - u + 1; i < u * v; ++i ) {
		output[2] += edge_length(texelFetch(data, offset + i).xyz, texelFetch(data, offset + i - 1).xyz);
	}

	/*For Edge 02*/
	for ( i = u; i <= u * v - u; i += u ) {
		output[3] += edge_length(texelFetch(data, offset + i).xyz, texelFetch(data, offset + i - u).xyz);
	}
/**/
	return output;
}
Example #5
0
i32 main()
{
  SDL_Window  * sdl_window;
  SDL_GLContext sdl_glcontext;
  
  gfWindow(&sdl_window, &sdl_glcontext, 0, 0, "App", 1280, 720, 4);
  
  gpu_storage_t mesh = {0};
  mesh.format = xyz_f32;
  mesh.count  = 3;
  mesh = gfStorageCreateFromStruct(mesh);
  
  mesh.as_vec3[0].x = -0.5f;
  mesh.as_vec3[0].y = -0.5f;
  mesh.as_vec3[0].z =  0.0f;
  
  mesh.as_vec3[1].x =  0.0f;
  mesh.as_vec3[1].y =  0.5f;
  mesh.as_vec3[1].z =  0.0f;
  
  mesh.as_vec3[2].x =  0.5f;
  mesh.as_vec3[2].y = -0.5f;
  mesh.as_vec3[2].z =  0.0f;
  
  gpu_cmd_t cmd[1] = {0};
  
  cmd[0].count = mesh.count;
  cmd[0].instance_count = 1;
  
  const char * vs_str = VERT_HEAD STR
  (
    layout(binding = 0) uniform samplerBuffer in_pos;
    
    void main()
    {
      vec3 pos = texelFetch(in_pos, gl_VertexID).xyz;
      gl_Position = vec4(pos, 1.f);
    }
Example #6
0
void main()
{             

#ifdef MULTISAMPLE
	ivec2 screensize =textureSize( g_depth /*,0*/ );
#else
	ivec2 screensize =textureSize( g_depth, 0 );
#endif
	ndc_position = ( gl_FragCoord.xy / screensize ) * vec2(1) - vec2(1);

  // Retrieve data from gbuffer
#ifndef MULTISAMPLE
  //vec3 f_position = vec3(vec4(positionFromDepth( 0 ),1));
  
  vec4 fragCoord =texture( g_position, ndc_position).rgba;
  vec3 f_normal = mat3(mat_view)*texture(g_normal, ndc_position).rgb;
	vec3 f_diffuse = texture(g_diffusespec, ndc_position).rgb;
	float f_specular = texture(g_diffusespec, ndc_position).a;
#endif
	
	vec3 color =vec3(0);

#ifdef MULTISAMPLE
	/* For MS, we average over all the samples */
  for( int i=0; i < NUM_SAMPLES; i++ ) {
  
  	vec4 fragCoord =texelFetch( g_position, ivec2(gl_FragCoord.xy), i).rgba;
  	vec3 f_normal = mat3(mat_view) * texelFetch( g_normal, ivec2(gl_FragCoord.xy), i).rgb;
		vec3 f_diffuse = texelFetch( g_diffusespec, ivec2(gl_FragCoord.xy), i).rgb;
		float f_specular = texelFetch( g_diffusespec, ivec2(gl_FragCoord.xy), i).a;
#endif

		/* Calculate the NDC from the stored fragCoord,
			 then reconstruct the view-space position using the inverse projection matrix */
		vec4 ndcPos;
		ndcPos.xy = ((2.0 * fragCoord.xy) - (2.0 * vec2(0))) / (screensize) - 1;
		ndcPos.z = (2.0 * fragCoord.z - gl_DepthRange.near - gl_DepthRange.far) /
				(gl_DepthRange.far - gl_DepthRange.near);
		ndcPos.w = 1.0;
 
		vec4 clipPos = ndcPos / fragCoord.w;
	
		vec3 f_position = vec3(mat_windowtoview * clipPos);

		float attenuation = 1.0;
		vec3 diffuse;
		vec3 specular;
		vec3 lighting  = f_diffuse * 0.001; // hard-coded ambient component
		vec3 viewDir  = normalize( - f_position);
	
		if( light_direction.xyz == vec3(0) ) { // assumes point-light
	
			// Diffuse
			vec3 lightDir = normalize(light_position - f_position);
			diffuse = max(dot(f_normal, lightDir), 0.0) * f_diffuse * light_intensity;

			// Specular
			vec3 halfwayDir = normalize(lightDir + viewDir);  
			float spec = pow(max(dot(f_normal, halfwayDir), 0.0), 16.0);
			specular = light_intensity * spec * f_specular;

			// Attenuation
			float distance = length(light_position - f_position);
			attenuation = 1.0 / ( 
				light_attenuation.x +  // constant
				light_attenuation.y * distance +  // linear
				light_attenuation.z * distance * distance); // quadratic
		
		} else { // directional light

			lighting  = f_diffuse * 0.1; // DELETE ME
			vec3 lightDir = normalize(-light_direction);  
			float diff = max(dot(f_normal, lightDir), 0.0);
			diffuse = light_intensity * diff * f_diffuse;  
		
			// Specular
			vec3 reflectDir = reflect(-lightDir, f_normal);  
			float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16.0 );
			specular = light_intensity * spec * f_specular;
		}
		
		diffuse *= attenuation;
		specular *= attenuation;
		lighting += diffuse + specular;
		
#ifdef MULTISAMPLE
		color += (1.0 / NUM_SAMPLES) * lighting;
	}
#else
	color =lighting;
#endif
		
	fragColor = vec4(color, 1.0);
}
Example #7
0
void main()
{
  //Calculate the ray direction using viewport information
  vec3 rayDirection = frag_worldpos - RayOrigin;
  rayDirection = normalize(rayDirection);
  
  //Cube ray intersection test
  vec3 invR = 1.0 / rayDirection;
  vec3 tbot = invR * (volumeMin - RayOrigin);
  vec3 ttop = invR * (volumeMax - RayOrigin);
  
  //Now sort all elements of tbot and ttop to find the two min and max elements
  vec3 tmin = min(ttop, tbot); //Closest planes
  vec2 t = max(tmin.xx, tmin.yz); //Out of the closest planes, find the last to be entered (collision point)
  float tnear = max(t.x, t.y);//...
  
  //If the viewpoint is penetrating the volume, make sure to only cast the ray
  //from the eye position, not behind it
  tnear = max(0.0, tnear);
  
  //Now work out when the ray will leave the volume
  vec3 tmax = max(ttop, tbot); //Distant planes
  t = min(tmax.xx, tmax.yz);//Find the first plane to be exited
  float tfar = min(t.x, t.y);//...
  
  //Check what the screen depth is to make sure we don't sample the
  //volume past any standard GL objects
  float bufferDepth = texelFetch(DepthTexture, ivec2(gl_FragCoord.xy), 0).r;
  float depth = recalcZCoord(bufferDepth);
  tfar = min(depth, tfar);
  
  //We need to calculate the ray's starting position. We add a random
  //fraction of the stepsize to the original starting point to dither
  //the output
  float starting_offset = tnear; 

  if (DitherRay != 0)
    starting_offset += StepSize * fract(sin(gl_FragCoord.x * 12.9898 + gl_FragCoord.y * 78.233) * 43758.5453);

  vec3 rayPos = RayOrigin + rayDirection * starting_offset;
  
  //The color accumulation variable
  vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
  
  //Start the sampling by initialising the ray variables. We take the
  //first sample ready to integrate to the next sample
  vec4 first_sample = texture(DataTexture, (rayPos + 1.0) * 0.5);

  float lastsamplea = first_sample.a;
  vec4 lastTransfer = texture(IntTransferTexture, lastsamplea);
  vec3 lastnorm = first_sample.xyz * 2.0 - vec3(1.0);
  float lastnorm_length = length(lastnorm);
  lastnorm = (lastnorm_length == 0) ? -rayDirection : lastnorm / lastnorm_length;

  //Make this into the ray position step vector
  rayDirection *= StepSize;

  rayPos += rayDirection;

  for (float length = tfar - tnear; length > 0.0;
       length -= StepSize, rayPos += rayDirection)
    {
      //Grab the volume sample
      vec4 sample = texture(DataTexture, (rayPos - volumeMin) * invVolumeDimensions);
      float delta = sample.a - lastsamplea;
      vec4 transfer = texture(IntTransferTexture, sample.a);
      float deltaT = transfer.a - lastTransfer.a;
      vec3 deltaK = transfer.rgb - lastTransfer.rgb;

      vec4 src;
      if (delta == 0.0)
	{ //Special case where the integration breaks down, just use the constant val.
	  src = texture(TransferTexture, sample.a);
	  src.a = (1.0 - exp( - StepSize * src.a));
	}
      else
	{
	  /*Pre-Integrated color calc*/
	  float opacity = 1.0 - exp( - deltaT * StepSize / delta);
	  vec3 color = abs(deltaK) / (abs(deltaT) + 1.0e-10);
	  src = vec4(color, opacity);
	}

      lastTransfer = transfer;
      lastsamplea = sample.a;

      ////////////Lighting calculations
      //We perform all the calculations in the eye space, The normal
      //from the previous step is used, as it is the normal in the
      //direction the ray entered the volume.
      vec3 norm = (ViewMatrix * vec4(lastnorm, 0.0)).xyz;      
      src.rgb = calcLighting((ViewMatrix * vec4(rayPos,1.0)).xyz, norm, src.rgb);

      //Update the lastnormal with the new normal, if it is valid
      norm = sample.xyz * 2.0 - vec3(1.0);
      //Test if we've got a bad normal and need to reuse the old one
      float sqrnormlength = dot(norm,norm);
      norm /= sqrt(sqrnormlength);
      if (sqrnormlength >= 0.01)
	lastnorm = norm;

      ///////////Front to back blending
      src.rgb *= src.a;
      color = (1.0 - color.a) * src + color;
  
      //We only accumulate up to 0.95 alpha (the blending never
      //reaches 1).
      if (color.a >= 0.95)
  	{
  	  //We have to renormalize the color by the alpha value (see
  	  //below)
  	  color.rgb /= color.a;
  	  //Set the alpha to one to make sure the pixel is not transparent
  	  color.a = 1.0;
  	  break;
  	}
    }
  /*We must renormalize the color by the alpha value. For example, if
  our ray only hits just one white voxel with a alpha of 0.5, we will have
  
  src.rgb = vec4(1,1,1,0.5)
  
  src.rgb *= src.a; 
  //which gives, src.rgb = 0.5 * src.rgb = vec4(0.5,0.5,0.5,0.5)
  
  color = (1.0 - color.a) * src + color;
  //which gives, color = (1.0 - 0) * vec4(0.5,0.5,0.5,0.5) + vec4(0,0,0,0) = vec4(0.5,0.5,0.5,0.5)
  
  So the final color of the ray is half way between white and black, but the voxel it hit was white!
  The solution is to divide by the alpha, as this is the "amount of color" added to color.
  */
  color.rgb /= float(color.a == 0.0) + color.a;
  color_out = color;
});
Example #8
0
void
HornerBernstein(in samplerBuffer 	data,
		in int			offset,
		in int 			OrderU,
		in int 			OrderV,
		in vec2 		uv,
		out vec4 		du,
		out vec4		dv,
		out vec4 		point)
{
	int i, j;
	int n = OrderU - 1;
	int m = OrderV - 1;
	float powu, powv, nci, mcj;

	vec4 tpoint0;
	vec4 tpointi;
	vec4 tpointn; 			//For i == n
	point = vec4(0.0);

	//For First and Last Rows
	tpoint0 = tpointn = vec4(0.0);
	nci = mcj = powu = powv = 1.0;

	for ( j = 0; j < m; j++ ) {
		tpoint0 = (tpoint0 + mcj * powv * texelFetch(data, offset + OrderU * j)) * (1.0 - uv[1]);
		tpointn = (tpointn + mcj * powv * texelFetch(data, offset + OrderU * j + n)) * (1.0 - uv[1]);
		mcj *= float(m - j) / float(j + 1);
		powv *= uv[1];
	}

	tpoint0 = tpoint0 + powv * texelFetch(data, offset + OrderU * j);
	tpointn = tpointn + powv * texelFetch(data, offset + OrderU * j + n);
	point = (point + nci * powu * tpoint0) * (1.0 - uv[0]);
	nci = nci * float(n);
	powu = powu * uv[0];

	//For Remaining Rows
	for ( i = 1; i < n; i++ ) {
		tpointi = vec4(0.0);
		mcj = 1.0;
		powv = 1.0;

		for ( j = 0; j < m; j++ ) {
			tpointi = (tpointi + mcj * powv * texelFetch(data, offset + OrderU * j + i)) * (1.0 - uv[1]);
			mcj *= float(m - j) / float(j + 1);
			powv *= uv[1];
		}

		tpointi = tpointi + powv * texelFetch(data, offset + OrderU * j + i);
		point = (point + nci * powu * tpointi) * (1.0 - uv[0]);
		nci = nci * float(n - i) / float(i + 1);
		powu = powu * uv[0];
	}

	point = point + powu * tpointn;

	//Partial Derivative with respect to u   dP/du
	powu = powv = nci = mcj = 1.0;
	du = tpoint0 = tpointn = vec4(0.0);

	for ( j = 0; j < m; j++ ) {
		tpoint0 = (tpoint0 + mcj * powv * (texelFetch(data, offset + OrderU * j + 1) - texelFetch(data, offset + OrderU * j) ) ) * (1.0 - uv[1]);
		tpointn = (tpointn + mcj * powv * (texelFetch(data, offset + OrderU * j + n) - texelFetch(data, offset + OrderU * j + n - 1)) ) * (1.0 - uv[1]);
		mcj *= float(m - j) / float(j + 1);
		powv *= uv[1];
	}

	tpoint0 = tpoint0 + powv * (texelFetch(data, offset + OrderU * j + 1) - texelFetch(data, offset + OrderU * j));
	tpointn = tpointn + powv * (texelFetch(data, offset + OrderU * j + n) - texelFetch(data, offset + OrderU * j + n - 1));
	du = (du + nci * powu * tpoint0) * (1.0 - uv[0]);
	nci = nci * float(n - 1);
	powu = powu * uv[0];

	//For Remaining Rows
	for ( i = 1; i < n - 1; i++ ) {
		tpointi = vec4(0.0);
		mcj = 1.0;
		powv = 1.0;

		for ( j = 0; j < m; j++ ) {
			tpointi = (tpointi + mcj * powv * (texelFetch(data, offset + OrderU * j + i + 1) - texelFetch(data, offset + OrderU * j + i))) * (1.0 - uv[1]);
			mcj *= float(m - j) / float(j + 1);
			powv *= uv[1];
		}

		tpointi = tpointi + powv * (texelFetch(data, offset + OrderU * j + i + 1) - texelFetch(data, offset + OrderU * j + i));
		du = (du + nci * powu * tpointi) * (1.0 - uv[0]);
		nci = nci * float(n - i - 1) / float(i + 1);
		powu = powu * uv[0];
	}

	du = du + powu * tpointn;
	du = du * n;

	//Partial Derivative with respect to v   dP/dv
	dv = vec4(0.0);
	powu = 1.0;
	powv = 1.0;
	nci = 1.0; mcj = 1.0;
	tpoint0 = vec4(0.0);
	tpointn = vec4(0.0);

	for ( j = 0; j < m - 1; j++ ) {
		tpoint0 = (tpoint0 + mcj * powv * ( texelFetch(data, offset + OrderU * (j + 1)) - texelFetch(data, offset + OrderU * j) ) ) * (1.0 - uv[1]);
		tpointn = (tpointn + mcj * powv * (texelFetch(data, offset + OrderU * (j + 1) + n) - texelFetch(data, offset + OrderU * j + n)) ) * (1.0 - uv[1]);
		mcj *= float(m - j - 1) / float(j + 1);
		powv *= uv[1];
	}

	tpoint0 = tpoint0 + powv * (texelFetch(data, offset + OrderU * (j + 1)) - texelFetch(data, offset + OrderU * j));
	tpointn = tpointn + powv * (texelFetch(data, offset + OrderU * (j + 1) + n) - texelFetch(data, offset + OrderU * j + n));

	dv = (dv + nci * powu * tpoint0) * (1.0 - uv[0]);
	nci = nci * float(n);
	powu = powu * uv[0];

	//For Remaining Rows
	for ( i = 1; i < n; i++ ) {
		tpointi = vec4(0.0);
		mcj = 1.0;
		powv = 1.0;

		for ( j = 0; j < m - 1; j++ ) {
			tpointi = (tpointi + mcj * powv * (texelFetch(data, offset + OrderU * (j + 1) + i) - texelFetch(data, offset + OrderU * j + i))) * (1.0 - uv[1]);
			mcj *= float(m - j - 1) / float(j + 1);
			powv *= uv[1];
		}

		tpointi = tpointi + powv * (texelFetch(data, offset + OrderU * (j + 1) + i) - texelFetch(data, offset + OrderU * j + i));
		dv = (dv + nci * powu * tpointi) * (1.0 - uv[0]);
		nci = nci * float(n - i) / float(i + 1);
		powu = powu * uv[0];
	}

	dv = dv + powu * tpointn;
	dv = dv * m;

	//Transformation from Homogeneous Space to Euclidean Space
	du = (du * point.w - point * du.w) / pow(point.w, 2);		//P.S.:  simply p(t) = r(t) / s(t) => p'(t) = (r'(t)s(t)-r(t)s'(t)) / (s(t)^2) .....
        dv = (dv * point.w - point * dv.w) / pow(point.w, 2);		//P.S.: p(t) = r(t) / s(t) => r(t) = p(t) x s(t) => r'(t) = p'(t)xs(t) + p(t)xs'(t) => p'(t) = ..... doesn't give precise results
        point = point / point.w;
}
Example #9
0
void main()
{
	tcPosition[ID] 	= vPosition[ID];
	tcIndex[ID] 	= vIndex[ID];
	tcTessCoord[ID] = vTessCoord[ID];

	vec4 data = texelFetch(attribute_texture, int(vIndex[ID]) * 5);

	if ( frustum_cull() ) {
		if ( abs(vTessCoord[0].x - vTessCoord[1].x) * abs(vTessCoord[1].y - vTessCoord[2].y) == 1.0 ) {
			vec4 curve_factor = clamp(texelFetch(attribute_texture, int(vIndex[ID]) * 5 + 4), 1, 4);
			vec4 edgelen = control_polygon_length(parameter_texture, int(data.x), int(data.y), int(data.z));

			//	    2
			//	2------3
			//3	|      |      1
			//      |      |
			//      0------1
			//	    0

			float edge01 = edge_tesslevel(edgelen[0]);
			float edge32 = edge_tesslevel(edgelen[2]);
			float edge13 = edge_tesslevel(edgelen[1]);
			float edge20 = edge_tesslevel(edgelen[3]);

			//Following three must be same for Ist Pass
			gl_TessLevelInner[0] = inner_tesslevel();
			gl_TessLevelOuter[1] = edge01;
			gl_TessLevelOuter[3] = edge32;

			//Following three must be same for Ist Pass
			gl_TessLevelInner[1] = inner_tesslevel();
			gl_TessLevelOuter[0] = edge20;
			gl_TessLevelOuter[2] = edge13;
		} else {
			vec4 point_on_plane0 = to_screen_space(vPosition[0]);
			vec4 point_on_plane1 = to_screen_space(vPosition[1]);
			vec4 point_on_plane2 = to_screen_space(vPosition[2]);
			vec4 point_on_plane3 = to_screen_space(vPosition[3]);

			//Approach I-----> For Outer Tessellation Levels : Take ratio according to the original control polygon length.
			//		   For Inner Tessellation Levels : Evaluate the mid point of the patch and get the diagonal length.

			vec4 edgelen = control_polygon_length(parameter_texture, int(data.x), int(data.y), int(data.z));

			vec2 p1 = mix(vTessCoord[0].xy, vTessCoord[1].xy, 0.5);
			vec2 p2 = mix(vTessCoord[3].xy, vTessCoord[2].xy, 0.5);

			vec2 mid_uv = mix(p1, p2, 0.5);
			vec4 du, dv, _puv;

			HornerBernstein(parameter_texture, int(data.x), int(data.y), int(data.z), mid_uv, du, dv, _puv);

			_puv = to_screen_space(_puv.xyz);

			float length1 = length(point_on_plane0.xy - _puv.xy) + length(_puv.xy - point_on_plane3.xy);
			float length2 = length(point_on_plane2.xy - _puv.xy) + length(_puv.xy - point_on_plane1.xy);

			float diagonal_length = min(length1, length2);

			float edge01 = edge_tesslevel(mix(edgelen[0], edgelen[2], abs(vTessCoord[0].y - vTessCoord[2].y)));
			float edge32 = edge_tesslevel(mix(edgelen[0], edgelen[2], abs(vTessCoord[0].y - vTessCoord[2].y)));
			float edge13 = edge_tesslevel(mix(edgelen[1], edgelen[3], abs(vTessCoord[0].x - vTessCoord[1].x)));
			float edge20 = edge_tesslevel(mix(edgelen[1], edgelen[3], abs(vTessCoord[0].x - vTessCoord[1].x)));

			/*****/

			//Approach II-----> For Outer Tessellation Levels : Approximate the curvature length of the edge according to the angle between its normals.
			//		    For Inner Tessellation Levels : Approximate the curvature of the surface according to the all edge normals.

			//Normals projected in XY-Plane
/*			vec2 normal0 = normalize(transpose(inverse(mat3(view_matrix * model_matrix))) * vNormal[0].xyz).xy;
			vec2 normal1 = normalize(transpose(inverse(mat3(view_matrix * model_matrix))) * vNormal[1].xyz).xy;
			vec2 normal2 = normalize(transpose(inverse(mat3(view_matrix * model_matrix))) * vNormal[2].xyz).xy;
			vec2 normal3 = normalize(transpose(inverse(mat3(view_matrix * model_matrix))) * vNormal[3].xyz).xy;

			float edge01 = edge_tesslevel(length(point_on_plane0 - point_on_plane1) * acos(dot(normal0, normal1)) / (2.0 * sin(acos(dot(normal0, normal1) / 2.0))));
			float edge32 = edge_tesslevel(length(point_on_plane3 - point_on_plane2) * acos(dot(normal3, normal2)) / (2.0 * sin(acos(dot(normal3, normal2) / 2.0))));
			float edge13 = edge_tesslevel(length(point_on_plane1 - point_on_plane3) * acos(dot(normal1, normal3)) / (2.0 * sin(acos(dot(normal1, normal3) / 2.0))));
			float edge20 = edge_tesslevel(length(point_on_plane2 - point_on_plane0) * acos(dot(normal2, normal0)) / (2.0 * sin(acos(dot(normal2, normal0) / 2.0))));*/

			//Following three must be same for Ist Pass
			gl_TessLevelInner[0] = edge_tesslevel(diagonal_length);
			gl_TessLevelOuter[1] = edge01;
			gl_TessLevelOuter[3] = edge32;

			//Following three must be same for Ist Pass
			gl_TessLevelInner[1] = edge_tesslevel(diagonal_length);
			gl_TessLevelOuter[0] = edge20;
			gl_TessLevelOuter[2] = edge13;
		}
	} else {
		gl_TessLevelInner[0] = 1;
		gl_TessLevelOuter[1] = 1;
		gl_TessLevelOuter[3] = 1;

		gl_TessLevelInner[1] = 1;
		gl_TessLevelOuter[0] = 1;
		gl_TessLevelOuter[2] = 1;
	}
}