threepipe
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

script.ts 2.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import {
  2. _testFinish,
  3. _testStart,
  4. AScreenPassExtensionPlugin,
  5. Color,
  6. glsl,
  7. onChange,
  8. serialize,
  9. ThreeViewer,
  10. uiColor,
  11. uiFolderContainer,
  12. uiSlider,
  13. uiToggle,
  14. uniform,
  15. } from 'threepipe'
  16. import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
  17. // Add a material extension to the screen shader material to modify the final rendered image.
  18. // Here, AScreenPassExtensionPlugin is used to create a custom screen pass extension plugin with auto generated UI and serialization.
  19. // Checkout the ScreenPass guide for more details: https://threepipe.org/docs/guides/screen-pass
  20. @uiFolderContainer('Custom Tint Extension')
  21. export class CustomScreenPassExtensionPlugin extends AScreenPassExtensionPlugin {
  22. static readonly PluginType = 'CustomScreenPassExtensionPlugin'
  23. readonly extraUniforms = {
  24. intensity: {value: 1},
  25. tintColor: {value: new Color(0xff0000)},
  26. } as const
  27. @onChange(CustomScreenPassExtensionPlugin.prototype.setDirty)
  28. @uiToggle('Enable')
  29. @serialize() enabled: boolean
  30. @uiSlider('Intensity', [0.1, 4], 0.01)
  31. @uniform({propKey: 'tintIntensity'})
  32. @serialize() intensity = 1
  33. @uiColor<CustomScreenPassExtensionPlugin>('Color', t=>({onChange:()=>t?.setDirty()}))
  34. @uniform({propKey: 'tintColor'})
  35. @serialize('tintColor') color = new Color(0xff0000)
  36. /**
  37. * The priority of the material extension when applied to the material in ScreenPass
  38. * set to very low priority, so applied at the end
  39. */
  40. priority = -50
  41. parsFragmentSnippet = () => {
  42. if (this.isDisabled()) return ''
  43. return glsl`
  44. uniform float tintIntensity;
  45. uniform vec3 tintColor;
  46. vec4 ApplyTint(vec4 color) {
  47. return vec4(color.rgb * tintColor * tintIntensity, color.a);
  48. }
  49. `
  50. }
  51. protected _shaderPatch = 'diffuseColor = ApplyTint(diffuseColor);'
  52. constructor(enabled = true) {
  53. super()
  54. this.enabled = enabled
  55. }
  56. }
  57. const viewer = new ThreeViewer({
  58. canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
  59. tonemap: true, // also tonemap (this is also added as an extension)
  60. plugins: [CustomScreenPassExtensionPlugin],
  61. })
  62. async function init() {
  63. await Promise.all([
  64. viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr'),
  65. viewer.load('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
  66. autoCenter: true,
  67. autoScale: true,
  68. })])
  69. // Add the color to the UI
  70. const ui = viewer.addPluginSync(TweakpaneUiPlugin, true)
  71. ui.setupPluginUi(CustomScreenPassExtensionPlugin, {expanded: true})
  72. }
  73. _testStart()
  74. init().finally(_testFinish)