NgtsCustomShaderMaterial
import { ChangeDetectionStrategy, Component } from '@angular/core';import { SobaWrapper } from '@soba/wrapper.ts';import { NgtCanvas, provideNgtRenderer } from 'angular-three/dom';import { SceneGraph } from './scene-graph';
@Component({ selector: 'app-custom-shader-material', template: ` <ngt-canvas [camera]="{ position: [0, 0, 3], fov: 50 }"> <app-soba-wrapper *canvasContent [grid]="false"> <app-scene-graph /> </app-soba-wrapper> </ngt-canvas> `, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'custom-shader-material-demo relative block h-full' }, imports: [NgtCanvas, SobaWrapper, SceneGraph],})export default class CustomShaderMaterial { static clientProviders = [provideNgtRenderer()];}import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, viewChild } from '@angular/core';import { beforeRender, NgtArgs } from 'angular-three';import { NgtsCustomShaderMaterial } from 'angular-three-soba/materials';import { MeshStandardMaterial } from 'three';
@Component({ selector: 'app-scene-graph', template: ` <ngt-mesh> <ngt-sphere-geometry *args="[1, 64, 64]" /> <ngts-custom-shader-material [baseMaterial]="MeshStandardMaterial" [options]="{ vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, metalness: 0.5, roughness: 0.3, }" /> </ngt-mesh> `, schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgtArgs, NgtsCustomShaderMaterial],})export class SceneGraph { protected readonly MeshStandardMaterial = MeshStandardMaterial;
private materialRef = viewChild(NgtsCustomShaderMaterial);
uniforms = { uTime: { value: 0 }, uAmplitude: { value: 0.2 }, uFrequency: { value: 3.0 }, };
vertexShader = /* glsl */ ` uniform float uTime; uniform float uAmplitude; uniform float uFrequency;
varying vec3 vNormal;
void main() { vNormal = normal;
// Wave displacement float displacement = sin(position.x * uFrequency + uTime) * sin(position.y * uFrequency + uTime) * sin(position.z * uFrequency + uTime) * uAmplitude;
vec3 newPosition = position + normal * displacement; csm_Position = newPosition; } `;
fragmentShader = /* glsl */ ` uniform float uTime; varying vec3 vNormal;
void main() { // Color based on normal and time vec3 color = 0.5 + 0.5 * cos(uTime + vNormal.xyx + vec3(0, 2, 4)); csm_DiffuseColor = vec4(color, 1.0); } `;
constructor() { beforeRender(({ clock }) => { const material = this.materialRef()?.material(); if (material) { material.uniforms['uTime'].value = clock.elapsedTime; } }); }}NgtsCustomShaderMaterial is a port of three-custom-shader-material that allows you to create custom shader materials by extending existing THREE.js materials. It provides a flexible way to define your own shaders while retaining all the features of the base material.
Usage
import { NgtsCustomShaderMaterial } from 'angular-three-soba/materials';<ngt-points> <ngt-icosahedron-geometry *args="[1, 32]" /> <ngts-custom-shader-material [baseMaterial]="PointsMaterial" [options]="{ vertexShader: myVertexShader, fragmentShader: myFragmentShader, uniforms: { time: { value: 0 } } }" /></ngt-points>Peer Dependencies
Requires three-custom-shader-material:
npm install three-custom-shader-materialExample with MeshPhysicalMaterial
import * as THREE from 'three';
@Component({ template: ` <ngt-mesh> <ngt-sphere-geometry /> <ngts-custom-shader-material [baseMaterial]="MeshPhysicalMaterial" [options]="{ vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, roughness: 0.5, metalness: 0.8 }" /> </ngt-mesh> `})export class CustomMaterial { MeshPhysicalMaterial = THREE.MeshPhysicalMaterial;
vertexShader = ` varying vec3 vPosition; void main() { vPosition = position; } `;
fragmentShader = ` varying vec3 vPosition; void main() { csm_DiffuseColor = vec4(vPosition * 0.5 + 0.5, 1.0); } `;
uniforms = { time: { value: 0 } };}Options
Properties
| name | type | description |
|---|---|---|
| baseMaterial | Material | Class<Material> | ElementRef<Material> | The base material to extend. Can be a material instance, a material class, or an ElementRef to a material. |
| attach | string | How to attach the material to its parent object. |
| vertexShader | string | The vertex shader code. |
| fragmentShader | string | The fragment shader code. |
| uniforms | Record<string, { value: any }> | An object containing the uniforms for the shader. |
| cacheKey | string | Cache key for shader compilation. |