Creating shaders

Shaders are created by defining TypeScript classes. The class can receive parameters and should return an instance of a material. The class should inherit from a base class such as Shader or NodeShader and override a specific method in each.

Creating a shader class

Shaders can be written in either Typescript or GLSL.

Using Typescript

To write a shader with typescript, extend from NodeShader and override the output method.


import { rgb, standardMaterial } from "@hology/core/shader-nodes";
import { NodeShader, NodeShaderOutput, Parameter } from "@hology/core/shader/shader";
import { Color } from "three";

export class ExampleShader extends NodeShader {
  @Parameter()
  color: Color = new Color(0xff0000)

  output(): NodeShaderOutput {
    return {
      color: standardMaterial({color: rgb(this.color)})
    }
  }
}

Using GLSL

To create a shader with GLSL, extend from the Shader class and override the build method, returning a new shader material.

import { Shader } from "@hology/core/shader/shader";
import { Color, ShaderMaterial, Material } from "three";

export class MyShader extends Shader {
  
  build(): Material {
    return new ShaderMaterial({
      vertexShader: `
        void main() {
          gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
        }
      `,
      fragmentShader: `
        void main() {
          gl_FragColor = vec4(1., 0., 0., 1.);
        }
      `
    })
  }
}

Exporting shaders

For shaders to be available in the editor, shaders have to be exported in the index.ts file in a configured directory.

import { ExampleShader } from './example-shader';
import { MyShader } from './my-shader';

export default {
  ExampleShader,
  MyShader,
}

The folder in which this index.ts file is, should be configured in the hology.config.json file in the root of your project's directory.

When to use Typescript or GLSL

While you could achive the same thing directly with GLSL as in Typescript, it may require significantly more code. With typescript, it is much easier to reuse code. In the above example, we use `standardMaterial()` which adds light calculations to your color which otherwise is non-trivial to calculate on your own.

GLSL could be useful if your material doesn't require light calculations and your are more familiar with GLSL or already have code snippets you want to reuse.

Using the node based approach with Typescript is more common in Hology Engine and tutorials.

Last updated