ColorSpaceNode.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import {
  2. LinearEncoding,
  3. sRGBEncoding
  4. } from '../../../../build/three.module.js';
  5. import { TempNode } from '../core/TempNode.js';
  6. import { FunctionNode } from '../core/FunctionNode.js';
  7. class ColorSpaceNode extends TempNode {
  8. constructor( input, method ) {
  9. super( 'v4' );
  10. this.input = input;
  11. this.method = method || ColorSpaceNode.LINEAR_TO_LINEAR;
  12. }
  13. generate( builder, output ) {
  14. const input = this.input.build( builder, 'v4' );
  15. const outputType = this.getType( builder );
  16. const methodNode = ColorSpaceNode.Nodes[ this.method ];
  17. const method = builder.include( methodNode );
  18. if ( method === ColorSpaceNode.LINEAR_TO_LINEAR ) {
  19. return builder.format( input, outputType, output );
  20. } else {
  21. if ( methodNode.inputs.length === 2 ) {
  22. const factor = this.factor.build( builder, 'f' );
  23. return builder.format( method + '( ' + input + ', ' + factor + ' )', outputType, output );
  24. } else {
  25. return builder.format( method + '( ' + input + ' )', outputType, output );
  26. }
  27. }
  28. }
  29. fromEncoding( encoding ) {
  30. const components = ColorSpaceNode.getEncodingComponents( encoding );
  31. this.method = 'LinearTo' + components[ 0 ];
  32. this.factor = components[ 1 ];
  33. }
  34. fromDecoding( encoding ) {
  35. const components = ColorSpaceNode.getEncodingComponents( encoding );
  36. this.method = components[ 0 ] + 'ToLinear';
  37. this.factor = components[ 1 ];
  38. }
  39. copy( source ) {
  40. super.copy( source );
  41. this.input = source.input;
  42. this.method = source.method;
  43. return this;
  44. }
  45. toJSON( meta ) {
  46. let data = this.getJSONNode( meta );
  47. if ( ! data ) {
  48. data = this.createJSONNode( meta );
  49. data.input = this.input.toJSON( meta ).uuid;
  50. data.method = this.method;
  51. }
  52. return data;
  53. }
  54. }
  55. ColorSpaceNode.Nodes = ( function () {
  56. const LinearToLinear = new FunctionNode( /* glsl */`
  57. vec4 LinearToLinear( in vec4 value ) {
  58. return value;
  59. }`
  60. );
  61. const sRGBToLinear = new FunctionNode( /* glsl */`
  62. vec4 sRGBToLinear( in vec4 value ) {
  63. return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );
  64. }`
  65. );
  66. const LinearTosRGB = new FunctionNode( /* glsl */`
  67. vec4 LinearTosRGB( in vec4 value ) {
  68. return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );
  69. }`
  70. );
  71. return {
  72. LinearToLinear: LinearToLinear,
  73. sRGBToLinear: sRGBToLinear,
  74. LinearTosRGB: LinearTosRGB
  75. };
  76. } )();
  77. ColorSpaceNode.LINEAR_TO_LINEAR = 'LinearToLinear';
  78. ColorSpaceNode.SRGB_TO_LINEAR = 'sRGBToLinear';
  79. ColorSpaceNode.LINEAR_TO_SRGB = 'LinearTosRGB';
  80. ColorSpaceNode.getEncodingComponents = function ( encoding ) {
  81. switch ( encoding ) {
  82. case LinearEncoding:
  83. return [ 'Linear' ];
  84. case sRGBEncoding:
  85. return [ 'sRGB' ];
  86. }
  87. };
  88. ColorSpaceNode.prototype.nodeType = 'ColorSpace';
  89. ColorSpaceNode.prototype.hashProperties = [ 'method' ];
  90. export { ColorSpaceNode };