Skip to content
This repository was archived by the owner on Jun 22, 2025. It is now read-only.
This repository was archived by the owner on Jun 22, 2025. It is now read-only.

Add mask layers #33

@supermoos

Description

@supermoos

Hi, is it possible to make a layer that's last in line in the fragment shader renderer. The reason I ask is because I'm trying to create a an AlphaGradient Layer, essentially the same as the Gradient layer, except it works as a "mask" for the whole object, so you should be able to use it to fade out an object selectively using the same params as you use to control the Gradient Layer.

Here's a test were I just tried hardcoding the alpha value to be 0.0 to make it invisible, however this quick test revealed that the alpha value doesn't seem to propegate / override the main material?

import { Abstract } from 'lamina/vanilla'

export default class AlphaGradient extends Abstract {
  static u_colorA = 'white'
  static u_colorB = 'black'
  static u_alpha = 1

  static u_start = 1
  static u_end = -1
  static u_contrast = 1

  static vertexShader = `
		varying vec3 v_position;

		vod main() {
      v_position = lamina_mapping_template;
		}
  `

  static fragmentShader = `
    uniform vec3 u_colorA;
    uniform vec3 u_colorB;
    uniform vec3 u_axis;
    uniform float u_alpha;
    uniform float u_start;
    uniform float u_end;
    uniform float u_contrast;

		varying vec3 v_position;

    void main() {

      float f_step = smoothstep(u_start, u_end, v_position.axes_template * u_contrast);
      vec3 f_color = mix(u_colorA, u_colorB, f_step);

      return vec4(f_color, 0.0);
    }
  `

  axes: 'x' | 'y' | 'z' = 'x'
  mapping: 'local' | 'world' | 'uv' = 'local'

  constructor(props?) {
    super(
      AlphaGradient,
      {
        name: 'AlphaGradient',
        ...props,
      },
      (self: AlphaGradient) => {
        self.schema.push({
          value: self.axes,
          label: 'axes',
          options: ['x', 'y', 'z'],
        })

        self.schema.push({
          value: self.mapping,
          label: 'mapping',
          options: ['uv', 'world', 'local'],
        })

        const mapping = AlphaGradient.getMapping(self.mapping)

        self.vertexShader = self.vertexShader.replace('lamina_mapping_template', mapping || 'local')
        self.fragmentShader = self.fragmentShader.replace('axes_template', self.axes || 'x')
      }
    )
  }

  private static getMapping(type?: string) {
    switch (type) {
      default:
      case 'local':
        return `position`
      case 'world':
        return `(modelMatrix * vec4(position,1.0)).xyz`
      case 'uv':
        return `vec3(uv, 0.)`
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions