material.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /**
  2. * Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { NumberArray } from './type-helpers';
  7. import { ParamDefinition as PD } from './param-definition';
  8. import { toFixed } from './number';
  9. /** Material properties expressed as a single number */
  10. export type Material = { readonly '@type': 'material' } & number
  11. export function Material(hex: number) { return hex as Material; }
  12. export namespace Material {
  13. export function fromNormalized(metalness: number, roughness: number): Material {
  14. return (((metalness * 255) << 16) | ((roughness * 255) << 8)) as Material;
  15. }
  16. export function fromObjectNormalized(v: { metalness: number, roughness: number }): Material {
  17. return fromNormalized(v.metalness, v.roughness);
  18. }
  19. export function toObjectNormalized(material: Material, fractionDigits?: number) {
  20. const metalness = (material >> 16 & 255) / 255;
  21. const roughness = (material >> 8 & 255) / 255;
  22. return {
  23. metalness: fractionDigits ? toFixed(metalness, fractionDigits) : metalness,
  24. roughness: fractionDigits ? toFixed(roughness, fractionDigits) : roughness
  25. };
  26. }
  27. export function toArray(material: Material, array: NumberArray, offset: number) {
  28. array[offset] = (material >> 16 & 255);
  29. array[offset + 1] = (material >> 8 & 255);
  30. return array;
  31. }
  32. export function toString(material: Material) {
  33. const metalness = (material >> 16 & 255) / 255;
  34. const roughness = (material >> 8 & 255) / 255;
  35. return `M ${metalness} | R ${roughness}`;
  36. }
  37. export function getParam(info?: { isExpanded?: boolean, isFlat?: boolean }) {
  38. return PD.Converted(
  39. (v: Material) => toObjectNormalized(v, 2),
  40. (v: { metalness: number, roughness: number }) => fromObjectNormalized(v),
  41. PD.Group({
  42. metalness: PD.Numeric(0, { min: 0, max: 1, step: 0.01 }),
  43. roughness: PD.Numeric(1, { min: 0, max: 1, step: 0.01 }),
  44. }, {
  45. ...info,
  46. presets: [
  47. [{ metalness: 0, roughness: 1 }, 'Matte'],
  48. [{ metalness: 0.5, roughness: 0.5 }, 'Metallic'],
  49. [{ metalness: 0, roughness: 0 }, 'Plastic'],
  50. ]
  51. })
  52. );
  53. }
  54. }