Normals, culling, lighting
A Coracle implementation of the Code-It-Yourself! 3D Graphics Engine Part #2 tutorial
import coracle.*
import coracle.shapes.Mesh
import coracle.shapes.Point
/*
Code-It-Yourself! 3D Graphics Engine Part #2 - Normals, Culling, Lighting
Adapted from: https://github.com/OneLoneCoder/videos/blob/master/OneLoneCoder_olcEngine3D_Part2.cpp
See: https://youtu.be/xgmwc6lumg4
*/
class NormalsCullingLighting: Drawing() {
var cube: Mesh
lateinit
var projectionMatrix = Matrix.projectionMatrix(450f / 450f, 90.0f, 0.1f, 1000.0f)
var matRotZ = Matrix()
var matRotX = Matrix()
val camera = Point()//Camera is at 0,0,0
val light = Point(0.0f, 0.0f, -1.0f)
var frame = 0
override fun setup() {
(450, 450)
size
= Mesh.cube()
cube
.normalise()
light}
override fun draw() {
(0x1d1d1d)
background++
frame
val f = frame / 20.0f
.rotateZ(f)
matRotZ.rotateX(f * 0.5f)
matRotX
.triangles.forEach { triangle ->
cubeval rotatedTriangle = triangle * matRotZ
*= matRotX
rotatedTriangle .applyZOffset(3f)
rotatedTriangle
val normal = rotatedTriangle.normal()
if(normal.x * (rotatedTriangle.a.x - camera.x) + normal.y * (rotatedTriangle.a.y - camera.y) + normal.z * (rotatedTriangle.a.z - camera.z) < 0.0f) {
// Illumination
val dp = normal.x * light.x + normal.y * light.y + normal.z * light.z
val colourVal = dp * 255f
(Colour.grey(colourVal.toInt()))
fill()
noStroke
val tri2D = rotatedTriangle.to2D(projectionMatrix)
.scale(width/2f)
tri2D.translate(width/2f, height/2f)
tri2D.draw()
tri2D}
}
}
}