Calendar

September 2014
Mo Tu We Th Fr Sa Su
<< >>
1234567
891011121314
15161718192021
22232425262728
2930

Langs

Announcing HxSL

Posted on Feb 28 2011

Yesterday great news were published concerning the 3D on the web :

  • Adobe released their Flash Player 11 "Incubator" Public Beta, which includes a full low-level 3D API which is GPU-accelerated, see Adobe Labs

  • Unity announced in this blog post that they're working on a way to export to Flash (using the same lowlevel 3D API)

As you will see while reading the documentation or Thibault tutorial, most of the work in 3D is handled by shaders : they are short programs that get sent and run on the GPU, handling all the 3D transformations, but also Lighting, Texturing, and providing an infinite amount of custom effects.

In AS3, shaders are written in assembler and put into a string of your program, such as :

var shader : String =
    "dp4 op.x, va0, vc0    \n" +
    "dp4 op.y, va0, vc1    \n" +
    "dp4 op.z, va0, vc2    \n" +
    "dp4 op.w, va0, vc3    \n" +
    "mov v0, va1.xyzw      \n";

And you have to write a lot of boilerplate code to make sure that your vertex buffer works well with your shader. Adobe announced that they are working on PixelBender3D Toolkit, that will enable you to test and compile shaders, but this won't suppress the boilerplate code and you will still have to use a 3rd party tool to edit your shaders, which as a programmer I find annoying.

This is for this reason that I have developed a new shader language for Haxe, called HxSL (for Haxe Shader Language). You can directly embed HxSL code into your Haxe program, by using Haxe Metadata :

@:shader({
    var input : {
        pos : Float3,
    };
    var color : Float3;
    function vertex( mpos : M44, mproj : M44 ) {
        out = pos.xyzw * mpos * mproj;
        color = pos;
    }
    function fragment() {
        out = color.xyzw;
    }
}) class Shader extends format.hxsl.Shader {
}

When you compile your program, a Haxe macro will simply check the shader correctness and report you any syntax or logic error directly in your IDE as it would have done for another error. If success, it will generate a few methods that will generate all the boilerplate code for you.

In order to use this shader, you will simply have to do :

// initialize shader variables
shader.init(
    { mpos : mpos, mproj : project },
    {}
);
// initialize vertex buffer registers    
shader.bind(vbuf);
// you can then simply draw with your index buffer
context3D.drawTriangles(ibuf);

HxSL is a high level shader language so you don't have to write any assembler. You can also include constant values such as 1.56 or constant vectors such as [1,-1,0,0.5] - which is not possible to do using Flash11 assembler.

If you want to get started with Haxe/Flash11 now, simply follow the Tutorial on Haxe Website and read the HxSL Documentation.

Forgot to say : one nice thing with HxSL is that it can be compiled to other high-level shader languages such as GLSL for OpenGL/WebGL or HLSL for DirectX. Haxe being multiplatform itself, this opens a lot of possibilities for cross platform 3D development in the near future.

12 comments
  • Feb 28, 2011 at 18:39

    This looks great!

    Implementing shaders using Macros under the hood looks to be a much more elegant (and potentially less frustrating) approach than the Flash 11 API.

    You mentioned OpenGL and DirectX. Would this be compatible with OpenGL ES, or is that beyond its scope? (or maybe this is possible in OpenGL ES 2, but not 1.1?)

    Thanks for continuing to make a great platform greater.

  • Feb 28, 2011 at 18:44

    @Joshua, yes OpenGL ES 2.0 is needed for shaders, it is supported by iPhone 3GS+ iPad, and Android 2.2+

  • Keless
    Feb 28, 2011 at 19:09

    The mercury engine code I've been putting under haxe uses Open GL ES 2.0 and shaders-- this will be a nice utility for writing custom shaders over it!

  • Feb 28, 2011 at 21:36

    Having all these low level talents, why should we ever use a foregner(unity)'s IDE to create 3D games in flash?!

    We shall put the time we waste on earning money for creating ourselves a community made IDE.

  • Smily
    Feb 28, 2011 at 21:39

    I think it would be fair to mention that the "Flash11 assembler" that you mention is just an actionscript 3 class that converts the mentioned assembly into AGAL bytecode, so it's not really a feature of the language or the Flash API, but just a helper class that was made available so people can get started more easily without having to write the actual bytecode bytes manually.

    The inline HxSL looks interestingly wild though! :D

  • Feb 28, 2011 at 21:47

    Oh, that was quick :)

  • Craig Murray
    Mar 01, 2011 at 00:22

    Are any of the Molehill-enabled 3D engines written in HaXe? If so, that would be the obvious choice of engine if you want to use HXSL

  • Mattt
    Mar 01, 2011 at 12:24

    I wonder how many innocent designers who started flash just using a mouse (and frontpage or dreamwaver) will end up writing assembly code

  • Mar 01, 2011 at 17:29

    Awesome compiler!
    I went straight to compiling samples in molehill.zip, it seemed to need a few fix.
    :%s/ pos/ pos.xyzw/gc

  • pixnlove
    Mar 01, 2011 at 19:58

    Nicolas, you are amazing man!
    so gifted and clever.
    But how do you do that man...

    Thanks for this wonderful language which make everything possible.
    Long life to Haxe.

  • Mar 01, 2011 at 20:40

    @Kazuma : examples should have been fixed, this is a today change in HxSL

  • Dmitry
    Sep 10, 2012 at 21:11

    Is there a way to compile this example for CPP target in haxenme? I'm trying and getting:

    $ haxelib run nme build application.nmml windows
    Shader.hx:33: characters 1-35 : Class not found : flash.display3D.Context3D

Name : Email : Website : Message :