diff --git a/RayTracer/shape/Triangle.cpp b/RayTracer/shape/Triangle.cpp
index 9aa2e942bd29e42c5873d97173477a772bff170a..510efa03e3e9af2a690f5739f58c1a9b3a2df173 100644
--- a/RayTracer/shape/Triangle.cpp
+++ b/RayTracer/shape/Triangle.cpp
@@ -2,32 +2,17 @@
 
 #include "Triangle.h"
 
+#include "../tools/Random.h"
+#include "math.h"
+
 namespace shapes {
 Triangle::Triangle(util::Vertex p1, util::Vertex p2, util::Vertex p3,
                    const std::shared_ptr<material::Material>& material)
     : p1(p1), p2(p2), p3(p3), material(material) {
 	recalculateBB();
 }
-
-util::AxisAlignedBoundingBox Triangle::bounds() const {
-	return bb;
-}
-void Triangle::recalculateBB() {
-	const util::Vec3 xx = p1.position;
-	const util::Vec3 yy = p2.position;
-	const util::Vec3 zz = p3.position;
-	const util::Vec3 minBound =
-	    util::Vec3(std::min<float>({xx.x(), yy.x(), zz.x()}),
-	               std::min<float>({xx.y(), yy.y(), zz.y()}),
-	               std::min<float>({xx.z(), yy.z(), zz.z()}));
-	const util::Vec3 maxBound =
-	    util::Vec3(std::max<float>({xx.x(), yy.x(), zz.x()}),
-	               std::max<float>({xx.y(), yy.y(), zz.y()}),
-	               std::max<float>({xx.z(), yy.z(), zz.z()}));
-	bb = util::AxisAlignedBoundingBox(minBound, maxBound);
-}
-
 std::optional<cam::Hit> Triangle::intersect(const cam::Ray& r) const {
+	// std::cout << "In tri intersect" << std::endl;
 	util::Vec3 e1 = p2.position - p1.position;
 	util::Vec3 e2 = p3.position - p1.position;
 	util::Vec3 pvec = util::cross(r.d, e2);
@@ -62,4 +47,48 @@ std::optional<cam::Hit> Triangle::intersect(const cam::Ray& r) const {
 	//	std::cout << "Hm" << std::endl;
 	return std::optional<cam::Hit>(cam::Hit(hit, cross_normal, t, material));
 }
+
+util::AxisAlignedBoundingBox Triangle::bounds() const {
+	// std::cout << "In tri bounds" << std::endl;
+	return bb;
+}
+// TODO
+util::SurfacePoint Triangle::sampleLight() const {
+	// X coord of the sampled point.
+	float x = util::disMinus1To1(util::gen) * 1 / 2;
+	// Z coord of the sampled point.
+	float z = util::disMinus1To1(util::gen) * 1 / 2;
+	return util::SurfacePoint(util::Vec3(x, 0, z), util::Vec3(0, 1, 0),
+	                          material);
+	// The sampled point will be in local coordinates.
+}
+// TODO
+util::Vec3 Triangle::calculateLightEmission(const util::SurfacePoint& p,
+                                            const util::Vec3& d) const {
+	// Basically this is just the emission at a surface point. And the pdf dimms
+	// the light in regard to the angle.
+	// Uniform pdf of shape is 1/area, converting to pdf over solid angle is
+	// pdf/(dot/length^2).
+	auto emission = p.emission();
+	auto dot = std::max<float>(util::dot(p.normal(), d.normalize()), 0);
+	auto area = 1;
+	auto pdf = std::pow(d.length(), 2) / (dot * area);
+	return emission / pdf;
+}
+
+void Triangle::recalculateBB() {
+	const util::Vec3 xx = p1.position;
+	const util::Vec3 yy = p2.position;
+	const util::Vec3 zz = p3.position;
+	const util::Vec3 minBound =
+	    util::Vec3(std::min<float>({xx.x(), yy.x(), zz.x()}),
+	               std::min<float>({xx.y(), yy.y(), zz.y()}),
+	               std::min<float>({xx.z(), yy.z(), zz.z()}));
+	const util::Vec3 maxBound =
+	    util::Vec3(std::max<float>({xx.x(), yy.x(), zz.x()}),
+	               std::max<float>({xx.y(), yy.y(), zz.y()}),
+	               std::max<float>({xx.z(), yy.z(), zz.z()}));
+	bb = util::AxisAlignedBoundingBox(minBound, maxBound);
+}
+
 }  // namespace shapes
diff --git a/RayTracer/shape/Triangle.h b/RayTracer/shape/Triangle.h
index 03d5e98e469e1ef2fa9f1d65c9111af62bca4324..64da4aaa1ac8560a44373b9929c9f105fd98a8c1 100644
--- a/RayTracer/shape/Triangle.h
+++ b/RayTracer/shape/Triangle.h
@@ -6,9 +6,11 @@
 #include "../camera/Hit.h"
 #include "../tools/AxisAlignedBoundingBox.h"
 #include "../tools/Vertex.h"
+#include "Light.h"
+#include "Shape.h"
 
 namespace shapes {
-class Triangle {
+class Triangle : public Light, public Shape {
    public:
 	Triangle(util::Vertex p1, util::Vertex p2, util::Vertex p3,
 	         const std::shared_ptr<material::Material>& material);