func (self *SurfacePoint) Emission(toPosition Vector3f, outDirection Vector3f, isSolidAngle bool) Vector3f { ray := toPosition.Sub(self.Position) normal := self.Tri.Normal() distance2 := ray.Dot(normal) cosOut := outDirection.Dot(normal) area := self.Tri.Area() /* emit front face of surface only */ var mulval1, mulval2 float32 mulval1 = math32.Bool2Float(cosOut > 0.0) if isSolidAngle { /* with infinity clamped-out */ var divval, powval float32 powval = math32.Pow10(-6) if distance2 >= powval { divval = distance2 } else { divval = powval } mulval2 = (cosOut * area) / divval } else { mulval2 = 1.0 } solidAngle := mulval1 * mulval2 return self.Tri.Emitivity.Mulf(solidAngle) }
func (self *SurfacePoint) Reflection(inDirection, inRadiance, outDirection Vector3f) Vector3f { normal := self.Tri.Normal() inDot := inDirection.Dot(normal) outDot := outDirection.Dot(normal) /* directions must be same side of surface (no transmission) */ isSameSide := !(math32.Xor(inDot < 0.0, outDot < 0.0)) /* ideal diffuse BRDF: radiance sacaled by reflectivity, cosine and 1/pi */ r := inRadiance.Mulv(self.Tri.Reflectivity) mulval1 := (math32.Abs(inDot) / math32.Pi) mulval2 := math32.Bool2Float(isSameSide) return r.Mulf(mulval1 * mulval2) }