← Projects

Project

TeneaX

TeneaX is an inverse optical design engine. Classical lens design is a forward, trial and error loop: you shape a surface, trace the light, look at the result, and adjust. TeneaX aims to invert that. You specify the illuminance pattern you want on a target plane, and the engine solves for the lens that produces it, automatically, by gradient based optimization. Formally it minimizes the mismatch between the achieved and the target distribution, minc L(c)=I(c)Itarget2,\min_{c}\ \mathcal{L}(c) = \lVert I(c) - I_{\text{target}} \rVert^2, where cc are the control points of a freeform lens and I(c)I(c) is the illuminance from tracing thousands of rays through it.

Live demo →

Ray Tracing

At the heart of TeneaX is a physically based ray tracer. Thousands of rays are emitted from the source, refracted through the freeform lens, and accumulated on a detector to form the illuminance image that the optimizer scores. The physics is standard: each ray refracts by the vectorial Snell's law t=ηd+(ηcosθicosθt)n\mathbf{t} = \eta\,\mathbf{d} + (\eta\cos\theta_i - \cos\theta_t)\,\mathbf{n} with η=n1/n2\eta = n_1/n_2 and cosθt=1η2(1cos2θi)\cos\theta_t = \sqrt{1 - \eta^2(1-\cos^2\theta_i)}. Getting this forward model right, and numerically robust through total internal reflection and grazing incidence, is what makes the whole inverse design loop trustworthy.

Ray Tracing

NURBS Surfaces

The lens surface has to be smooth, freeform, and controllable with a manageable number of parameters, which is exactly what a NURBS surface gives you. It is a weighted combination of B-spline basis functions over a grid of control points, S(u,v)=ijNi,p(u)Nj,q(v)wijPijijNi,p(u)Nj,q(v)wij,S(u,v) = \frac{\sum_i \sum_j N_{i,p}(u)\,N_{j,q}(v)\,w_{ij}\,\mathbf{P}_{ij}}{\sum_i \sum_j N_{i,p}(u)\,N_{j,q}(v)\,w_{ij}}, where the control points Pij\mathbf{P}_{ij} are the design variables the optimizer moves and everything else stays fixed. A modest 15×1515\times15 grid already spans a rich space of freeform shapes while keeping the problem well conditioned. Tracing a ray against such a surface has no closed form, so every intersection is found by Newton-Raphson iteration, solving S(u,v)=o+tdS(u,v) = \mathbf{o} + t\,\mathbf{d} for (u,v,t)(u,v,t).

Watch on YouTube
NURBS Surfaces

Resulting Surface

With the forward model and a NURBS parametrization in place, the inverse problem becomes a least squares fit, and the classic optical design optimizer applies: Levenberg-Marquardt. Writing the merit as residuals r(c)=I(c)Itargetr(c) = I(c) - I_{\text{target}}, each step solves (JJ+λI)δ=Jr,J=rc,(J^{\top}J + \lambda I)\,\delta = -\,J^{\top} r, \qquad J = \frac{\partial r}{\partial c}, and moves the control points by δ\delta. The damping λ\lambda interpolates between Gauss-Newton (fast, λ0\lambda \to 0) and gradient descent (safe, λ\lambda \to \infty): a step is accepted only if it lowers the cost, otherwise λ\lambda is raised and the step retried. That single rule also makes the solver robust to the numerical pathologies of ray tracing, such as total internal reflection and grazing hits, that would otherwise poison the optimization. The goal is a freeform lens, expressed in real photometric units (Lux), that reshapes the source into the specified target pattern.

Resulting Surface