fxaa.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { QuadSchema, QuadValues } from '../../mol-gl/compute/util';
  7. import { ComputeRenderable, createComputeRenderable } from '../../mol-gl/renderable';
  8. import { TextureSpec, UniformSpec, DefineSpec, Values } from '../../mol-gl/renderable/schema';
  9. import { ShaderCode } from '../../mol-gl/shader-code';
  10. import { WebGLContext } from '../../mol-gl/webgl/context';
  11. import { createComputeRenderItem } from '../../mol-gl/webgl/render-item';
  12. import { Texture } from '../../mol-gl/webgl/texture';
  13. import { Vec2 } from '../../mol-math/linear-algebra';
  14. import { ValueCell } from '../../mol-util';
  15. import { ParamDefinition as PD } from '../../mol-util/param-definition';
  16. import quad_vert from '../../mol-gl/shader/quad.vert';
  17. import fxaa_frag from '../../mol-gl/shader/fxaa.frag';
  18. export const FxaaParams = {
  19. edgeThresholdMin: PD.Numeric(0.0312, { min: 0.0312, max: 0.0833, step: 0.0001 }, { description: 'Trims the algorithm from processing darks.' }),
  20. edgeThresholdMax: PD.Numeric(0.063, { min: 0.063, max: 0.333, step: 0.001 }, { description: 'The minimum amount of local contrast required to apply algorithm.' }),
  21. iterations: PD.Numeric(12, { min: 0, max: 16, step: 1 }, { description: 'Number of edge exploration steps.' }),
  22. subpixelQuality: PD.Numeric(0.30, { min: 0.00, max: 1.00, step: 0.01 }, { description: 'Choose the amount of sub-pixel aliasing removal.' }),
  23. };
  24. export type FxaaProps = PD.Values<typeof FxaaParams>
  25. export class FxaaPass {
  26. private readonly renderable: FxaaRenderable
  27. constructor(webgl: WebGLContext, input: Texture) {
  28. this.renderable = getFxaaRenderable(webgl, input);
  29. }
  30. setSize(width: number, height: number) {
  31. ValueCell.update(this.renderable.values.uTexSizeInv, Vec2.set(this.renderable.values.uTexSizeInv.ref.value, 1 / width, 1 / height));
  32. }
  33. update(input: Texture, props: FxaaProps) {
  34. const { values } = this.renderable;
  35. const { edgeThresholdMin, edgeThresholdMax, iterations, subpixelQuality } = props;
  36. let needsUpdate = false;
  37. if (values.tColor.ref.value !== input) {
  38. ValueCell.update(this.renderable.values.tColor, input);
  39. needsUpdate = true;
  40. }
  41. if (values.dEdgeThresholdMin.ref.value !== edgeThresholdMin) needsUpdate = true;
  42. ValueCell.updateIfChanged(values.dEdgeThresholdMin, edgeThresholdMin);
  43. if (values.dEdgeThresholdMax.ref.value !== edgeThresholdMax) needsUpdate = true;
  44. ValueCell.updateIfChanged(values.dEdgeThresholdMax, edgeThresholdMax);
  45. if (values.dIterations.ref.value !== iterations) needsUpdate = true;
  46. ValueCell.updateIfChanged(values.dIterations, iterations);
  47. if (values.dSubpixelQuality.ref.value !== subpixelQuality) needsUpdate = true;
  48. ValueCell.updateIfChanged(values.dSubpixelQuality, subpixelQuality);
  49. if (needsUpdate) {
  50. this.renderable.update();
  51. }
  52. }
  53. render() {
  54. this.renderable.render();
  55. }
  56. }
  57. //
  58. const FxaaSchema = {
  59. ...QuadSchema,
  60. tColor: TextureSpec('texture', 'rgba', 'ubyte', 'linear'),
  61. uTexSizeInv: UniformSpec('v2'),
  62. dEdgeThresholdMin: DefineSpec('number'),
  63. dEdgeThresholdMax: DefineSpec('number'),
  64. dIterations: DefineSpec('number'),
  65. dSubpixelQuality: DefineSpec('number'),
  66. };
  67. const FxaaShaderCode = ShaderCode('fxaa', quad_vert, fxaa_frag);
  68. type FxaaRenderable = ComputeRenderable<Values<typeof FxaaSchema>>
  69. function getFxaaRenderable(ctx: WebGLContext, colorTexture: Texture): FxaaRenderable {
  70. const width = colorTexture.getWidth();
  71. const height = colorTexture.getHeight();
  72. const values: Values<typeof FxaaSchema> = {
  73. ...QuadValues,
  74. tColor: ValueCell.create(colorTexture),
  75. uTexSizeInv: ValueCell.create(Vec2.create(1 / width, 1 / height)),
  76. dEdgeThresholdMin: ValueCell.create(0.0312),
  77. dEdgeThresholdMax: ValueCell.create(0.125),
  78. dIterations: ValueCell.create(12),
  79. dSubpixelQuality: ValueCell.create(0.3),
  80. };
  81. const schema = { ...FxaaSchema };
  82. const renderItem = createComputeRenderItem(ctx, 'triangles', FxaaShaderCode, schema, values);
  83. return createComputeRenderable(renderItem, values);
  84. }