[mtl canvas] Fix artifacts on tiger that was due to epsilon comparison for cubics equation in draw kernel. Removed that (now do <= 0), but then we need to weed out false negatives for solid triangles. So we compute if the triangle is solid in the triangle kernel and store it in the mg_triangle_data struct for now.
This commit is contained in:
		
							parent
							
								
									b0be21795e
								
							
						
					
					
						commit
						e9ecd9d521
					
				| 
						 | 
				
			
			@ -65,7 +65,7 @@ int main()
 | 
			
		|||
 | 
			
		||||
	//NOTE: create surface
 | 
			
		||||
	mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_DEFAULT);
 | 
			
		||||
	mg_surface_swap_interval(surface, 0);
 | 
			
		||||
	mg_surface_swap_interval(surface, 1);
 | 
			
		||||
 | 
			
		||||
	//TODO: create canvas
 | 
			
		||||
	mg_canvas canvas = mg_canvas_create(surface);
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ int main()
 | 
			
		|||
	bool tracked = false;
 | 
			
		||||
	vec2 trackPoint = {0};
 | 
			
		||||
	f32 zoom = 1;
 | 
			
		||||
	f32 startX = 0, startY = 0;
 | 
			
		||||
	f32 startX = 300, startY = 200;
 | 
			
		||||
 | 
			
		||||
	f64 frameTime = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -112,8 +112,8 @@ int main()
 | 
			
		|||
						{
 | 
			
		||||
							tracked = true;
 | 
			
		||||
							vec2 mousePos = mp_mouse_position();
 | 
			
		||||
							trackPoint.x = mousePos.x/zoom - startX;
 | 
			
		||||
							trackPoint.y = mousePos.y/zoom - startY;
 | 
			
		||||
							trackPoint.x = (mousePos.x - startX)/zoom;
 | 
			
		||||
							trackPoint.y = (mousePos.y - startY)/zoom;
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
| 
						 | 
				
			
			@ -125,14 +125,14 @@ int main()
 | 
			
		|||
				case MP_EVENT_MOUSE_WHEEL:
 | 
			
		||||
				{
 | 
			
		||||
					vec2 mousePos = mp_mouse_position();
 | 
			
		||||
					f32 trackX = mousePos.x/zoom - startX;
 | 
			
		||||
					f32 trackY = mousePos.y/zoom - startY;
 | 
			
		||||
					f32 pinX = (mousePos.x - startX)/zoom;
 | 
			
		||||
					f32 pinY = (mousePos.y - startY)/zoom;
 | 
			
		||||
 | 
			
		||||
					zoom *= 1 + event.move.deltaY * 0.01;
 | 
			
		||||
					zoom = Clamp(zoom, 0.2, 10);
 | 
			
		||||
					zoom = Clamp(zoom, 0.5, 5);
 | 
			
		||||
 | 
			
		||||
					startX = mousePos.x/zoom - trackX;
 | 
			
		||||
					startY = mousePos.y/zoom - trackY;
 | 
			
		||||
					startX = mousePos.x - pinX*zoom;
 | 
			
		||||
					startY = mousePos.y - pinY*zoom;
 | 
			
		||||
				} break;
 | 
			
		||||
 | 
			
		||||
				default:
 | 
			
		||||
| 
						 | 
				
			
			@ -143,8 +143,8 @@ int main()
 | 
			
		|||
		if(tracked)
 | 
			
		||||
		{
 | 
			
		||||
			vec2 mousePos = mp_mouse_position();
 | 
			
		||||
			startX = mousePos.x/zoom - trackPoint.x;
 | 
			
		||||
			startY = mousePos.y/zoom - trackPoint.y;
 | 
			
		||||
			startX = mousePos.x - trackPoint.x*zoom;
 | 
			
		||||
			startY = mousePos.y - trackPoint.y*zoom;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		mg_surface_prepare(surface);
 | 
			
		||||
| 
						 | 
				
			
			@ -152,8 +152,8 @@ int main()
 | 
			
		|||
		mg_set_color_rgba(1, 0, 1, 1);
 | 
			
		||||
		mg_clear();
 | 
			
		||||
 | 
			
		||||
		mg_matrix_push((mg_mat2x3){zoom, 0, 300+startX*zoom,
 | 
			
		||||
		                           0, zoom, 200+startY*zoom});
 | 
			
		||||
		mg_matrix_push((mg_mat2x3){zoom, 0, startX,
 | 
			
		||||
		                           0, zoom, startY});
 | 
			
		||||
 | 
			
		||||
		draw_tiger();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,10 +208,13 @@ for g in tree.iter('{http://www.w3.org/2000/svg}g'):
 | 
			
		|||
			print("\tmg_set_color_rgba(" + f2s(r) + ", " + f2s(g) + ", " + f2s(b) + ", 1);")
 | 
			
		||||
			print("\tmg_fill();")
 | 
			
		||||
 | 
			
		||||
		if stroke_width != None:
 | 
			
		||||
			print("\tmg_set_width(" + stroke_width + ");");
 | 
			
		||||
 | 
			
		||||
		if stroke != None and stroke != "none":
 | 
			
		||||
 | 
			
		||||
			if stroke_width != None:
 | 
			
		||||
				print("\tmg_set_width(" + stroke_width + ");");
 | 
			
		||||
			else:
 | 
			
		||||
				print("\tmg_set_width(1);");
 | 
			
		||||
 | 
			
		||||
			(r, g, b) = parse_color(stroke)
 | 
			
		||||
			if fill != None:
 | 
			
		||||
				ctx.reset()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -284,6 +284,7 @@ void draw_tiger()
 | 
			
		|||
	mg_close_path();
 | 
			
		||||
	mg_set_color_rgba(1.000, 1.000, 1.000, 1);
 | 
			
		||||
	mg_fill();
 | 
			
		||||
	mg_set_width(1);
 | 
			
		||||
	mg_move_to(-129.830, 103.060);
 | 
			
		||||
	mg_cubic_to(-129.330, 109.110, -128.340, 115.680, -126.600, 118.800);
 | 
			
		||||
	mg_cubic_to(-126.600, 118.800, -130.200, 131.200, -121.400, 144.400);
 | 
			
		||||
| 
						 | 
				
			
			@ -422,6 +423,7 @@ void draw_tiger()
 | 
			
		|||
	mg_close_path();
 | 
			
		||||
	mg_set_color_rgba(0.800, 0.447, 0.149, 1);
 | 
			
		||||
	mg_fill();
 | 
			
		||||
	mg_set_width(1);
 | 
			
		||||
	mg_move_to(299.720, 80.245);
 | 
			
		||||
	mg_cubic_to(300.340, 80.426, 302.550, 81.550, 303.800, 83.200);
 | 
			
		||||
	mg_cubic_to(303.800, 83.200, 310.600, 94.000, 305.400, 75.600);
 | 
			
		||||
| 
						 | 
				
			
			@ -909,6 +911,7 @@ void draw_tiger()
 | 
			
		|||
	mg_close_path();
 | 
			
		||||
	mg_set_color_rgba(1.000, 0.447, 0.498, 1);
 | 
			
		||||
	mg_fill();
 | 
			
		||||
	mg_set_width(1);
 | 
			
		||||
	mg_move_to(-9.800, 174.400);
 | 
			
		||||
	mg_cubic_to(-9.800, 174.400, -12.600, 196.800, -9.400, 205.200);
 | 
			
		||||
	mg_cubic_to(-6.200, 213.600, -7.000, 215.600, -7.800, 219.600);
 | 
			
		||||
| 
						 | 
				
			
			@ -3879,21 +3882,25 @@ void draw_tiger()
 | 
			
		|||
 | 
			
		||||
	mg_move_to(-89.250, 169.000);
 | 
			
		||||
	mg_move_to(-67.250, 173.750);
 | 
			
		||||
	mg_set_width(1);
 | 
			
		||||
	mg_set_color_rgba(0.000, 0.000, 0.000, 1);
 | 
			
		||||
	mg_stroke();
 | 
			
		||||
 | 
			
		||||
	mg_move_to(-39.000, 331.000);
 | 
			
		||||
	mg_cubic_to(-39.000, 331.000, -39.500, 327.500, -48.500, 338.000);
 | 
			
		||||
	mg_set_width(1);
 | 
			
		||||
	mg_set_color_rgba(0.000, 0.000, 0.000, 1);
 | 
			
		||||
	mg_stroke();
 | 
			
		||||
 | 
			
		||||
	mg_move_to(-33.500, 336.000);
 | 
			
		||||
	mg_cubic_to(-33.500, 336.000, -31.500, 329.500, -38.000, 334.000);
 | 
			
		||||
	mg_set_width(1);
 | 
			
		||||
	mg_set_color_rgba(0.000, 0.000, 0.000, 1);
 | 
			
		||||
	mg_stroke();
 | 
			
		||||
 | 
			
		||||
	mg_move_to(20.500, 344.500);
 | 
			
		||||
	mg_cubic_to(20.500, 344.500, 22.000, 333.500, 10.500, 346.500);
 | 
			
		||||
	mg_set_width(1);
 | 
			
		||||
	mg_set_color_rgba(0.000, 0.000, 0.000, 1);
 | 
			
		||||
	mg_stroke();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@
 | 
			
		|||
 | 
			
		||||
#define RENDERER_TILE_SIZE 16
 | 
			
		||||
#define RENDERER_MAX_TILES 65536
 | 
			
		||||
#define RENDERER_TILE_BUFFER_COUNT 4*(1<<10)
 | 
			
		||||
#define RENDERER_TILE_BUFFER_COUNT 8*(1<<10)
 | 
			
		||||
 | 
			
		||||
#define RENDERER_DEBUG_TILE_VISITED 0xf00d
 | 
			
		||||
#define RENDERER_DEBUG_TILE_BUFFER_OVERFLOW 0xdead
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +38,7 @@ typedef struct mg_triangle_data
 | 
			
		|||
	matrix_float3x3 uvTransform;
 | 
			
		||||
	vector_float4 color;
 | 
			
		||||
 | 
			
		||||
	bool full;
 | 
			
		||||
	vector_float4 cubic0;
 | 
			
		||||
	vector_float4 cubic1;
 | 
			
		||||
	vector_float4 cubic2;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -158,6 +158,12 @@ kernel void TriangleKernel(constant mg_vertex* vertexBuffer [[buffer(0)]],
 | 
			
		|||
	triangleArray[gid].bias1 = is_top_left(p2, p0) ? -(1-cw)/2 : -(1+cw)/2;
 | 
			
		||||
	triangleArray[gid].bias2 = is_top_left(p0, p1) ? -(1-cw)/2 : -(1+cw)/2;
 | 
			
		||||
 | 
			
		||||
	bool triangleFull = all(  triangleArray[gid].cubic0 == float4(1, 1, 1, 1)
 | 
			
		||||
	                       && triangleArray[gid].cubic1 == float4(1, 1, 1, 1)
 | 
			
		||||
	                       && triangleArray[gid].cubic2 == float4(1, 1, 1, 1));
 | 
			
		||||
 | 
			
		||||
	triangleArray[gid].full = triangleFull;
 | 
			
		||||
 | 
			
		||||
	int4 coarseBox = int4(fbox)/RENDERER_TILE_SIZE;
 | 
			
		||||
 | 
			
		||||
	//NOTE: bucket triangle into tiles
 | 
			
		||||
| 
						 | 
				
			
			@ -172,10 +178,6 @@ kernel void TriangleKernel(constant mg_vertex* vertexBuffer [[buffer(0)]],
 | 
			
		|||
	//NOTE(martin): it's important to do the computation with signed int, so that we can have negative xMax/yMax
 | 
			
		||||
	//              otherwise all triangles on the left or below the x/y axis are attributed to tiles on row/column 0.
 | 
			
		||||
 | 
			
		||||
	bool triangleFull = all(  triangleArray[gid].cubic0 == float4(1, 1, 1, 1)
 | 
			
		||||
	                       && triangleArray[gid].cubic1 == float4(1, 1, 1, 1)
 | 
			
		||||
	                       && triangleArray[gid].cubic2 == float4(1, 1, 1, 1));
 | 
			
		||||
 | 
			
		||||
	int2 edges[3][2] = {{ip0, ip1}, {ip1, ip2}, {ip2, ip0}};
 | 
			
		||||
 | 
			
		||||
	for(int y = yMin; y <= yMax; y++)
 | 
			
		||||
| 
						 | 
				
			
			@ -450,6 +452,8 @@ kernel void RenderKernel(const device uint* tileCounters [[buffer(0)]],
 | 
			
		|||
			float4 cubic1 = triangle->cubic1;
 | 
			
		||||
			float4 cubic2 = triangle->cubic2;
 | 
			
		||||
 | 
			
		||||
			bool fullTriangle = triangle->full;
 | 
			
		||||
 | 
			
		||||
			int shapeIndex = triangle->shapeIndex;
 | 
			
		||||
			float4 color = triangle->color;
 | 
			
		||||
			color.rgb *= color.a;
 | 
			
		||||
| 
						 | 
				
			
			@ -478,8 +482,8 @@ kernel void RenderKernel(const device uint* tileCounters [[buffer(0)]],
 | 
			
		|||
				{
 | 
			
		||||
					float4 cubic = (cubic0*w0 + cubic1*w1 + cubic2*w2)/(w0+w1+w2);
 | 
			
		||||
 | 
			
		||||
					float eps = 0.0001;
 | 
			
		||||
					if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps)
 | 
			
		||||
					if( fullTriangle
 | 
			
		||||
					  ||(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= 0))
 | 
			
		||||
					{
 | 
			
		||||
						if(shapeIndex == currentShapeIndex[sampleIndex])
 | 
			
		||||
						{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue