NgtsMeshRefractionMaterial
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-mesh-refraction-material', template: ` <ngt-canvas [camera]="{ position: [0, 0, 4], fov: 50 }"> <app-soba-wrapper *canvasContent [grid]="false" [lights]="false"> <app-scene-graph /> </app-soba-wrapper> </ngt-canvas> `, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'mesh-refraction-material-demo relative block h-full' }, imports: [NgtCanvas, SobaWrapper, SceneGraph],})export default class MeshRefractionMaterial { static clientProviders = [provideNgtRenderer()];}import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, viewChild } from '@angular/core';import { beforeRender, NgtArgs } from 'angular-three';import { NgtsCameraContent, NgtsCubeCamera } from 'angular-three-soba/cameras';import { NgtsMeshRefractionMaterial } from 'angular-three-soba/materials';import { NgtsEnvironment } from 'angular-three-soba/staging';import { Mesh } from 'three';
@Component({ selector: 'app-scene-graph', template: ` <ngts-environment [options]="{ preset: 'city', background: true, backgroundBlurriness: 0.1 }" />
<ngts-cube-camera [options]="{ frames: 6, resolution: 256 }"> <ng-template cameraContent let-texture> <ngt-mesh #crystal [scale]="1.2"> <ngt-icosahedron-geometry *args="[1, 0]" /> <ngts-mesh-refraction-material [envMap]="texture" [options]="{ bounces: 3, ior: 2.4, fresnel: 1, aberrationStrength: 0.02, fastChroma: true, toneMapped: false, }" /> </ngt-mesh> </ng-template> </ngts-cube-camera>
<ngt-point-light [position]="[-3, 2, 2]" color="#ff6b6b" [intensity]="50" /> <ngt-point-light [position]="[3, 2, 2]" color="#4ecdc4" [intensity]="50" /> <ngt-point-light [position]="[0, -2, 3]" color="#ffe66d" [intensity]="50" />
<ngt-ambient-light [intensity]="0.5" /> `, schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgtArgs, NgtsMeshRefractionMaterial, NgtsCubeCamera, NgtsCameraContent, NgtsEnvironment],})export class SceneGraph { private crystalRef = viewChild<ElementRef<Mesh>>('crystal');
constructor() { beforeRender(({ delta }) => { const crystal = this.crystalRef()?.nativeElement; if (crystal) { crystal.rotation.y += delta * 0.2; crystal.rotation.x += delta * 0.1; } }); }}NgtsMeshRefractionMaterial is a port of Drei’s MeshRefractionMaterial that simulates realistic light refraction through transparent objects. It uses ray tracing with BVH acceleration for accurate light bending effects, making it ideal for diamonds, crystals, glass, and other transparent materials.
Peer Dependencies
Requires three-mesh-bvh:
npm install three-mesh-bvhUsage
import { NgtsMeshRefractionMaterial } from 'angular-three-soba/materials';If you want the material to reflect other objects in the scene, pair it with NgtsCubeCamera:
<ngts-cube-camera> <ngt-mesh *cameraContent="let texture"> <ngt-dodecahedron-geometry /> <ngts-mesh-refraction-material [envMap]="texture()" /> </ngt-mesh></ngts-cube-camera>Otherwise, just pass an environment map directly:
<!-- texture = loaderResource(() => RGBELoader, () => 'path/to/texture.hdr') --><ngt-mesh> <ngt-dodecahedron-geometry /> <ngts-mesh-refraction-material [envMap]="texture()" /></ngt-mesh>Diamond Example
@Component({ template: ` <ngts-cube-camera [options]="{ resolution: 256, frames: 1 }"> <ngt-mesh *cameraContent="let texture"> <ngt-dodecahedron-geometry /> <ngts-mesh-refraction-material [envMap]="texture()" [options]="{ bounces: 3, ior: 2.4, fresnel: 1, aberrationStrength: 0.02, color: 'white' }" /> </ngt-mesh> </ngts-cube-camera> `})export class Diamond {}Common IOR Values
| Material | IOR |
|---|---|
| Air | 1.0 |
| Water | 1.33 |
| Glass | 1.5 |
| Crystal | 2.0 |
| Diamond | 2.4 |
Higher bounces values produce more accurate refractions but require more computation. For most cases, 2-3 bounces provide a good balance between quality and performance.
Inputs
| name | type | description | required |
|---|---|---|---|
| envMap | THREE.CubeTexture | THREE.Texture | The environment map used for refraction. Required for the material to work. | yes |
| attach | string | How to attach the material to its parent object. | no |
Options
Properties
| name | type | description |
|---|---|---|
| bounces | number | The number of ray-cast bounces for light simulation. |
| ior | number | The refraction index. Diamond is 2.4, glass is 1.5, water is 1.33. |
| fresnel | number | The Fresnel effect intensity (strip light reflections). |
| aberrationStrength | number | The RGB chromatic aberration shift intensity. |
| color | THREE.ColorRepresentation | The color of the material. |
| fastChroma | boolean | Whether to use fewer ray casts for the RGB shift, sacrificing physical accuracy for performance. |