/haxe-threejs-template

three.js + haxe starter project

Primary LanguageHaxe

Haxe + three.js starter project

This is a batteries-included template project using three.js with the haxe language. Main.hx sets up a physically based rendering pipeline and some optimized HDR lighting environments are include in assets/env

See live

Screenshot 2022-01-10 at 15 43 34

Building and running

  • Download haxe 4.2
  • cd into this directory and install node modules with npm install
  • Start an live server with npm start
  • run haxe build.hxml to recompile the project into bin/

Editing

VSCode has great haxe IDE support with the haxe extension

I recommend installing the trigger task on save extension – this will trigger the project to recompile when you save haxe files, which is helpful for live editing

Project Overview

We can interact with three.js through externs generated from the typescript type definitions using the dts2hx tool. The generated externs are included in this repository in the .haxelib directory. To regenerate these files you can call npm run externs

three.js is included as a module by using require(), since browsers don't have require we use a bundler (esbuild) so we generate a single file – this is called by build.hxml. Alternatively we could have used three.js globally via a script tag if we generated the externs with --global

A haxe library, three-toolkit is included, which provides useful utilities for working with three.js and haxe, including

  • Post processing pipeline tools
  • A dat.gui extension: DevUI
  • CustomPhysicalMaterial for making pbr materials with custom shaders
  • Objects such as a soft mirror plane
  • Spring physics animation tooling

Why haxe not TypeScript?

Where TypeScript improves on JavaScript by adding types, haxe asks how could we build a better language from ECMAScript foundations, without maintaining the warts from js. On the surface syntactically it's similar to TS but differs in a few key ways:

  • metaprogrammig: you can mark functions for compile-time execution
  • there's only one way import code, simply import Module;
  • this only refers to the current type and does not change on context at runtime
  • it supports functional programming patterns inspired my meta languages like OCaml:
  • significantly faster compile-times
  • zero-cost abstraction types with abstracts

Have fun :D, feel free to open issues if you have questions