Hi!

I’m Sandy, a senior backend engineer turned graphics programmer. I’m interested in game engine development, real-time rendering and functional programming.

Get in touch!

If you're looking for an engine developer or graphics programmer, I'd love to hear from you! You can reach me at jysandilya@gmail.com.


Things I've built

Gradient

View on Github

Gradient is a game engine written in C++ and DirectX 12. It uses forward rendering with a Z-prepass. The scene has 9.7 million leaves which are individually instanced, culled and animated on the GPU using a mesh shader. Some other major features are physics simulation and a first-person character controller using Jolt, frustum culling, PBR materials, HDR rendering, water and procedurally generated foliage.

Here's a more exhaustive list of features and references:

  • Mesh shaders are used to render the 9.7 million leaves in the scene. The mesh shader also performs frustum culling on the GPU, in all passes. Details and performance discussion here.
  • A basic scene tree and entity system built on entt. entt is used to group physics bodies, meshes, transforms, materials, instance data and more.
  • PBR direct lighting and materials based on UE4's roughness-metallic workflow.
    • Image-based lighting using a BRDF LUT is currently not implemented. Since I was short on time, I used a cheap approximation instead. To compute indirect lighting, the reflected view vector is used to sample the sky dome. A flat ambient term is added to this value and the result is fed to the BRDF. This step is repeated by sampling the sky dome using the surface normal and the two results are combined. Refer to the source here for details.
  • GTAO (without bent normals) using XeGTAO.
  • Physics simulation and first-person movement using the Jolt physics engine.
  • Water simulation using hardware tesselation. Refer to this blog post for details.
  • Procedurally generated foliage using L-systems. Details are in this blog post.
  • Coarse frustum culling on the CPU. This is done for all passes, including the shadow pass. Details here. The culling frustum can be frozen in place to observe the effects.
  • Shadow mapping with large kernel PCF. The shadow frustum is fit around the camera frustum for culling and to make efficient use of the shadow map texels.
  • Point lights with shadows. Culling is in place when drawing point light shadows as well.
  • Normal mapping without precomputed tangents, as explained by Christian Schüler here.
  • A translucency-based subsurface scattering approximation, explained by Alan Zucconi here. This is in turn based on EA's presentation here. I used this for both the water and the leaves.

Interval Shaded Volumetrics

View on Github

This is a novel volumetric rendering technique that doesn't use ray-marching, voxels or temporal blending. The volumetric particles are represented by tetrahedrons which are converted to triangle proxies using a mesh shader. This project forms my master's dissertation, and is still under active development.

  • This method builds on the work of Thibault Tricard's Interval Shading to draw volumetric particles as tetrahedrons that are composed of participating media.
  • Interval Shading uses mesh shaders to splat tetrahedrons to the screen as triangle proxies. Vertex attributes are set in such a way that after rasterization, the pixel shader receives two depths: one for the front face of the tetrahedron and one for the back. This depth interval can then be used for shading.
  • Since the medium is represented by a rasterized particle system instead of a density field or voxels, it is easy to animate and can be used for interactive simulations, as demonstrated in the video.
  • Radiance is integrated analytically for a single tetrahedron using the depth interval provided by interval shading. The tetrahedrons are sorted and drawn furthest-to-nearest and blending is used to integrate radiance across all particles.
  • Self shadowing is achieved by first rendering optical depth into a light-space 3D texture similar to conventional shadow maps. To determine the radiance arriving at any point along a depth interval, this 3D texture is sampled at both interval boundaries and linearly interpolated.
  • Some of the planned future work includes:
    • Making the tetrahedron edges less visible.
    • Shadowing of the medium by opaque objects.
    • Casting volumetric shadows onto opaque objects.
    • Performance optimizations:
      • Draw to a lower resolution to reduce pixel shader cost, then upscale and composite.
      • Frustum culling when drawing the volumetric shadow map.
      • Early-Z culling does not work with this method. Therefore, occlusion culling has to be performed in the mesh shader.

sandtrace

View on Github

sandtrace is a non-real-time Whitted ray-tracer written in C++. I worked on it during my undergrad in 2014.

CitruSpire: Quest For the Sacred Fruit

View on Github Download on itch.io

CitruSpire: Quest for the Sacred Fruit is a short 2.5D action platformer game made in Unreal Engine 5.4. I worked with a team of second year undergraduate students to build this as a part of my master's programme at Abertay University. I was responsible for programming most of the core systems of the game, including character movement and animations, a camera pivoting mechanic, parallax 2D backgrounds, the save and checkpoint system and enemy AI, to name a few. I was also responsible for production of the project.


Experiences I've had

I've worked professionally as a software engineer for around 7 years. Almost all of that time was spent at nilenso, an employee-owned software consultancy. I worked with clients to build complex and scalable backend services. I also played the role of a hiring manager at nilenso and have mentored and trained junior engineers.

I helped clients and teams build better products, both by delivering software to a high standard myself and by coaching and advising teams that I worked with. These are some of the clients whom I've worked with:

Gojek is an on-demand decacorn in Southeast Asia. I worked on multiple mission-critical systems, including their ride-hailing platform, the A/B testing system, a payment processing system and many others.

  • I built a fault-tolerant payment processing system for the ride-hailing product, in a team of 3 engineers. The system was designed to be eventually consistent. It automatically retried failed payments, and had controls for manual intervention as a fallback or in the event of a serious outage.
  • As a part of the on-call rotation, I responded to and debugged production outages and customer support tickets. I wrote root-cause analyses for any outages that occured while I was on call.
  • I built a configurable, rule-based traffic segmentation system for the company’s main A/B testing platform.
    • Traffic was routed into one of two variants: the treatment group or control group. Each group could be assigned a percentage of traffic.
    • Changing the traffic percentage assignment later results in a minimal number of customers moving from one variant to another, so as to retain stickiness of sessions and minimise disruption.
    • Product managers and developers could also route customers using a set of rules. More details in this blog post by my colleague here.
  • I trained and mentored a team of 6 developers in the Clojure programming language, and worked with them to build and ship a new microservice written in Clojure.
    • I conducted structured classes and workshops for the first couple of weeks.
    • After that, I pair programmed with the other engineers in the team to further develop their comfort with the language.
    • I also contributed to the design and architecture of the system itself.
  • I maintained multiple large databases (>900 GB in size, >25k writes per minute) and tuned them for performance and throughput.
    • I set up telemetry queries to monitor the health of the ride-hailing database, and these were eventually put to use in databases across the company.
    • I archived large volumes of data (~700-800 GB) with zero downtime.
  • I mentored junior developers and coached them on good software architecture, iterative development and other aspects of professional software development.

Consolidate Health is a healthcare data app for American patients. As one of their first 3 engineers, I designed their patient data platform and built the product from the ground up.

  • I designed and built the patient data ingestion system which was central to the product. This system fetched, aggregated and normalized patient data from a variety of configurable sources.
  • I set up the system's infrastructure in AWS, and built the CI/CD pipelines needed to deploy it.

Staples Sparx was an arm of Staples that used machine learning to suggest content on Staples’ e-commerce website. I built a web-based frontend for their internal A/B testing system.


Tech I've used

  • C++
  • DirectX 12
  • Unreal Engine
  • Clojure
  • C#
  • Ruby
  • Go
  • JavaScript
  • Haskell
  • Postgres
  • Google Cloud
  • AWS
  • Kubernetes

Odds and ends

IN/Clojure is India's annual Clojure and ClojureScript conference. I've helped organise it in 2018, 2019 and 2020. I ran the beginner's Clojure workshop every year and helped develop the curriculum for it.

I recorded some screencasts on the nilenso YouTube channel addressing some fundamental Clojure topics that I felt weren't covered well in existing Clojure material.