diff --git a/components/renderers/cpp/src/triangle_render.cu b/components/renderers/cpp/src/triangle_render.cu
index 5887d8233a5f5333c0662bff570bd8a62caeb86b..e87a1009aa0589ce93f1ab70ebc3cb11acc25aef 100644
--- a/components/renderers/cpp/src/triangle_render.cu
+++ b/components/renderers/cpp/src/triangle_render.cu
@@ -11,6 +11,85 @@ using ftl::render::SplatParams;
 
 __device__ inline float length2(int dx, int dy) { return dx*dx + dy*dy; }
 
+__device__ inline float cross(const float2 &a, const float2 &b) {
+	return a.x*b.y - a.y*b.x;
+}
+
+__device__ inline bool within(float x) {
+    return 0.0f <= x <= 1.0f;
+}
+
+__device__ inline bool operator==(const float2 &a, const float2 &b) {
+	return a.x == b.x && a.y == b.y;
+}
+
+__device__ inline bool insideTriangle(const float2 &a, const float2 &b, const float2 &c, const float2 &p)
+{   
+    float det = (b.y - c.y)*(a.x - c.x) + (c.x - b.x)*(a.y - c.y);
+    float factor_alpha = (b.y - c.y)*(p.x - c.x) + (c.x - b.x)*(p.y - c.y);
+    float factor_beta = (c.y - a.y)*(p.x - c.x) + (a.x - c.x)*(p.y - c.y);
+    float alpha = factor_alpha / det;
+    float beta = factor_beta / det;
+    float gamma = 1.0 - alpha - beta;
+
+    return p == a || p == b || p == c || (within(alpha) && within(beta) && within(gamma));
+}
+
+__device__ inline void swap(short2 &a, short2 &b) {
+	short2 t = a;
+	a = b;
+	b = t;
+}
+
+__device__ void drawLine(TextureObject<int> &depth_out, int y, int x1, int x2, float d) {
+	for (int x=x1; x<=x2; ++x) {
+		if (x < 0) continue;
+		if (x >= depth_out.width()) return;
+		atomicMin(&depth_out(x,y), int(d*1000.0f));
+	}
+}
+
+/**
+ * Calculate the signed area of a given triangle.
+ */
+__device__ static inline
+ float calculateSignedArea(const short2 &a, const short2 &b, const short2 &c) {
+	 return 0.5f * (float(c.x - a.x) * float(b.y - a.y) - float(b.x - a.x) * float(c.y - a.y));
+ }
+
+// CHECKITOUT
+/**
+ * Helper function for calculating barycentric coordinates.
+ */
+ __device__ static inline
+ float calculateBarycentricCoordinateValue(const short2 &a, const short2 &b, const short2 &c, const short2 (&tri)[3]) {
+	 return calculateSignedArea(a,b,c) / calculateSignedArea(tri[0], tri[1], tri[2]);
+ }
+ 
+ // CHECKITOUT
+ /**
+  * Calculate barycentric coordinates.
+  * TODO: Update to handle triangles coming in and not the array
+  */
+__device__ static
+ float3 calculateBarycentricCoordinate(const short2 (&tri)[3], const short2 &point) {
+	 float beta = calculateBarycentricCoordinateValue(tri[0], point, tri[2], tri);
+	 float gamma = calculateBarycentricCoordinateValue(tri[0], tri[1], point, tri);
+	 float alpha = 1.0 - beta - gamma;
+	 return make_float3(alpha, beta, gamma);
+ }
+ 
+ // CHECKITOUT
+ /**
+  * Check if a barycentric coordinate is within the boundaries of a triangle.
+  */
+ __host__ __device__ static
+ bool isBarycentricCoordInBounds(const float3 &barycentricCoord) {
+	 return barycentricCoord.x >= 0.0 && barycentricCoord.x <= 1.0 &&
+			barycentricCoord.y >= 0.0 && barycentricCoord.y <= 1.0 &&
+			barycentricCoord.z >= 0.0 && barycentricCoord.z <= 1.0;
+ }
+
 /*
  * Convert source screen position to output screen coordinates.
  */
@@ -30,15 +109,63 @@ __device__ inline float length2(int dx, int dy) { return dx*dx + dy*dy; }
     d[2] = depth_in.tex2D(x+A,y+(1-B));
 
     // Is this triangle valid
-	if (fabs(d[0] - d[1]) > 0.04f || fabs(d[0] - d[2]) > 0.04f) return;
+	if (fabs(d[0] - d[1]) > 0.04f || fabs(d[0] - d[2]) > 0.04f || fabs(d[1] - d[2]) > 0.04f) return;
 	if (d[0] < params.camera.minDepth || d[0] > params.camera.maxDepth) return;
 
-    short2 s[3];
-    s[0] = screen.tex2D(x+A,y+B);
-    s[1] = screen.tex2D(x+(1-A),y+B);
-	s[2] = screen.tex2D(x+A,y+(1-B));
+    short2 v[3];
+    v[0] = screen.tex2D(x+A,y+B);
+    v[1] = screen.tex2D(x+(1-A),y+B);
+	v[2] = screen.tex2D(x+A,y+(1-B));
+
+	const int minX = min(v[0].x, min(v[1].x, v[2].x));
+	const int minY = min(v[0].y, min(v[1].y, v[2].y));
+	const int maxX = max(v[0].x, max(v[1].x, v[2].x));
+	const int maxY = max(v[0].y, max(v[1].y, v[2].y));
+
+	//if ((maxX - minX) * (maxY - minY) > 200) return;
+	int incx = ((maxX - minX) / 20) + 1;
+	int incy = ((maxY - minY) / 20) + 1;
+
+	float2 vs0 = make_float2(v[0].x, v[0].y);
+	float2 vs1 = make_float2(v[1].x, v[1].y);
+	float2 vs2 = make_float2(v[2].x, v[2].y);
+
+	for (int sy=minY; sy <= maxY; sy+=incy) {
+		for (int sx=minX; sx <= maxX; sx+=incx) {
+			if (sx >= params.camera.width || sx < 0 || sy >= params.camera.height || sy < 0) continue;
+			//float2 q = make_float2(sx, sy);
+			//float s = det(q - vs0, vs1) / det(vs0, vs1); //cross(q, vs2) / cross(vs1, vs2);
+			//float t = det(vs0, q - vs1) / det(vs0, vs1); //cross(vs1, q) / cross(vs1, vs2);
+
+			float3 baryCentricCoordinate = calculateBarycentricCoordinate(v, make_short2(sx, sy));
+
+			if (isBarycentricCoordInBounds(baryCentricCoordinate)) {
+			//if (s >= 0 && t >= 0 && ss+t <= 1) {
+			//if (insideTriangle(vs0,vs1,vs2, make_float2(sx,sy))) {
+				/*float dist1 = length2(sx - s[0].x, sy - s[0].y);
+				float dist2 = length2(sx - s[1].x, sy - s[1].y);
+				float dist3 = length2(sx - s[2].x, sy - s[2].y);
+
+				float maxlen = max(dist1, max(dist2, dist3));
+				if (maxlen > 0.0f) {
+				dist1 = 1.0f - dist1 / maxlen;
+				dist2 = 1.0f - dist2 / maxlen;
+				dist3 = 1.0f - dist3 / maxlen;
+				}
+				float new_depth = (maxlen == 0.0f) ? d[0] : (d[0]*dist1 + d[1]*dist2 + d[2]*dist3) / (dist1+dist2+dist3);
+				//if (new_depth < params.camera.minDepth || new_depth > params.camera.maxDepth) continue;*/
+
+				float new_depth = d[0];
+
+				atomicMin(&depth_out(sx,sy), int(new_depth*1000.0f));
+			}
+		}
+	}
+
+
+	// OLD
 	
-	const int dx = (A) ? -1 : 1;
+	/*const int dx = (A) ? -1 : 1;
 	const int dy = (B) ? -1 : 1;
 
     s[1].x = (A) ? s[0].x - s[1].x : s[1].x - s[0].x;
@@ -65,7 +192,7 @@ __device__ inline float length2(int dx, int dy) { return dx*dx + dy*dy; }
 
             atomicMin(&depth_out(dx*sx+s[0].x,dy*sy+s[0].y), int(new_depth*1000.0f));
         }
-    }
+    }*/
 }
 
 void ftl::cuda::triangle_render1(TextureObject<float> &depth_in, TextureObject<int> &depth_out, TextureObject<short2> &screen, const SplatParams &params, cudaStream_t stream) {