Bladeren bron

Examples: Convert shaders to ES6. (#21619)

Michael Herzog 4 jaren geleden
bovenliggende
commit
0978e03edf
100 gewijzigde bestanden met toevoegingen van 6565 en 4143 verwijderingen
  1. 62 10
      examples/js/shaders/ACESFilmicToneMappingShader.js
  2. 32 3
      examples/js/shaders/AfterimageShader.js
  3. 11 3
      examples/js/shaders/BasicShader.js
  4. 37 3
      examples/js/shaders/BleachBypassShader.js
  5. 24 3
      examples/js/shaders/BlendShader.js
  6. 1 5
      examples/js/shaders/BokehShader.js
  7. 1 2
      examples/js/shaders/BokehShader2.js
  8. 29 3
      examples/js/shaders/BrightnessContrastShader.js
  9. 23 3
      examples/js/shaders/ColorCorrectionShader.js
  10. 24 3
      examples/js/shaders/ColorifyShader.js
  11. 44 18
      examples/js/shaders/ConvolutionShader.js
  12. 20 2
      examples/js/shaders/CopyShader.js
  13. 29 3
      examples/js/shaders/DOFMipMapShader.js
  14. 97 13
      examples/js/shaders/DepthLimitedBlurShader.js
  15. 66 7
      examples/js/shaders/DigitalGlitch.js
  16. 38 3
      examples/js/shaders/DotScreenShader.js
  17. 1 2
      examples/js/shaders/FXAAShader.js
  18. 59 14
      examples/js/shaders/FilmShader.js
  19. 61 3
      examples/js/shaders/FocusShader.js
  20. 66 7
      examples/js/shaders/FreiChenShader.js
  21. 46 3
      examples/js/shaders/FresnelShader.js
  22. 20 4
      examples/js/shaders/GammaCorrectionShader.js
  23. 163 40
      examples/js/shaders/GodRaysShader.js
  24. 277 19
      examples/js/shaders/HalftoneShader.js
  25. 30 2
      examples/js/shaders/HorizontalBlurShader.js
  26. 33 2
      examples/js/shaders/HorizontalTiltShiftShader.js
  27. 40 5
      examples/js/shaders/HueSaturationShader.js
  28. 28 3
      examples/js/shaders/KaleidoShader.js
  29. 33 3
      examples/js/shaders/LuminosityHighPassShader.js
  30. 25 3
      examples/js/shaders/LuminosityShader.js
  31. 30 3
      examples/js/shaders/MirrorShader.js
  32. 25 3
      examples/js/shaders/NormalMapShader.js
  33. 151 19
      examples/js/shaders/ParallaxShader.js
  34. 23 4
      examples/js/shaders/PixelShader.js
  35. 24 3
      examples/js/shaders/RGBShiftShader.js
  36. 1 2
      examples/js/shaders/SAOShader.js
  37. 378 91
      examples/js/shaders/SMAAShader.js
  38. 206 19
      examples/js/shaders/SSAOShader.js
  39. 1 1
      examples/js/shaders/SSRrShader.js
  40. 27 3
      examples/js/shaders/SepiaShader.js
  41. 62 13
      examples/js/shaders/SobelOperatorShader.js
  42. 3 3
      examples/js/shaders/SubsurfaceScatteringShader.js
  43. 20 3
      examples/js/shaders/TechnicolorShader.js
  44. 48 5
      examples/js/shaders/ToneMapShader.js
  45. 214 12
      examples/js/shaders/ToonShader.js
  46. 41 4
      examples/js/shaders/TriangleBlurShader.js
  47. 23 3
      examples/js/shaders/UnpackDepthRGBAShader.js
  48. 31 3
      examples/js/shaders/VerticalBlurShader.js
  49. 34 3
      examples/js/shaders/VerticalTiltShiftShader.js
  50. 25 13
      examples/js/shaders/VignetteShader.js
  51. 259 50
      examples/js/shaders/VolumeShader.js
  52. 56 5
      examples/js/shaders/WaterRefractionShader.js
  53. 38 42
      examples/jsm/shaders/ACESFilmicToneMappingShader.js
  54. 21 25
      examples/jsm/shaders/AfterimageShader.js
  55. 9 13
      examples/jsm/shaders/BasicShader.js
  56. 25 29
      examples/jsm/shaders/BleachBypassShader.js
  57. 18 22
      examples/jsm/shaders/BlendShader.js
  58. 88 92
      examples/jsm/shaders/BokehShader.js
  59. 229 241
      examples/jsm/shaders/BokehShader2.js
  60. 21 25
      examples/jsm/shaders/BrightnessContrastShader.js
  61. 17 21
      examples/jsm/shaders/ColorCorrectionShader.js
  62. 17 21
      examples/jsm/shaders/ColorifyShader.js
  63. 36 39
      examples/jsm/shaders/ConvolutionShader.js
  64. 14 18
      examples/jsm/shaders/CopyShader.js
  65. 20 24
      examples/jsm/shaders/DOFMipMapShader.js
  66. 79 79
      examples/jsm/shaders/DepthLimitedBlurShader.js
  67. 62 65
      examples/jsm/shaders/DigitalGlitch.js
  68. 25 29
      examples/jsm/shaders/DotScreenShader.js
  69. 1087 1089
      examples/jsm/shaders/FXAAShader.js
  70. 28 32
      examples/jsm/shaders/FilmShader.js
  71. 42 46
      examples/jsm/shaders/FocusShader.js
  72. 52 55
      examples/jsm/shaders/FreiChenShader.js
  73. 34 38
      examples/jsm/shaders/FresnelShader.js
  74. 14 18
      examples/jsm/shaders/GammaCorrectionShader.js
  75. 88 105
      examples/jsm/shaders/GodRaysShader.js
  76. 201 205
      examples/jsm/shaders/HalftoneShader.js
  77. 23 27
      examples/jsm/shaders/HorizontalBlurShader.js
  78. 25 29
      examples/jsm/shaders/HorizontalTiltShiftShader.js
  79. 32 36
      examples/jsm/shaders/HueSaturationShader.js
  80. 23 27
      examples/jsm/shaders/KaleidoShader.js
  81. 22 26
      examples/jsm/shaders/LuminosityHighPassShader.js
  82. 16 20
      examples/jsm/shaders/LuminosityShader.js
  83. 25 29
      examples/jsm/shaders/MirrorShader.js
  84. 18 22
      examples/jsm/shaders/NormalMapShader.js
  85. 108 112
      examples/jsm/shaders/ParallaxShader.js
  86. 18 21
      examples/jsm/shaders/PixelShader.js
  87. 19 23
      examples/jsm/shaders/RGBShiftShader.js
  88. 146 148
      examples/jsm/shaders/SAOShader.js
  89. 288 300
      examples/jsm/shaders/SMAAShader.js
  90. 127 139
      examples/jsm/shaders/SSAOShader.js
  91. 1 1
      examples/jsm/shaders/SSRrShader.js
  92. 19 23
      examples/jsm/shaders/SepiaShader.js
  93. 33 37
      examples/jsm/shaders/SobelOperatorShader.js
  94. 3 3
      examples/jsm/shaders/SubsurfaceScatteringShader.js
  95. 15 19
      examples/jsm/shaders/TechnicolorShader.js
  96. 36 40
      examples/jsm/shaders/ToneMapShader.js
  97. 136 152
      examples/jsm/shaders/ToonShader.js
  98. 25 29
      examples/jsm/shaders/TriangleBlurShader.js
  99. 16 20
      examples/jsm/shaders/UnpackDepthRGBAShader.js
  100. 24 28
      examples/jsm/shaders/VerticalBlurShader.js

+ 62 - 10
examples/js/shaders/ACESFilmicToneMappingShader.js

@@ -7,7 +7,7 @@
  * this implementation of ACES is modified to accommodate a brighter viewing environment.
  * this implementation of ACES is modified to accommodate a brighter viewing environment.
  * the scale factor of 1/0.6 is subjective. see discussion in #19621.
  * the scale factor of 1/0.6 is subjective. see discussion in #19621.
  */
  */
-	var ACESFilmicToneMappingShader = {
+	const ACESFilmicToneMappingShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -16,15 +16,67 @@
 				value: 1.0
 				value: 1.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ '#define saturate(a) clamp( a, 0.0, 1.0 )', 'uniform sampler2D tDiffuse;', 'uniform float exposure;', 'varying vec2 vUv;', 'vec3 RRTAndODTFit( vec3 v ) {', '	vec3 a = v * ( v + 0.0245786 ) - 0.000090537;', '	vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;', '	return a / b;', '}', 'vec3 ACESFilmicToneMapping( vec3 color ) {', // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
-			'	const mat3 ACESInputMat = mat3(', '		vec3( 0.59719, 0.07600, 0.02840 ),', // transposed from source
-			'		vec3( 0.35458, 0.90834, 0.13383 ),', '		vec3( 0.04823, 0.01566, 0.83777 )', '	);', // ODT_SAT => XYZ => D60_2_D65 => sRGB
-			'	const mat3 ACESOutputMat = mat3(', '		vec3(	1.60475, -0.10208, -0.00327 ),', // transposed from source
-			'		vec3( -0.53108,	1.10813, -0.07276 ),', '		vec3( -0.07367, -0.00605,	1.07602 )', '	);', '	color = ACESInputMat * color;', // Apply RRT and ODT
-			'	color = RRTAndODTFit( color );', '	color = ACESOutputMat * color;', // Clamp to [0, 1]
-			'	return saturate( color );', '}', 'void main() {', '	vec4 tex = texture2D( tDiffuse, vUv );', '	tex.rgb *= exposure / 0.6;', // pre-exposed, outside of the tone mapping function
-			'	gl_FragColor = vec4( ACESFilmicToneMapping( tex.rgb ), tex.a );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `#define saturate(a) clamp( a, 0.0, 1.0 )
+
+		uniform sampler2D tDiffuse;
+
+		uniform float exposure;
+
+		varying vec2 vUv;
+
+		vec3 RRTAndODTFit( vec3 v ) {
+
+			vec3 a = v * ( v + 0.0245786 ) - 0.000090537;
+			vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;
+			return a / b;
+
+		}
+
+		vec3 ACESFilmicToneMapping( vec3 color ) {
+
+		// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
+			const mat3 ACESInputMat = mat3(
+				vec3( 0.59719, 0.07600, 0.02840 ), // transposed from source
+				vec3( 0.35458, 0.90834, 0.13383 ),
+				vec3( 0.04823, 0.01566, 0.83777 )
+			);
+
+		// ODT_SAT => XYZ => D60_2_D65 => sRGB
+			const mat3 ACESOutputMat = mat3(
+				vec3(	1.60475, -0.10208, -0.00327 ), // transposed from source
+				vec3( -0.53108,	1.10813, -0.07276 ),
+				vec3( -0.07367, -0.00605,	1.07602 )
+			);
+
+			color = ACESInputMat * color;
+
+		// Apply RRT and ODT
+			color = RRTAndODTFit( color );
+
+			color = ACESOutputMat * color;
+
+		// Clamp to [0, 1]
+			return saturate( color );
+
+		}
+
+		void main() {
+
+			vec4 tex = texture2D( tDiffuse, vUv );
+
+			tex.rgb *= exposure / 0.6; // pre-exposed, outside of the tone mapping function
+
+			gl_FragColor = vec4( ACESFilmicToneMapping( tex.rgb ), tex.a );
+
+		}`
 	};
 	};
 
 
 	THREE.ACESFilmicToneMappingShader = ACESFilmicToneMappingShader;
 	THREE.ACESFilmicToneMappingShader = ACESFilmicToneMappingShader;

+ 32 - 3
examples/js/shaders/AfterimageShader.js

@@ -5,7 +5,7 @@
  * I created this effect inspired by a demo on codepen:
  * I created this effect inspired by a demo on codepen:
  * https://codepen.io/brunoimbrizi/pen/MoRJaN?page=1&
  * https://codepen.io/brunoimbrizi/pen/MoRJaN?page=1&
  */
  */
-	var AfterimageShader = {
+	const AfterimageShader = {
 		uniforms: {
 		uniforms: {
 			'damp': {
 			'damp': {
 				value: 0.96
 				value: 0.96
@@ -17,8 +17,37 @@
 				value: null
 				value: null
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float damp;', 'uniform sampler2D tOld;', 'uniform sampler2D tNew;', 'varying vec2 vUv;', 'vec4 when_gt( vec4 x, float y ) {', '	return max( sign( x - y ), 0.0 );', '}', 'void main() {', '	vec4 texelOld = texture2D( tOld, vUv );', '	vec4 texelNew = texture2D( tNew, vUv );', '	texelOld *= damp * when_gt( texelOld, 0.1 );', '	gl_FragColor = max(texelNew, texelOld);', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float damp;
+
+		uniform sampler2D tOld;
+		uniform sampler2D tNew;
+
+		varying vec2 vUv;
+
+		vec4 when_gt( vec4 x, float y ) {
+
+			return max( sign( x - y ), 0.0 );
+
+		}
+
+		void main() {
+
+			vec4 texelOld = texture2D( tOld, vUv );
+			vec4 texelNew = texture2D( tNew, vUv );
+
+			texelOld *= damp * when_gt( texelOld, 0.1 );
+
+			gl_FragColor = max(texelNew, texelOld);
+
+		}`
 	};
 	};
 
 
 	THREE.AfterimageShader = AfterimageShader;
 	THREE.AfterimageShader = AfterimageShader;

+ 11 - 3
examples/js/shaders/BasicShader.js

@@ -3,10 +3,18 @@
 	/**
 	/**
  * Simple test shader
  * Simple test shader
  */
  */
-	var BasicShader = {
+	const BasicShader = {
 		uniforms: {},
 		uniforms: {},
-		vertexShader: [ 'void main() {', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'void main() {', '	gl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5 );', '}' ].join( '\n' )
+		vertexShader: `void main() {
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `void main() {
+
+			gl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5 );
+
+		}`
 	};
 	};
 
 
 	THREE.BasicShader = BasicShader;
 	THREE.BasicShader = BasicShader;

+ 37 - 3
examples/js/shaders/BleachBypassShader.js

@@ -5,7 +5,7 @@
  * - based on Nvidia example
  * - based on Nvidia example
  * http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html#post_bleach_bypass
  * http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html#post_bleach_bypass
  */
  */
-	var BleachBypassShader = {
+	const BleachBypassShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -14,8 +14,42 @@
 				value: 1.0
 				value: 1.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float opacity;', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'void main() {', '	vec4 base = texture2D( tDiffuse, vUv );', '	vec3 lumCoeff = vec3( 0.25, 0.65, 0.1 );', '	float lum = dot( lumCoeff, base.rgb );', '	vec3 blend = vec3( lum );', '	float L = min( 1.0, max( 0.0, 10.0 * ( lum - 0.45 ) ) );', '	vec3 result1 = 2.0 * base.rgb * blend;', '	vec3 result2 = 1.0 - 2.0 * ( 1.0 - blend ) * ( 1.0 - base.rgb );', '	vec3 newColor = mix( result1, result2, L );', '	float A2 = opacity * base.a;', '	vec3 mixRGB = A2 * newColor.rgb;', '	mixRGB += ( ( 1.0 - A2 ) * base.rgb );', '	gl_FragColor = vec4( mixRGB, base.a );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float opacity;
+
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 base = texture2D( tDiffuse, vUv );
+
+			vec3 lumCoeff = vec3( 0.25, 0.65, 0.1 );
+			float lum = dot( lumCoeff, base.rgb );
+			vec3 blend = vec3( lum );
+
+			float L = min( 1.0, max( 0.0, 10.0 * ( lum - 0.45 ) ) );
+
+			vec3 result1 = 2.0 * base.rgb * blend;
+			vec3 result2 = 1.0 - 2.0 * ( 1.0 - blend ) * ( 1.0 - base.rgb );
+
+			vec3 newColor = mix( result1, result2, L );
+
+			float A2 = opacity * base.a;
+			vec3 mixRGB = A2 * newColor.rgb;
+			mixRGB += ( ( 1.0 - A2 ) * base.rgb );
+
+			gl_FragColor = vec4( mixRGB, base.a );
+
+		}`
 	};
 	};
 
 
 	THREE.BleachBypassShader = BleachBypassShader;
 	THREE.BleachBypassShader = BleachBypassShader;

+ 24 - 3
examples/js/shaders/BlendShader.js

@@ -3,7 +3,7 @@
 	/**
 	/**
  * Blend two textures
  * Blend two textures
  */
  */
-	var BlendShader = {
+	const BlendShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse1': {
 			'tDiffuse1': {
 				value: null
 				value: null
@@ -18,8 +18,29 @@
 				value: 1.0
 				value: 1.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float opacity;', 'uniform float mixRatio;', 'uniform sampler2D tDiffuse1;', 'uniform sampler2D tDiffuse2;', 'varying vec2 vUv;', 'void main() {', '	vec4 texel1 = texture2D( tDiffuse1, vUv );', '	vec4 texel2 = texture2D( tDiffuse2, vUv );', '	gl_FragColor = opacity * mix( texel1, texel2, mixRatio );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float opacity;
+		uniform float mixRatio;
+
+		uniform sampler2D tDiffuse1;
+		uniform sampler2D tDiffuse2;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 texel1 = texture2D( tDiffuse1, vUv );
+			vec4 texel2 = texture2D( tDiffuse2, vUv );
+			gl_FragColor = opacity * mix( texel1, texel2, mixRatio );
+
+		}`
 	};
 	};
 
 
 	THREE.BlendShader = BlendShader;
 	THREE.BlendShader = BlendShader;

File diff suppressed because it is too large
+ 1 - 5
examples/js/shaders/BokehShader.js


File diff suppressed because it is too large
+ 1 - 2
examples/js/shaders/BokehShader2.js


+ 29 - 3
examples/js/shaders/BrightnessContrastShader.js

@@ -6,7 +6,7 @@
  * brightness: -1 to 1 (-1 is solid black, 0 is no change, and 1 is solid white)
  * brightness: -1 to 1 (-1 is solid black, 0 is no change, and 1 is solid white)
  * contrast: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast)
  * contrast: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast)
  */
  */
-	var BrightnessContrastShader = {
+	const BrightnessContrastShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -18,8 +18,34 @@
 				value: 0
 				value: 0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform float brightness;', 'uniform float contrast;', 'varying vec2 vUv;', 'void main() {', '	gl_FragColor = texture2D( tDiffuse, vUv );', '	gl_FragColor.rgb += brightness;', '	if (contrast > 0.0) {', '		gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) / (1.0 - contrast) + 0.5;', '	} else {', '		gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) * (1.0 + contrast) + 0.5;', '	}', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform float brightness;
+		uniform float contrast;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			gl_FragColor = texture2D( tDiffuse, vUv );
+
+			gl_FragColor.rgb += brightness;
+
+			if (contrast > 0.0) {
+				gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) / (1.0 - contrast) + 0.5;
+			} else {
+				gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) * (1.0 + contrast) + 0.5;
+			}
+
+		}`
 	};
 	};
 
 
 	THREE.BrightnessContrastShader = BrightnessContrastShader;
 	THREE.BrightnessContrastShader = BrightnessContrastShader;

+ 23 - 3
examples/js/shaders/ColorCorrectionShader.js

@@ -4,7 +4,7 @@
  * Color correction
  * Color correction
  */
  */
 
 
-	var ColorCorrectionShader = {
+	const ColorCorrectionShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -19,8 +19,28 @@
 				value: new THREE.Vector3( 0, 0, 0 )
 				value: new THREE.Vector3( 0, 0, 0 )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform vec3 powRGB;', 'uniform vec3 mulRGB;', 'uniform vec3 addRGB;', 'varying vec2 vUv;', 'void main() {', '	gl_FragColor = texture2D( tDiffuse, vUv );', '	gl_FragColor.rgb = mulRGB * pow( ( gl_FragColor.rgb + addRGB ), powRGB );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform vec3 powRGB;
+		uniform vec3 mulRGB;
+		uniform vec3 addRGB;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			gl_FragColor = texture2D( tDiffuse, vUv );
+			gl_FragColor.rgb = mulRGB * pow( ( gl_FragColor.rgb + addRGB ), powRGB );
+
+		}`
 	};
 	};
 
 
 	THREE.ColorCorrectionShader = ColorCorrectionShader;
 	THREE.ColorCorrectionShader = ColorCorrectionShader;

+ 24 - 3
examples/js/shaders/ColorifyShader.js

@@ -4,7 +4,7 @@
  * Colorify shader
  * Colorify shader
  */
  */
 
 
-	var ColorifyShader = {
+	const ColorifyShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -13,8 +13,29 @@
 				value: new THREE.Color( 0xffffff )
 				value: new THREE.Color( 0xffffff )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform vec3 color;', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'void main() {', '	vec4 texel = texture2D( tDiffuse, vUv );', '	vec3 luma = vec3( 0.299, 0.587, 0.114 );', '	float v = dot( texel.xyz, luma );', '	gl_FragColor = vec4( v * color, texel.w );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform vec3 color;
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 texel = texture2D( tDiffuse, vUv );
+
+			vec3 luma = vec3( 0.299, 0.587, 0.114 );
+			float v = dot( texel.xyz, luma );
+
+			gl_FragColor = vec4( v * color, texel.w );
+
+		}`
 	};
 	};
 
 
 	THREE.ColorifyShader = ColorifyShader;
 	THREE.ColorifyShader = ColorifyShader;

+ 44 - 18
examples/js/shaders/ConvolutionShader.js

@@ -6,7 +6,7 @@
  * http://o3d.googlecode.com/svn/trunk/samples/convolution.html
  * http://o3d.googlecode.com/svn/trunk/samples/convolution.html
  */
  */
 
 
-	var ConvolutionShader = {
+	const ConvolutionShader = {
 		defines: {
 		defines: {
 			'KERNEL_SIZE_FLOAT': '25.0',
 			'KERNEL_SIZE_FLOAT': '25.0',
 			'KERNEL_SIZE_INT': '25'
 			'KERNEL_SIZE_INT': '25'
@@ -22,29 +22,49 @@
 				value: []
 				value: []
 			}
 			}
 		},
 		},
-		vertexShader: [ 'uniform vec2 uImageIncrement;', 'varying vec2 vUv;', 'void main() {', '	vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float cKernel[ KERNEL_SIZE_INT ];', 'uniform sampler2D tDiffuse;', 'uniform vec2 uImageIncrement;', 'varying vec2 vUv;', 'void main() {', '	vec2 imageCoord = vUv;', '	vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );', '	for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {', '		sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];', '		imageCoord += uImageIncrement;', '	}', '	gl_FragColor = sum;', '}' ].join( '\n' ),
-		buildKernel: function ( sigma ) {
+		vertexShader: `uniform vec2 uImageIncrement;
 
 
-			// We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway.
-			function gauss( x, sigma ) {
+		varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float cKernel[ KERNEL_SIZE_INT ];
+
+		uniform sampler2D tDiffuse;
+		uniform vec2 uImageIncrement;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec2 imageCoord = vUv;
+			vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );
 
 
-				return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) );
+			for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {
+
+				sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];
+				imageCoord += uImageIncrement;
 
 
 			}
 			}
 
 
-			var i,
-				values,
-				sum,
-				halfWidth,
-				kMaxKernelSize = 25,
-				kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1;
+			gl_FragColor = sum;
+
+		}`,
+		buildKernel: function ( sigma ) {
+
+			// We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway.
+			const kMaxKernelSize = 25;
+			let kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1;
 			if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize;
 			if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize;
-			halfWidth = ( kernelSize - 1 ) * 0.5;
-			values = new Array( kernelSize );
-			sum = 0.0;
+			const halfWidth = ( kernelSize - 1 ) * 0.5;
+			const values = new Array( kernelSize );
+			let sum = 0.0;
 
 
-			for ( i = 0; i < kernelSize; ++ i ) {
+			for ( let i = 0; i < kernelSize; ++ i ) {
 
 
 				values[ i ] = gauss( i - halfWidth, sigma );
 				values[ i ] = gauss( i - halfWidth, sigma );
 				sum += values[ i ];
 				sum += values[ i ];
@@ -52,13 +72,19 @@
 			} // normalize the kernel
 			} // normalize the kernel
 
 
 
 
-			for ( i = 0; i < kernelSize; ++ i ) values[ i ] /= sum;
+			for ( let i = 0; i < kernelSize; ++ i ) values[ i ] /= sum;
 
 
 			return values;
 			return values;
 
 
 		}
 		}
 	};
 	};
 
 
+	function gauss( x, sigma ) {
+
+		return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) );
+
+	}
+
 	THREE.ConvolutionShader = ConvolutionShader;
 	THREE.ConvolutionShader = ConvolutionShader;
 
 
 } )();
 } )();

+ 20 - 2
examples/js/shaders/CopyShader.js

@@ -12,8 +12,26 @@
 				value: 1.0
 				value: 1.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float opacity;', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'void main() {', '	vec4 texel = texture2D( tDiffuse, vUv );', '	gl_FragColor = opacity * texel;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float opacity;
+
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 texel = texture2D( tDiffuse, vUv );
+			gl_FragColor = opacity * texel;
+
+		}`
 	};
 	};
 
 
 	THREE.CopyShader = CopyShader;
 	THREE.CopyShader = CopyShader;

+ 29 - 3
examples/js/shaders/DOFMipMapShader.js

@@ -5,7 +5,7 @@
  * - from Matt Handley @applmak
  * - from Matt Handley @applmak
  * - requires power-of-2 sized render target with enabled mipmaps
  * - requires power-of-2 sized render target with enabled mipmaps
  */
  */
-	var DOFMipMapShader = {
+	const DOFMipMapShader = {
 		uniforms: {
 		uniforms: {
 			'tColor': {
 			'tColor': {
 				value: null
 				value: null
@@ -20,8 +20,34 @@
 				value: 1.0
 				value: 1.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float focus;', 'uniform float maxblur;', 'uniform sampler2D tColor;', 'uniform sampler2D tDepth;', 'varying vec2 vUv;', 'void main() {', '	vec4 depth = texture2D( tDepth, vUv );', '	float factor = depth.x - focus;', '	vec4 col = texture2D( tColor, vUv, 2.0 * maxblur * abs( focus - depth.x ) );', '	gl_FragColor = col;', '	gl_FragColor.a = 1.0;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float focus;
+		uniform float maxblur;
+
+		uniform sampler2D tColor;
+		uniform sampler2D tDepth;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 depth = texture2D( tDepth, vUv );
+
+			float factor = depth.x - focus;
+
+			vec4 col = texture2D( tColor, vUv, 2.0 * maxblur * abs( focus - depth.x ) );
+
+			gl_FragColor = col;
+			gl_FragColor.a = 1.0;
+
+		}`
 	};
 	};
 
 
 	THREE.DOFMipMapShader = DOFMipMapShader;
 	THREE.DOFMipMapShader = DOFMipMapShader;

+ 97 - 13
examples/js/shaders/DepthLimitedBlurShader.js

@@ -4,7 +4,7 @@
  * TODO
  * TODO
  */
  */
 
 
-	var DepthLimitedBlurShader = {
+	const DepthLimitedBlurShader = {
 		defines: {
 		defines: {
 			'KERNEL_RADIUS': 4,
 			'KERNEL_RADIUS': 4,
 			'DEPTH_PACKING': 1,
 			'DEPTH_PACKING': 1,
@@ -36,21 +36,99 @@
 				value: 10
 				value: 10
 			}
 			}
 		},
 		},
-		vertexShader: [ '#include <common>', 'uniform vec2 size;', 'varying vec2 vUv;', 'varying vec2 vInvSize;', 'void main() {', '	vUv = uv;', '	vInvSize = 1.0 / size;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ '#include <common>', '#include <packing>', 'uniform sampler2D tDiffuse;', 'uniform sampler2D tDepth;', 'uniform float cameraNear;', 'uniform float cameraFar;', 'uniform float depthCutoff;', 'uniform vec2 sampleUvOffsets[ KERNEL_RADIUS + 1 ];', 'uniform float sampleWeights[ KERNEL_RADIUS + 1 ];', 'varying vec2 vUv;', 'varying vec2 vInvSize;', 'float getDepth( const in vec2 screenPosition ) {', '	#if DEPTH_PACKING == 1', '	return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );', '	#else', '	return texture2D( tDepth, screenPosition ).x;', '	#endif', '}', 'float getViewZ( const in float depth ) {', '	#if PERSPECTIVE_CAMERA == 1', '	return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );', '	#else', '	return orthographicDepthToViewZ( depth, cameraNear, cameraFar );', '	#endif', '}', 'void main() {', '	float depth = getDepth( vUv );', '	if( depth >= ( 1.0 - EPSILON ) ) {', '		discard;', '	}', '	float centerViewZ = -getViewZ( depth );', '	bool rBreak = false, lBreak = false;', '	float weightSum = sampleWeights[0];', '	vec4 diffuseSum = texture2D( tDiffuse, vUv ) * weightSum;', '	for( int i = 1; i <= KERNEL_RADIUS; i ++ ) {', '		float sampleWeight = sampleWeights[i];', '		vec2 sampleUvOffset = sampleUvOffsets[i] * vInvSize;', '		vec2 sampleUv = vUv + sampleUvOffset;', '		float viewZ = -getViewZ( getDepth( sampleUv ) );', '		if( abs( viewZ - centerViewZ ) > depthCutoff ) rBreak = true;', '		if( ! rBreak ) {', '			diffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;', '			weightSum += sampleWeight;', '		}', '		sampleUv = vUv - sampleUvOffset;', '		viewZ = -getViewZ( getDepth( sampleUv ) );', '		if( abs( viewZ - centerViewZ ) > depthCutoff ) lBreak = true;', '		if( ! lBreak ) {', '			diffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;', '			weightSum += sampleWeight;', '		}', '	}', '	gl_FragColor = diffuseSum / weightSum;', '}' ].join( '\n' )
-	};
-	var BlurShaderUtils = {
-		createSampleWeights: function ( kernelRadius, stdDev ) {
+		vertexShader: `#include <common>
+
+		uniform vec2 size;
+
+		varying vec2 vUv;
+		varying vec2 vInvSize;
+
+		void main() {
+			vUv = uv;
+			vInvSize = 1.0 / size;
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+		}`,
+		fragmentShader: `#include <common>
+		#include <packing>
+
+		uniform sampler2D tDiffuse;
+		uniform sampler2D tDepth;
+
+		uniform float cameraNear;
+		uniform float cameraFar;
+		uniform float depthCutoff;
+
+		uniform vec2 sampleUvOffsets[ KERNEL_RADIUS + 1 ];
+		uniform float sampleWeights[ KERNEL_RADIUS + 1 ];
+
+		varying vec2 vUv;
+		varying vec2 vInvSize;
+
+		float getDepth( const in vec2 screenPosition ) {
+			#if DEPTH_PACKING == 1
+			return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );
+			#else
+			return texture2D( tDepth, screenPosition ).x;
+			#endif
+		}
+
+		float getViewZ( const in float depth ) {
+			#if PERSPECTIVE_CAMERA == 1
+			return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );
+			#else
+			return orthographicDepthToViewZ( depth, cameraNear, cameraFar );
+			#endif
+		}
+
+		void main() {
+			float depth = getDepth( vUv );
+			if( depth >= ( 1.0 - EPSILON ) ) {
+				discard;
+			}
 
 
-			var gaussian = function ( x, stdDev ) {
+			float centerViewZ = -getViewZ( depth );
+			bool rBreak = false, lBreak = false;
 
 
-				return Math.exp( - ( x * x ) / ( 2.0 * ( stdDev * stdDev ) ) ) / ( Math.sqrt( 2.0 * Math.PI ) * stdDev );
+			float weightSum = sampleWeights[0];
+			vec4 diffuseSum = texture2D( tDiffuse, vUv ) * weightSum;
 
 
-			};
+			for( int i = 1; i <= KERNEL_RADIUS; i ++ ) {
 
 
-			var weights = [];
+				float sampleWeight = sampleWeights[i];
+				vec2 sampleUvOffset = sampleUvOffsets[i] * vInvSize;
 
 
-			for ( var i = 0; i <= kernelRadius; i ++ ) {
+				vec2 sampleUv = vUv + sampleUvOffset;
+				float viewZ = -getViewZ( getDepth( sampleUv ) );
+
+				if( abs( viewZ - centerViewZ ) > depthCutoff ) rBreak = true;
+
+				if( ! rBreak ) {
+					diffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;
+					weightSum += sampleWeight;
+				}
+
+				sampleUv = vUv - sampleUvOffset;
+				viewZ = -getViewZ( getDepth( sampleUv ) );
+
+				if( abs( viewZ - centerViewZ ) > depthCutoff ) lBreak = true;
+
+				if( ! lBreak ) {
+					diffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;
+					weightSum += sampleWeight;
+				}
+
+			}
+
+			gl_FragColor = diffuseSum / weightSum;
+		}`
+	};
+	const BlurShaderUtils = {
+		createSampleWeights: function ( kernelRadius, stdDev ) {
+
+			const weights = [];
+
+			for ( let i = 0; i <= kernelRadius; i ++ ) {
 
 
 				weights.push( gaussian( i, stdDev ) );
 				weights.push( gaussian( i, stdDev ) );
 
 
@@ -61,9 +139,9 @@
 		},
 		},
 		createSampleOffsets: function ( kernelRadius, uvIncrement ) {
 		createSampleOffsets: function ( kernelRadius, uvIncrement ) {
 
 
-			var offsets = [];
+			const offsets = [];
 
 
-			for ( var i = 0; i <= kernelRadius; i ++ ) {
+			for ( let i = 0; i <= kernelRadius; i ++ ) {
 
 
 				offsets.push( uvIncrement.clone().multiplyScalar( i ) );
 				offsets.push( uvIncrement.clone().multiplyScalar( i ) );
 
 
@@ -82,6 +160,12 @@
 		}
 		}
 	};
 	};
 
 
+	function gaussian( x, stdDev ) {
+
+		return Math.exp( - ( x * x ) / ( 2.0 * ( stdDev * stdDev ) ) ) / ( Math.sqrt( 2.0 * Math.PI ) * stdDev );
+
+	}
+
 	THREE.BlurShaderUtils = BlurShaderUtils;
 	THREE.BlurShaderUtils = BlurShaderUtils;
 	THREE.DepthLimitedBlurShader = DepthLimitedBlurShader;
 	THREE.DepthLimitedBlurShader = DepthLimitedBlurShader;
 
 

+ 66 - 7
examples/js/shaders/DigitalGlitch.js

@@ -9,7 +9,7 @@
  * amount: shift distance (1 is width of input)
  * amount: shift distance (1 is width of input)
  * angle: shift angle in radians
  * angle: shift angle in radians
  */
  */
-	var DigitalGlitch = {
+	const DigitalGlitch = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -50,12 +50,71 @@
 				value: 0.05
 				value: 0.05
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform int byp;', //should we apply the glitch ?
-			'uniform sampler2D tDiffuse;', 'uniform sampler2D tDisp;', 'uniform float amount;', 'uniform float angle;', 'uniform float seed;', 'uniform float seed_x;', 'uniform float seed_y;', 'uniform float distortion_x;', 'uniform float distortion_y;', 'uniform float col_s;', 'varying vec2 vUv;', 'float rand(vec2 co){', '	return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);', '}', 'void main() {', '	if(byp<1) {', '		vec2 p = vUv;', '		float xs = floor(gl_FragCoord.x / 0.5);', '		float ys = floor(gl_FragCoord.y / 0.5);', //based on staffantans glitch shader for unity https://github.com/staffantan/unityglitch
-			'		vec4 normal = texture2D (tDisp, p*seed*seed);', '		if(p.y<distortion_x+col_s && p.y>distortion_x-col_s*seed) {', '			if(seed_x>0.){', '				p.y = 1. - (p.y + distortion_y);', '			}', '			else {', '				p.y = distortion_y;', '			}', '		}', '		if(p.x<distortion_y+col_s && p.x>distortion_y-col_s*seed) {', '			if(seed_y>0.){', '				p.x=distortion_x;', '			}', '			else {', '				p.x = 1. - (p.x + distortion_x);', '			}', '		}', '		p.x+=normal.x*seed_x*(seed/5.);', '		p.y+=normal.y*seed_y*(seed/5.);', //base from RGB shift shader
-			'		vec2 offset = amount * vec2( cos(angle), sin(angle));', '		vec4 cr = texture2D(tDiffuse, p + offset);', '		vec4 cga = texture2D(tDiffuse, p);', '		vec4 cb = texture2D(tDiffuse, p - offset);', '		gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);', //add noise
-			'		vec4 snow = 200.*amount*vec4(rand(vec2(xs * seed,ys * seed*50.))*0.2);', '		gl_FragColor = gl_FragColor+ snow;', '	}', '	else {', '		gl_FragColor=texture2D (tDiffuse, vUv);', '	}', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+		void main() {
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+		}`,
+		fragmentShader: `uniform int byp; //should we apply the glitch ?
+
+		uniform sampler2D tDiffuse;
+		uniform sampler2D tDisp;
+
+		uniform float amount;
+		uniform float angle;
+		uniform float seed;
+		uniform float seed_x;
+		uniform float seed_y;
+		uniform float distortion_x;
+		uniform float distortion_y;
+		uniform float col_s;
+
+		varying vec2 vUv;
+
+
+		float rand(vec2 co){
+			return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
+		}
+
+		void main() {
+			if(byp<1) {
+				vec2 p = vUv;
+				float xs = floor(gl_FragCoord.x / 0.5);
+				float ys = floor(gl_FragCoord.y / 0.5);
+				//based on staffantans glitch shader for unity https://github.com/staffantan/unityglitch
+				vec4 normal = texture2D (tDisp, p*seed*seed);
+				if(p.y<distortion_x+col_s && p.y>distortion_x-col_s*seed) {
+					if(seed_x>0.){
+						p.y = 1. - (p.y + distortion_y);
+					}
+					else {
+						p.y = distortion_y;
+					}
+				}
+				if(p.x<distortion_y+col_s && p.x>distortion_y-col_s*seed) {
+					if(seed_y>0.){
+						p.x=distortion_x;
+					}
+					else {
+						p.x = 1. - (p.x + distortion_x);
+					}
+				}
+				p.x+=normal.x*seed_x*(seed/5.);
+				p.y+=normal.y*seed_y*(seed/5.);
+				//base from RGB shift shader
+				vec2 offset = amount * vec2( cos(angle), sin(angle));
+				vec4 cr = texture2D(tDiffuse, p + offset);
+				vec4 cga = texture2D(tDiffuse, p);
+				vec4 cb = texture2D(tDiffuse, p - offset);
+				gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);
+				//add noise
+				vec4 snow = 200.*amount*vec4(rand(vec2(xs * seed,ys * seed*50.))*0.2);
+				gl_FragColor = gl_FragColor+ snow;
+			}
+			else {
+				gl_FragColor=texture2D (tDiffuse, vUv);
+			}
+		}`
 	};
 	};
 
 
 	THREE.DigitalGlitch = DigitalGlitch;
 	THREE.DigitalGlitch = DigitalGlitch;

+ 38 - 3
examples/js/shaders/DotScreenShader.js

@@ -6,7 +6,7 @@
  * https://github.com/evanw/glfx.js
  * https://github.com/evanw/glfx.js
  */
  */
 
 
-	var DotScreenShader = {
+	const DotScreenShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -24,8 +24,43 @@
 				value: 1.0
 				value: 1.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform vec2 center;', 'uniform float angle;', 'uniform float scale;', 'uniform vec2 tSize;', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'float pattern() {', '	float s = sin( angle ), c = cos( angle );', '	vec2 tex = vUv * tSize - center;', '	vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;', '	return ( sin( point.x ) * sin( point.y ) ) * 4.0;', '}', 'void main() {', '	vec4 color = texture2D( tDiffuse, vUv );', '	float average = ( color.r + color.g + color.b ) / 3.0;', '	gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform vec2 center;
+		uniform float angle;
+		uniform float scale;
+		uniform vec2 tSize;
+
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		float pattern() {
+
+			float s = sin( angle ), c = cos( angle );
+
+			vec2 tex = vUv * tSize - center;
+			vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;
+
+			return ( sin( point.x ) * sin( point.y ) ) * 4.0;
+
+		}
+
+		void main() {
+
+			vec4 color = texture2D( tDiffuse, vUv );
+
+			float average = ( color.r + color.g + color.b ) / 3.0;
+
+			gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );
+
+		}`
 	};
 	};
 
 
 	THREE.DotScreenShader = DotScreenShader;
 	THREE.DotScreenShader = DotScreenShader;

File diff suppressed because it is too large
+ 1 - 2
examples/js/shaders/FXAAShader.js


+ 59 - 14
examples/js/shaders/FilmShader.js

@@ -19,7 +19,7 @@
  * This version is provided under a Creative Commons Attribution 3.0 License
  * This version is provided under a Creative Commons Attribution 3.0 License
  * http://creativecommons.org/licenses/by/3.0/
  * http://creativecommons.org/licenses/by/3.0/
  */
  */
-	var FilmShader = {
+	const FilmShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -40,19 +40,64 @@
 				value: 1
 				value: 1
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ '#include <common>', // control parameter
-			'uniform float time;', 'uniform bool grayscale;', // noise effect intensity value (0 = no effect, 1 = full effect)
-			'uniform float nIntensity;', // scanlines effect intensity value (0 = no effect, 1 = full effect)
-			'uniform float sIntensity;', // scanlines effect count value (0 = no effect, 4096 = full effect)
-			'uniform float sCount;', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'void main() {', // sample the source
-			'	vec4 cTextureScreen = texture2D( tDiffuse, vUv );', // make some noise
-			'	float dx = rand( vUv + time );', // add noise
-			'	vec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx, 0.0, 1.0 );', // get us a sine and cosine
-			'	vec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );', // add scanlines
-			'	cResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;', // interpolate between source and result by intensity
-			'	cResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );', // convert to grayscale if desired
-			'	if( grayscale ) {', '		cResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );', '	}', '	gl_FragColor =	vec4( cResult, cTextureScreen.a );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `#include <common>
+
+		// control parameter
+		uniform float time;
+
+		uniform bool grayscale;
+
+		// noise effect intensity value (0 = no effect, 1 = full effect)
+		uniform float nIntensity;
+
+		// scanlines effect intensity value (0 = no effect, 1 = full effect)
+		uniform float sIntensity;
+
+		// scanlines effect count value (0 = no effect, 4096 = full effect)
+		uniform float sCount;
+
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		void main() {
+
+		// sample the source
+			vec4 cTextureScreen = texture2D( tDiffuse, vUv );
+
+		// make some noise
+			float dx = rand( vUv + time );
+
+		// add noise
+			vec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx, 0.0, 1.0 );
+
+		// get us a sine and cosine
+			vec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );
+
+		// add scanlines
+			cResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;
+
+		// interpolate between source and result by intensity
+			cResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );
+
+		// convert to grayscale if desired
+			if( grayscale ) {
+
+				cResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );
+
+			}
+
+			gl_FragColor =	vec4( cResult, cTextureScreen.a );
+
+		}`
 	};
 	};
 
 
 	THREE.FilmShader = FilmShader;
 	THREE.FilmShader = FilmShader;

+ 61 - 3
examples/js/shaders/FocusShader.js

@@ -5,7 +5,7 @@
  * based on PaintEffect postprocess from ro.me
  * based on PaintEffect postprocess from ro.me
  * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js
  * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js
  */
  */
-	var FocusShader = {
+	const FocusShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -23,8 +23,66 @@
 				value: 0.00125
 				value: 0.00125
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float screenWidth;', 'uniform float screenHeight;', 'uniform float sampleDistance;', 'uniform float waveFactor;', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'void main() {', '	vec4 color, org, tmp, add;', '	float sample_dist, f;', '	vec2 vin;', '	vec2 uv = vUv;', '	add = color = org = texture2D( tDiffuse, uv );', '	vin = ( uv - vec2( 0.5 ) ) * vec2( 1.4 );', '	sample_dist = dot( vin, vin ) * 2.0;', '	f = ( waveFactor * 100.0 + sample_dist ) * sampleDistance * 4.0;', '	vec2 sampleSize = vec2(	1.0 / screenWidth, 1.0 / screenHeight ) * vec2( f );', '	add += tmp = texture2D( tDiffuse, uv + vec2( 0.111964, 0.993712 ) * sampleSize );', '	if( tmp.b < color.b ) color = tmp;', '	add += tmp = texture2D( tDiffuse, uv + vec2( 0.846724, 0.532032 ) * sampleSize );', '	if( tmp.b < color.b ) color = tmp;', '	add += tmp = texture2D( tDiffuse, uv + vec2( 0.943883, -0.330279 ) * sampleSize );', '	if( tmp.b < color.b ) color = tmp;', '	add += tmp = texture2D( tDiffuse, uv + vec2( 0.330279, -0.943883 ) * sampleSize );', '	if( tmp.b < color.b ) color = tmp;', '	add += tmp = texture2D( tDiffuse, uv + vec2( -0.532032, -0.846724 ) * sampleSize );', '	if( tmp.b < color.b ) color = tmp;', '	add += tmp = texture2D( tDiffuse, uv + vec2( -0.993712, -0.111964 ) * sampleSize );', '	if( tmp.b < color.b ) color = tmp;', '	add += tmp = texture2D( tDiffuse, uv + vec2( -0.707107, 0.707107 ) * sampleSize );', '	if( tmp.b < color.b ) color = tmp;', '	color = color * vec4( 2.0 ) - ( add / vec4( 8.0 ) );', '	color = color + ( add / vec4( 8.0 ) - color ) * ( vec4( 1.0 ) - vec4( sample_dist * 0.5 ) );', '	gl_FragColor = vec4( color.rgb * color.rgb * vec3( 0.95 ) + color.rgb, 1.0 );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float screenWidth;
+		uniform float screenHeight;
+		uniform float sampleDistance;
+		uniform float waveFactor;
+
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 color, org, tmp, add;
+			float sample_dist, f;
+			vec2 vin;
+			vec2 uv = vUv;
+
+			add = color = org = texture2D( tDiffuse, uv );
+
+			vin = ( uv - vec2( 0.5 ) ) * vec2( 1.4 );
+			sample_dist = dot( vin, vin ) * 2.0;
+
+			f = ( waveFactor * 100.0 + sample_dist ) * sampleDistance * 4.0;
+
+			vec2 sampleSize = vec2(	1.0 / screenWidth, 1.0 / screenHeight ) * vec2( f );
+
+			add += tmp = texture2D( tDiffuse, uv + vec2( 0.111964, 0.993712 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
+
+			add += tmp = texture2D( tDiffuse, uv + vec2( 0.846724, 0.532032 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
+
+			add += tmp = texture2D( tDiffuse, uv + vec2( 0.943883, -0.330279 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
+
+			add += tmp = texture2D( tDiffuse, uv + vec2( 0.330279, -0.943883 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
+
+			add += tmp = texture2D( tDiffuse, uv + vec2( -0.532032, -0.846724 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
+
+			add += tmp = texture2D( tDiffuse, uv + vec2( -0.993712, -0.111964 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
+
+			add += tmp = texture2D( tDiffuse, uv + vec2( -0.707107, 0.707107 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
+
+			color = color * vec4( 2.0 ) - ( add / vec4( 8.0 ) );
+			color = color + ( add / vec4( 8.0 ) - color ) * ( vec4( 1.0 ) - vec4( sample_dist * 0.5 ) );
+
+			gl_FragColor = vec4( color.rgb * color.rgb * vec3( 0.95 ) + color.rgb, 1.0 );
+
+		}`
 	};
 	};
 
 
 	THREE.FocusShader = FocusShader;
 	THREE.FocusShader = FocusShader;

+ 66 - 7
examples/js/shaders/FreiChenShader.js

@@ -16,13 +16,72 @@
 				value: new THREE.Vector2( 512, 512 )
 				value: new THREE.Vector2( 512, 512 )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'uniform vec2 aspect;', 'vec2 texel = vec2(1.0 / aspect.x, 1.0 / aspect.y);', 'mat3 G[9];', // hard coded matrix values!!!! as suggested in https://github.com/neilmendoza/ofxPostProcessing/blob/master/src/EdgePass.cpp#L45
-			'const mat3 g0 = mat3( 0.3535533845424652, 0, -0.3535533845424652, 0.5, 0, -0.5, 0.3535533845424652, 0, -0.3535533845424652 );', 'const mat3 g1 = mat3( 0.3535533845424652, 0.5, 0.3535533845424652, 0, 0, 0, -0.3535533845424652, -0.5, -0.3535533845424652 );', 'const mat3 g2 = mat3( 0, 0.3535533845424652, -0.5, -0.3535533845424652, 0, 0.3535533845424652, 0.5, -0.3535533845424652, 0 );', 'const mat3 g3 = mat3( 0.5, -0.3535533845424652, 0, -0.3535533845424652, 0, 0.3535533845424652, 0, 0.3535533845424652, -0.5 );', 'const mat3 g4 = mat3( 0, -0.5, 0, 0.5, 0, 0.5, 0, -0.5, 0 );', 'const mat3 g5 = mat3( -0.5, 0, 0.5, 0, 0, 0, 0.5, 0, -0.5 );', 'const mat3 g6 = mat3( 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.6666666865348816, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204 );', 'const mat3 g7 = mat3( -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, 0.6666666865348816, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408 );', 'const mat3 g8 = mat3( 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408 );', 'void main(void)', '{', '	G[0] = g0,', '	G[1] = g1,', '	G[2] = g2,', '	G[3] = g3,', '	G[4] = g4,', '	G[5] = g5,', '	G[6] = g6,', '	G[7] = g7,', '	G[8] = g8;', '	mat3 I;', '	float cnv[9];', '	vec3 sample;',
-			/* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */
-			'	for (float i=0.0; i<3.0; i++) {', '		for (float j=0.0; j<3.0; j++) {', '			sample = texture2D(tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;', '			I[int(i)][int(j)] = length(sample);', '		}', '	}',
-			/* calculate the convolution values for all the masks */
-			'	for (int i=0; i<9; i++) {', '		float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);', '		cnv[i] = dp3 * dp3;', '	}', '	float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]);', '	float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M);', '	gl_FragColor = vec4(vec3(sqrt(M/S)), 1.0);', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		varying vec2 vUv;
+
+		uniform vec2 aspect;
+
+		vec2 texel = vec2( 1.0 / aspect.x, 1.0 / aspect.y );
+
+
+		mat3 G[9];
+
+		// hard coded matrix values!!!! as suggested in https://github.com/neilmendoza/ofxPostProcessing/blob/master/src/EdgePass.cpp#L45
+
+		const mat3 g0 = mat3( 0.3535533845424652, 0, -0.3535533845424652, 0.5, 0, -0.5, 0.3535533845424652, 0, -0.3535533845424652 );
+		const mat3 g1 = mat3( 0.3535533845424652, 0.5, 0.3535533845424652, 0, 0, 0, -0.3535533845424652, -0.5, -0.3535533845424652 );
+		const mat3 g2 = mat3( 0, 0.3535533845424652, -0.5, -0.3535533845424652, 0, 0.3535533845424652, 0.5, -0.3535533845424652, 0 );
+		const mat3 g3 = mat3( 0.5, -0.3535533845424652, 0, -0.3535533845424652, 0, 0.3535533845424652, 0, 0.3535533845424652, -0.5 );
+		const mat3 g4 = mat3( 0, -0.5, 0, 0.5, 0, 0.5, 0, -0.5, 0 );
+		const mat3 g5 = mat3( -0.5, 0, 0.5, 0, 0, 0, 0.5, 0, -0.5 );
+		const mat3 g6 = mat3( 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.6666666865348816, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204 );
+		const mat3 g7 = mat3( -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, 0.6666666865348816, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408 );
+		const mat3 g8 = mat3( 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408 );
+
+		void main(void)
+		{
+
+			G[0] = g0,
+			G[1] = g1,
+			G[2] = g2,
+			G[3] = g3,
+			G[4] = g4,
+			G[5] = g5,
+			G[6] = g6,
+			G[7] = g7,
+			G[8] = g8;
+
+			mat3 I;
+			float cnv[9];
+			vec3 sample;
+
+		/* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */
+			for (float i=0.0; i<3.0; i++) {
+				for (float j=0.0; j<3.0; j++) {
+					sample = texture2D(tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;
+					I[int(i)][int(j)] = length(sample);
+				}
+			}
+
+		/* calculate the convolution values for all the masks */
+			for (int i=0; i<9; i++) {
+				float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);
+				cnv[i] = dp3 * dp3;
+			}
+
+			float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]);
+			float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M);
+
+			gl_FragColor = vec4(vec3(sqrt(M/S)), 1.0);
+		}`
 	};
 	};
 
 
 	THREE.FreiChenShader = FreiChenShader;
 	THREE.FreiChenShader = FreiChenShader;

+ 46 - 3
examples/js/shaders/FresnelShader.js

@@ -3,7 +3,7 @@
 	/**
 	/**
  * Based on Nvidia Cg tutorial
  * Based on Nvidia Cg tutorial
  */
  */
-	var FresnelShader = {
+	const FresnelShader = {
 		uniforms: {
 		uniforms: {
 			'mRefractionRatio': {
 			'mRefractionRatio': {
 				value: 1.02
 				value: 1.02
@@ -21,8 +21,51 @@
 				value: null
 				value: null
 			}
 			}
 		},
 		},
-		vertexShader: [ 'uniform float mRefractionRatio;', 'uniform float mFresnelBias;', 'uniform float mFresnelScale;', 'uniform float mFresnelPower;', 'varying vec3 vReflect;', 'varying vec3 vRefract[3];', 'varying float vReflectionFactor;', 'void main() {', '	vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );', '	vec4 worldPosition = modelMatrix * vec4( position, 1.0 );', '	vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );', '	vec3 I = worldPosition.xyz - cameraPosition;', '	vReflect = reflect( I, worldNormal );', '	vRefract[0] = refract( normalize( I ), worldNormal, mRefractionRatio );', '	vRefract[1] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.99 );', '	vRefract[2] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.98 );', '	vReflectionFactor = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), mFresnelPower );', '	gl_Position = projectionMatrix * mvPosition;', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform samplerCube tCube;', 'varying vec3 vReflect;', 'varying vec3 vRefract[3];', 'varying float vReflectionFactor;', 'void main() {', '	vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );', '	vec4 refractedColor = vec4( 1.0 );', '	refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;', '	refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;', '	refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;', '	gl_FragColor = mix( refractedColor, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );', '}' ].join( '\n' )
+		vertexShader: `uniform float mRefractionRatio;
+		uniform float mFresnelBias;
+		uniform float mFresnelScale;
+		uniform float mFresnelPower;
+
+		varying vec3 vReflect;
+		varying vec3 vRefract[3];
+		varying float vReflectionFactor;
+
+		void main() {
+
+			vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+			vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
+
+			vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
+
+			vec3 I = worldPosition.xyz - cameraPosition;
+
+			vReflect = reflect( I, worldNormal );
+			vRefract[0] = refract( normalize( I ), worldNormal, mRefractionRatio );
+			vRefract[1] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.99 );
+			vRefract[2] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.98 );
+			vReflectionFactor = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), mFresnelPower );
+
+			gl_Position = projectionMatrix * mvPosition;
+
+		}`,
+		fragmentShader: `uniform samplerCube tCube;
+
+		varying vec3 vReflect;
+		varying vec3 vRefract[3];
+		varying float vReflectionFactor;
+
+		void main() {
+
+			vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );
+			vec4 refractedColor = vec4( 1.0 );
+
+			refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;
+			refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;
+			refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;
+
+			gl_FragColor = mix( refractedColor, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );
+
+		}`
 	};
 	};
 
 
 	THREE.FresnelShader = FresnelShader;
 	THREE.FresnelShader = FresnelShader;

+ 20 - 4
examples/js/shaders/GammaCorrectionShader.js

@@ -4,15 +4,31 @@
  * Gamma Correction Shader
  * Gamma Correction Shader
  * http://en.wikipedia.org/wiki/gamma_correction
  * http://en.wikipedia.org/wiki/gamma_correction
  */
  */
-	var GammaCorrectionShader = {
+	const GammaCorrectionShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'void main() {', '	vec4 tex = texture2D( tDiffuse, vUv );', '	gl_FragColor = LinearTosRGB( tex );', // optional: LinearToGamma( tex, float( GAMMA_FACTOR ) );
-			'}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 tex = texture2D( tDiffuse, vUv );
+
+			gl_FragColor = LinearTosRGB( tex ); // optional: LinearToGamma( tex, float( GAMMA_FACTOR ) );
+
+		}`
 	};
 	};
 
 
 	THREE.GammaCorrectionShader = GammaCorrectionShader;
 	THREE.GammaCorrectionShader = GammaCorrectionShader;

+ 163 - 40
examples/js/shaders/GodRaysShader.js

@@ -18,14 +18,29 @@
  * Sousa2008 - Crysis Next Gen Effects, GDC2008, http://www.crytek.com/sites/default/files/GDC08_SousaT_CrysisEffects.ppt
  * Sousa2008 - Crysis Next Gen Effects, GDC2008, http://www.crytek.com/sites/default/files/GDC08_SousaT_CrysisEffects.ppt
  */
  */
 
 
-	var GodRaysDepthMaskShader = {
+	const GodRaysDepthMaskShader = {
 		uniforms: {
 		uniforms: {
 			tInput: {
 			tInput: {
 				value: null
 				value: null
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', ' vUv = uv;', ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'varying vec2 vUv;', 'uniform sampler2D tInput;', 'void main() {', '	gl_FragColor = vec4( 1.0 ) - texture2D( tInput, vUv );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+		 vUv = uv;
+		 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+	 }`,
+		fragmentShader: `varying vec2 vUv;
+
+		uniform sampler2D tInput;
+
+		void main() {
+
+			gl_FragColor = vec4( 1.0 ) - texture2D( tInput, vUv );
+
+		}`
 	};
 	};
 	/**
 	/**
  * The god-ray generation shader.
  * The god-ray generation shader.
@@ -42,7 +57,7 @@
  * decreased distance between samples.
  * decreased distance between samples.
  */
  */
 
 
-	var GodRaysGenerateShader = {
+	const GodRaysGenerateShader = {
 		uniforms: {
 		uniforms: {
 			tInput: {
 			tInput: {
 				value: null
 				value: null
@@ -54,44 +69,104 @@
 				value: new THREE.Vector3()
 				value: new THREE.Vector3()
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', ' vUv = uv;', ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ '#define TAPS_PER_PASS 6.0', 'varying vec2 vUv;', 'uniform sampler2D tInput;', 'uniform vec3 vSunPositionScreenSpace;', 'uniform float fStepSize;', // filter step size
-			'void main() {', // delta from current pixel to "sun" position
-			'	vec2 delta = vSunPositionScreenSpace.xy - vUv;', '	float dist = length( delta );', // Step vector (uv space)
-			'	vec2 stepv = fStepSize * delta / dist;', // Number of iterations between pixel and sun
-			'	float iters = dist/fStepSize;', '	vec2 uv = vUv.xy;', '	float col = 0.0;', // This breaks ANGLE in Chrome 22
-			//	- see http://code.google.com/p/chromium/issues/detail?id=153105
-
-			/*
-	// Unrolling didnt do much on my hardware (ATI Mobility Radeon 3450),
-	// so i've just left the loop
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+		 vUv = uv;
+		 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+	 }`,
+		fragmentShader: `#define TAPS_PER_PASS 6.0
+
+		varying vec2 vUv;
+
+		uniform sampler2D tInput;
+
+		uniform vec3 vSunPositionScreenSpace;
+		uniform float fStepSize; // filter step size
+
+		void main() {
+
+		// delta from current pixel to "sun" position
+
+			vec2 delta = vSunPositionScreenSpace.xy - vUv;
+			float dist = length( delta );
+
+		// Step vector (uv space)
+
+			vec2 stepv = fStepSize * delta / dist;
+
+		// Number of iterations between pixel and sun
+
+			float iters = dist/fStepSize;
+
+			vec2 uv = vUv.xy;
+			float col = 0.0;
+
+		// This breaks ANGLE in Chrome 22
+		//	- see http://code.google.com/p/chromium/issues/detail?id=153105
+
+		/*
+		// Unrolling didnt do much on my hardware (ATI Mobility Radeon 3450),
+		// so i've just left the loop
+
 		"for ( float i = 0.0; i < TAPS_PER_PASS; i += 1.0 ) {",
 		"for ( float i = 0.0; i < TAPS_PER_PASS; i += 1.0 ) {",
+
 		// Accumulate samples, making sure we dont walk past the light source.
 		// Accumulate samples, making sure we dont walk past the light source.
+
 		// The check for uv.y < 1 would not be necessary with "border" UV wrap
 		// The check for uv.y < 1 would not be necessary with "border" UV wrap
-	// mode, with a black border color. I don't think this is currently
-	// exposed by three.js. As a result there might be artifacts when the
-	// sun is to the left, right or bottom of screen as these cases are
-	// not specifically handled.
+		// mode, with a black border color. I don't think this is currently
+		// exposed by three.js. As a result there might be artifacts when the
+		// sun is to the left, right or bottom of screen as these cases are
+		// not specifically handled.
+
 		"	col += ( i <= iters && uv.y < 1.0 ? texture2D( tInput, uv ).r : 0.0 );",
 		"	col += ( i <= iters && uv.y < 1.0 ? texture2D( tInput, uv ).r : 0.0 );",
-	"	uv += stepv;",
+		"	uv += stepv;",
+
 		"}",
 		"}",
-	*/
-			// Unrolling loop manually makes it work in ANGLE
-			'	float f = min( 1.0, max( vSunPositionScreenSpace.z / 1000.0, 0.0 ) );', // used to fade out godrays
-			'	if ( 0.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;', '	uv += stepv;', '	if ( 1.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;', '	uv += stepv;', '	if ( 2.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;', '	uv += stepv;', '	if ( 3.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;', '	uv += stepv;', '	if ( 4.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;', '	uv += stepv;', '	if ( 5.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;', '	uv += stepv;', // Should technically be dividing by 'iters', but 'TAPS_PER_PASS' smooths out
-			// objectionable artifacts, in particular near the sun position. The side
-			// effect is that the result is darker than it should be around the sun, as
-			// TAPS_PER_PASS is greater than the number of samples actually accumulated.
-			// When the result is inverted (in the shader 'godrays_combine', this produces
-			// a slight bright spot at the position of the sun, even when it is occluded.
-			'	gl_FragColor = vec4( col/TAPS_PER_PASS );', '	gl_FragColor.a = 1.0;', '}' ].join( '\n' )
+		*/
+
+		// Unrolling loop manually makes it work in ANGLE
+
+			float f = min( 1.0, max( vSunPositionScreenSpace.z / 1000.0, 0.0 ) ); // used to fade out godrays
+
+			if ( 0.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
+
+			if ( 1.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
+
+			if ( 2.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
+
+			if ( 3.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
+
+			if ( 4.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
+
+			if ( 5.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
+
+		// Should technically be dividing by 'iters but 'TAPS_PER_PASS' smooths out
+		// objectionable artifacts, in particular near the sun position. The side
+		// effect is that the result is darker than it should be around the sun, as
+		// TAPS_PER_PASS is greater than the number of samples actually accumulated.
+		// When the result is inverted (in the shader 'godrays_combine this produces
+		// a slight bright spot at the position of the sun, even when it is occluded.
+
+			gl_FragColor = vec4( col/TAPS_PER_PASS );
+			gl_FragColor.a = 1.0;
+
+		}`
 	};
 	};
 	/**
 	/**
  * Additively applies god rays from texture tGodRays to a background (tColors).
  * Additively applies god rays from texture tGodRays to a background (tColors).
  * fGodRayIntensity attenuates the god rays.
  * fGodRayIntensity attenuates the god rays.
  */
  */
 
 
-	var GodRaysCombineShader = {
+	const GodRaysCombineShader = {
 		uniforms: {
 		uniforms: {
 			tColors: {
 			tColors: {
 				value: null
 				value: null
@@ -103,18 +178,38 @@
 				value: 0.69
 				value: 0.69
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'varying vec2 vUv;', 'uniform sampler2D tColors;', 'uniform sampler2D tGodRays;', 'uniform float fGodRayIntensity;', 'void main() {', // Since THREE.MeshDepthMaterial renders foreground objects white and background
-			// objects black, the god-rays will be white streaks. Therefore value is inverted
-			// before being combined with tColors
-			'	gl_FragColor = texture2D( tColors, vUv ) + fGodRayIntensity * vec4( 1.0 - texture2D( tGodRays, vUv ).r );', '	gl_FragColor.a = 1.0;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `varying vec2 vUv;
+
+		uniform sampler2D tColors;
+		uniform sampler2D tGodRays;
+
+		uniform float fGodRayIntensity;
+
+		void main() {
+
+		// Since THREE.MeshDepthMaterial renders foreground objects white and background
+		// objects black, the god-rays will be white streaks. Therefore value is inverted
+		// before being combined with tColors
+
+			gl_FragColor = texture2D( tColors, vUv ) + fGodRayIntensity * vec4( 1.0 - texture2D( tGodRays, vUv ).r );
+			gl_FragColor.a = 1.0;
+
+		}`
 	};
 	};
 	/**
 	/**
  * A dodgy sun/sky shader. Makes a bright spot at the sun location. Would be
  * A dodgy sun/sky shader. Makes a bright spot at the sun location. Would be
  * cheaper/faster/simpler to implement this as a simple sun sprite.
  * cheaper/faster/simpler to implement this as a simple sun sprite.
  */
  */
 
 
-	var GodRaysFakeSunShader = {
+	const GodRaysFakeSunShader = {
 		uniforms: {
 		uniforms: {
 			vSunPositionScreenSpace: {
 			vSunPositionScreenSpace: {
 				value: new THREE.Vector3()
 				value: new THREE.Vector3()
@@ -129,9 +224,37 @@
 				value: new THREE.Color( 0x000000 )
 				value: new THREE.Color( 0x000000 )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'varying vec2 vUv;', 'uniform vec3 vSunPositionScreenSpace;', 'uniform float fAspect;', 'uniform vec3 sunColor;', 'uniform vec3 bgColor;', 'void main() {', '	vec2 diff = vUv - vSunPositionScreenSpace.xy;', // Correct for aspect ratio
-			'	diff.x *= fAspect;', '	float prop = clamp( length( diff ) / 0.5, 0.0, 1.0 );', '	prop = 0.35 * pow( 1.0 - prop, 3.0 );', '	gl_FragColor.xyz = ( vSunPositionScreenSpace.z > 0.0 ) ? mix( sunColor, bgColor, 1.0 - prop ) : bgColor;', '	gl_FragColor.w = 1.0;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `varying vec2 vUv;
+
+		uniform vec3 vSunPositionScreenSpace;
+		uniform float fAspect;
+
+		uniform vec3 sunColor;
+		uniform vec3 bgColor;
+
+		void main() {
+
+			vec2 diff = vUv - vSunPositionScreenSpace.xy;
+
+		// Correct for aspect ratio
+
+			diff.x *= fAspect;
+
+			float prop = clamp( length( diff ) / 0.5, 0.0, 1.0 );
+			prop = 0.35 * pow( 1.0 - prop, 3.0 );
+
+			gl_FragColor.xyz = ( vSunPositionScreenSpace.z > 0.0 ) ? mix( sunColor, bgColor, 1.0 - prop ) : bgColor;
+			gl_FragColor.w = 1.0;
+
+		}`
 	};
 	};
 
 
 	THREE.GodRaysCombineShader = GodRaysCombineShader;
 	THREE.GodRaysCombineShader = GodRaysCombineShader;

+ 277 - 19
examples/js/shaders/HalftoneShader.js

@@ -6,7 +6,7 @@
  * 		Shape (1 = Dot, 2 = Ellipse, 3 = Line, 4 = Square)
  * 		Shape (1 = Dot, 2 = Ellipse, 3 = Line, 4 = Square)
  *		Blending Mode (1 = Linear, 2 = Multiply, 3 = Add, 4 = Lighter, 5 = Darker)
  *		Blending Mode (1 = Linear, 2 = Multiply, 3 = Add, 4 = Lighter, 5 = Darker)
  */
  */
-	var HalftoneShader = {
+	const HalftoneShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -48,24 +48,282 @@
 				value: false
 				value: false
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUV;', 'void main() {', '	vUV = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);', '}' ].join( '\n' ),
-		fragmentShader: [ '#define SQRT2_MINUS_ONE 0.41421356', '#define SQRT2_HALF_MINUS_ONE 0.20710678', '#define PI2 6.28318531', '#define SHAPE_DOT 1', '#define SHAPE_ELLIPSE 2', '#define SHAPE_LINE 3', '#define SHAPE_SQUARE 4', '#define BLENDING_LINEAR 1', '#define BLENDING_MULTIPLY 2', '#define BLENDING_ADD 3', '#define BLENDING_LIGHTER 4', '#define BLENDING_DARKER 5', 'uniform sampler2D tDiffuse;', 'uniform float radius;', 'uniform float rotateR;', 'uniform float rotateG;', 'uniform float rotateB;', 'uniform float scatter;', 'uniform float width;', 'uniform float height;', 'uniform int shape;', 'uniform bool disable;', 'uniform float blending;', 'uniform int blendingMode;', 'varying vec2 vUV;', 'uniform bool greyscale;', 'const int samples = 8;', 'float blend( float a, float b, float t ) {', // linear blend
-			'	return a * ( 1.0 - t ) + b * t;', '}', 'float hypot( float x, float y ) {', // vector magnitude
-			'	return sqrt( x * x + y * y );', '}', 'float rand( vec2 seed ){', // get pseudo-random number
-			'return fract( sin( dot( seed.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );', '}', 'float distanceToDotRadius( float channel, vec2 coord, vec2 normal, vec2 p, float angle, float rad_max ) {', // apply shape-specific transforms
-			'	float dist = hypot( coord.x - p.x, coord.y - p.y );', '	float rad = channel;', '	if ( shape == SHAPE_DOT ) {', '		rad = pow( abs( rad ), 1.125 ) * rad_max;', '	} else if ( shape == SHAPE_ELLIPSE ) {', '		rad = pow( abs( rad ), 1.125 ) * rad_max;', '		if ( dist != 0.0 ) {', '			float dot_p = abs( ( p.x - coord.x ) / dist * normal.x + ( p.y - coord.y ) / dist * normal.y );', '			dist = ( dist * ( 1.0 - SQRT2_HALF_MINUS_ONE ) ) + dot_p * dist * SQRT2_MINUS_ONE;', '		}', '	} else if ( shape == SHAPE_LINE ) {', '		rad = pow( abs( rad ), 1.5) * rad_max;', '		float dot_p = ( p.x - coord.x ) * normal.x + ( p.y - coord.y ) * normal.y;', '		dist = hypot( normal.x * dot_p, normal.y * dot_p );', '	} else if ( shape == SHAPE_SQUARE ) {', '		float theta = atan( p.y - coord.y, p.x - coord.x ) - angle;', '		float sin_t = abs( sin( theta ) );', '		float cos_t = abs( cos( theta ) );', '		rad = pow( abs( rad ), 1.4 );', '		rad = rad_max * ( rad + ( ( sin_t > cos_t ) ? rad - sin_t * rad : rad - cos_t * rad ) );', '	}', '	return rad - dist;', '}', 'struct Cell {', // grid sample positions
-			'	vec2 normal;', '	vec2 p1;', '	vec2 p2;', '	vec2 p3;', '	vec2 p4;', '	float samp2;', '	float samp1;', '	float samp3;', '	float samp4;', '};', 'vec4 getSample( vec2 point ) {', // multi-sampled point
-			'	vec4 tex = texture2D( tDiffuse, vec2( point.x / width, point.y / height ) );', '	float base = rand( vec2( floor( point.x ), floor( point.y ) ) ) * PI2;', '	float step = PI2 / float( samples );', '	float dist = radius * 0.66;', '	for ( int i = 0; i < samples; ++i ) {', '		float r = base + step * float( i );', '		vec2 coord = point + vec2( cos( r ) * dist, sin( r ) * dist );', '		tex += texture2D( tDiffuse, vec2( coord.x / width, coord.y / height ) );', '	}', '	tex /= float( samples ) + 1.0;', '	return tex;', '}', 'float getDotColour( Cell c, vec2 p, int channel, float angle, float aa ) {', // get colour for given point
-			'	float dist_c_1, dist_c_2, dist_c_3, dist_c_4, res;', '	if ( channel == 0 ) {', '		c.samp1 = getSample( c.p1 ).r;', '		c.samp2 = getSample( c.p2 ).r;', '		c.samp3 = getSample( c.p3 ).r;', '		c.samp4 = getSample( c.p4 ).r;', '	} else if (channel == 1) {', '		c.samp1 = getSample( c.p1 ).g;', '		c.samp2 = getSample( c.p2 ).g;', '		c.samp3 = getSample( c.p3 ).g;', '		c.samp4 = getSample( c.p4 ).g;', '	} else {', '		c.samp1 = getSample( c.p1 ).b;', '		c.samp3 = getSample( c.p3 ).b;', '		c.samp2 = getSample( c.p2 ).b;', '		c.samp4 = getSample( c.p4 ).b;', '	}', '	dist_c_1 = distanceToDotRadius( c.samp1, c.p1, c.normal, p, angle, radius );', '	dist_c_2 = distanceToDotRadius( c.samp2, c.p2, c.normal, p, angle, radius );', '	dist_c_3 = distanceToDotRadius( c.samp3, c.p3, c.normal, p, angle, radius );', '	dist_c_4 = distanceToDotRadius( c.samp4, c.p4, c.normal, p, angle, radius );', '	res = ( dist_c_1 > 0.0 ) ? clamp( dist_c_1 / aa, 0.0, 1.0 ) : 0.0;', '	res += ( dist_c_2 > 0.0 ) ? clamp( dist_c_2 / aa, 0.0, 1.0 ) : 0.0;', '	res += ( dist_c_3 > 0.0 ) ? clamp( dist_c_3 / aa, 0.0, 1.0 ) : 0.0;', '	res += ( dist_c_4 > 0.0 ) ? clamp( dist_c_4 / aa, 0.0, 1.0 ) : 0.0;', '	res = clamp( res, 0.0, 1.0 );', '	return res;', '}', 'Cell getReferenceCell( vec2 p, vec2 origin, float grid_angle, float step ) {', // get containing cell
-			'	Cell c;', // calc grid
-			'	vec2 n = vec2( cos( grid_angle ), sin( grid_angle ) );', '	float threshold = step * 0.5;', '	float dot_normal = n.x * ( p.x - origin.x ) + n.y * ( p.y - origin.y );', '	float dot_line = -n.y * ( p.x - origin.x ) + n.x * ( p.y - origin.y );', '	vec2 offset = vec2( n.x * dot_normal, n.y * dot_normal );', '	float offset_normal = mod( hypot( offset.x, offset.y ), step );', '	float normal_dir = ( dot_normal < 0.0 ) ? 1.0 : -1.0;', '	float normal_scale = ( ( offset_normal < threshold ) ? -offset_normal : step - offset_normal ) * normal_dir;', '	float offset_line = mod( hypot( ( p.x - offset.x ) - origin.x, ( p.y - offset.y ) - origin.y ), step );', '	float line_dir = ( dot_line < 0.0 ) ? 1.0 : -1.0;', '	float line_scale = ( ( offset_line < threshold ) ? -offset_line : step - offset_line ) * line_dir;', // get closest corner
-			'	c.normal = n;', '	c.p1.x = p.x - n.x * normal_scale + n.y * line_scale;', '	c.p1.y = p.y - n.y * normal_scale - n.x * line_scale;', // scatter
-			'	if ( scatter != 0.0 ) {', '		float off_mag = scatter * threshold * 0.5;', '		float off_angle = rand( vec2( floor( c.p1.x ), floor( c.p1.y ) ) ) * PI2;', '		c.p1.x += cos( off_angle ) * off_mag;', '		c.p1.y += sin( off_angle ) * off_mag;', '	}', // find corners
-			'	float normal_step = normal_dir * ( ( offset_normal < threshold ) ? step : -step );', '	float line_step = line_dir * ( ( offset_line < threshold ) ? step : -step );', '	c.p2.x = c.p1.x - n.x * normal_step;', '	c.p2.y = c.p1.y - n.y * normal_step;', '	c.p3.x = c.p1.x + n.y * line_step;', '	c.p3.y = c.p1.y - n.x * line_step;', '	c.p4.x = c.p1.x - n.x * normal_step + n.y * line_step;', '	c.p4.y = c.p1.y - n.y * normal_step - n.x * line_step;', '	return c;', '}', 'float blendColour( float a, float b, float t ) {', // blend colours
-			'	if ( blendingMode == BLENDING_LINEAR ) {', '		return blend( a, b, 1.0 - t );', '	} else if ( blendingMode == BLENDING_ADD ) {', '		return blend( a, min( 1.0, a + b ), t );', '	} else if ( blendingMode == BLENDING_MULTIPLY ) {', '		return blend( a, max( 0.0, a * b ), t );', '	} else if ( blendingMode == BLENDING_LIGHTER ) {', '		return blend( a, max( a, b ), t );', '	} else if ( blendingMode == BLENDING_DARKER ) {', '		return blend( a, min( a, b ), t );', '	} else {', '		return blend( a, b, 1.0 - t );', '	}', '}', 'void main() {', '	if ( ! disable ) {', // setup
-			'		vec2 p = vec2( vUV.x * width, vUV.y * height );', '		vec2 origin = vec2( 0, 0 );', '		float aa = ( radius < 2.5 ) ? radius * 0.5 : 1.25;', // get channel samples
-			'		Cell cell_r = getReferenceCell( p, origin, rotateR, radius );', '		Cell cell_g = getReferenceCell( p, origin, rotateG, radius );', '		Cell cell_b = getReferenceCell( p, origin, rotateB, radius );', '		float r = getDotColour( cell_r, p, 0, rotateR, aa );', '		float g = getDotColour( cell_g, p, 1, rotateG, aa );', '		float b = getDotColour( cell_b, p, 2, rotateB, aa );', // blend with original
-			'		vec4 colour = texture2D( tDiffuse, vUV );', '		r = blendColour( r, colour.r, blending );', '		g = blendColour( g, colour.g, blending );', '		b = blendColour( b, colour.b, blending );', '		if ( greyscale ) {', '			r = g = b = (r + b + g) / 3.0;', '		}', '		gl_FragColor = vec4( r, g, b, 1.0 );', '	} else {', '		gl_FragColor = texture2D( tDiffuse, vUV );', '	}', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUV;
+
+		void main() {
+
+			vUV = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
+
+		}`,
+		fragmentShader: `#define SQRT2_MINUS_ONE 0.41421356
+		#define SQRT2_HALF_MINUS_ONE 0.20710678
+		#define PI2 6.28318531
+		#define SHAPE_DOT 1
+		#define SHAPE_ELLIPSE 2
+		#define SHAPE_LINE 3
+		#define SHAPE_SQUARE 4
+		#define BLENDING_LINEAR 1
+		#define BLENDING_MULTIPLY 2
+		#define BLENDING_ADD 3
+		#define BLENDING_LIGHTER 4
+		#define BLENDING_DARKER 5
+		uniform sampler2D tDiffuse;
+		uniform float radius;
+		uniform float rotateR;
+		uniform float rotateG;
+		uniform float rotateB;
+		uniform float scatter;
+		uniform float width;
+		uniform float height;
+		uniform int shape;
+		uniform bool disable;
+		uniform float blending;
+		uniform int blendingMode;
+		varying vec2 vUV;
+		uniform bool greyscale;
+		const int samples = 8;
+
+		float blend( float a, float b, float t ) {
+
+		// linear blend
+			return a * ( 1.0 - t ) + b * t;
+
+		}
+
+		float hypot( float x, float y ) {
+
+		// vector magnitude
+			return sqrt( x * x + y * y );
+
+		}
+
+		float rand( vec2 seed ){
+
+		// get pseudo-random number
+			return fract( sin( dot( seed.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );
+
+		}
+
+		float distanceToDotRadius( float channel, vec2 coord, vec2 normal, vec2 p, float angle, float rad_max ) {
+
+		// apply shape-specific transforms
+			float dist = hypot( coord.x - p.x, coord.y - p.y );
+			float rad = channel;
+
+			if ( shape == SHAPE_DOT ) {
+
+				rad = pow( abs( rad ), 1.125 ) * rad_max;
+
+			} else if ( shape == SHAPE_ELLIPSE ) {
+
+				rad = pow( abs( rad ), 1.125 ) * rad_max;
+
+				if ( dist != 0.0 ) {
+					float dot_p = abs( ( p.x - coord.x ) / dist * normal.x + ( p.y - coord.y ) / dist * normal.y );
+					dist = ( dist * ( 1.0 - SQRT2_HALF_MINUS_ONE ) ) + dot_p * dist * SQRT2_MINUS_ONE;
+				}
+
+			} else if ( shape == SHAPE_LINE ) {
+
+				rad = pow( abs( rad ), 1.5) * rad_max;
+				float dot_p = ( p.x - coord.x ) * normal.x + ( p.y - coord.y ) * normal.y;
+				dist = hypot( normal.x * dot_p, normal.y * dot_p );
+
+			} else if ( shape == SHAPE_SQUARE ) {
+
+				float theta = atan( p.y - coord.y, p.x - coord.x ) - angle;
+				float sin_t = abs( sin( theta ) );
+				float cos_t = abs( cos( theta ) );
+				rad = pow( abs( rad ), 1.4 );
+				rad = rad_max * ( rad + ( ( sin_t > cos_t ) ? rad - sin_t * rad : rad - cos_t * rad ) );
+
+			}
+
+			return rad - dist;
+
+		}
+
+		struct Cell {
+
+		// grid sample positions
+			vec2 normal;
+			vec2 p1;
+			vec2 p2;
+			vec2 p3;
+			vec2 p4;
+			float samp2;
+			float samp1;
+			float samp3;
+			float samp4;
+
+		};
+
+		vec4 getSample( vec2 point ) {
+
+		// multi-sampled point
+			vec4 tex = texture2D( tDiffuse, vec2( point.x / width, point.y / height ) );
+			float base = rand( vec2( floor( point.x ), floor( point.y ) ) ) * PI2;
+			float step = PI2 / float( samples );
+			float dist = radius * 0.66;
+
+			for ( int i = 0; i < samples; ++i ) {
+
+				float r = base + step * float( i );
+				vec2 coord = point + vec2( cos( r ) * dist, sin( r ) * dist );
+				tex += texture2D( tDiffuse, vec2( coord.x / width, coord.y / height ) );
+
+			}
+
+			tex /= float( samples ) + 1.0;
+			return tex;
+
+		}
+
+		float getDotColour( Cell c, vec2 p, int channel, float angle, float aa ) {
+
+		// get colour for given point
+			float dist_c_1, dist_c_2, dist_c_3, dist_c_4, res;
+
+			if ( channel == 0 ) {
+
+				c.samp1 = getSample( c.p1 ).r;
+				c.samp2 = getSample( c.p2 ).r;
+				c.samp3 = getSample( c.p3 ).r;
+				c.samp4 = getSample( c.p4 ).r;
+
+			} else if (channel == 1) {
+
+				c.samp1 = getSample( c.p1 ).g;
+				c.samp2 = getSample( c.p2 ).g;
+				c.samp3 = getSample( c.p3 ).g;
+				c.samp4 = getSample( c.p4 ).g;
+
+			} else {
+
+				c.samp1 = getSample( c.p1 ).b;
+				c.samp3 = getSample( c.p3 ).b;
+				c.samp2 = getSample( c.p2 ).b;
+				c.samp4 = getSample( c.p4 ).b;
+
+			}
+
+			dist_c_1 = distanceToDotRadius( c.samp1, c.p1, c.normal, p, angle, radius );
+			dist_c_2 = distanceToDotRadius( c.samp2, c.p2, c.normal, p, angle, radius );
+			dist_c_3 = distanceToDotRadius( c.samp3, c.p3, c.normal, p, angle, radius );
+			dist_c_4 = distanceToDotRadius( c.samp4, c.p4, c.normal, p, angle, radius );
+			res = ( dist_c_1 > 0.0 ) ? clamp( dist_c_1 / aa, 0.0, 1.0 ) : 0.0;
+			res += ( dist_c_2 > 0.0 ) ? clamp( dist_c_2 / aa, 0.0, 1.0 ) : 0.0;
+			res += ( dist_c_3 > 0.0 ) ? clamp( dist_c_3 / aa, 0.0, 1.0 ) : 0.0;
+			res += ( dist_c_4 > 0.0 ) ? clamp( dist_c_4 / aa, 0.0, 1.0 ) : 0.0;
+			res = clamp( res, 0.0, 1.0 );
+
+			return res;
+
+		}
+
+		Cell getReferenceCell( vec2 p, vec2 origin, float grid_angle, float step ) {
+
+		// get containing cell
+			Cell c;
+
+		// calc grid
+			vec2 n = vec2( cos( grid_angle ), sin( grid_angle ) );
+			float threshold = step * 0.5;
+			float dot_normal = n.x * ( p.x - origin.x ) + n.y * ( p.y - origin.y );
+			float dot_line = -n.y * ( p.x - origin.x ) + n.x * ( p.y - origin.y );
+			vec2 offset = vec2( n.x * dot_normal, n.y * dot_normal );
+			float offset_normal = mod( hypot( offset.x, offset.y ), step );
+			float normal_dir = ( dot_normal < 0.0 ) ? 1.0 : -1.0;
+			float normal_scale = ( ( offset_normal < threshold ) ? -offset_normal : step - offset_normal ) * normal_dir;
+			float offset_line = mod( hypot( ( p.x - offset.x ) - origin.x, ( p.y - offset.y ) - origin.y ), step );
+			float line_dir = ( dot_line < 0.0 ) ? 1.0 : -1.0;
+			float line_scale = ( ( offset_line < threshold ) ? -offset_line : step - offset_line ) * line_dir;
+
+		// get closest corner
+			c.normal = n;
+			c.p1.x = p.x - n.x * normal_scale + n.y * line_scale;
+			c.p1.y = p.y - n.y * normal_scale - n.x * line_scale;
+
+		// scatter
+			if ( scatter != 0.0 ) {
+
+				float off_mag = scatter * threshold * 0.5;
+				float off_angle = rand( vec2( floor( c.p1.x ), floor( c.p1.y ) ) ) * PI2;
+				c.p1.x += cos( off_angle ) * off_mag;
+				c.p1.y += sin( off_angle ) * off_mag;
+
+			}
+
+		// find corners
+			float normal_step = normal_dir * ( ( offset_normal < threshold ) ? step : -step );
+			float line_step = line_dir * ( ( offset_line < threshold ) ? step : -step );
+			c.p2.x = c.p1.x - n.x * normal_step;
+			c.p2.y = c.p1.y - n.y * normal_step;
+			c.p3.x = c.p1.x + n.y * line_step;
+			c.p3.y = c.p1.y - n.x * line_step;
+			c.p4.x = c.p1.x - n.x * normal_step + n.y * line_step;
+			c.p4.y = c.p1.y - n.y * normal_step - n.x * line_step;
+
+			return c;
+
+		}
+
+		float blendColour( float a, float b, float t ) {
+
+		// blend colours
+			if ( blendingMode == BLENDING_LINEAR ) {
+				return blend( a, b, 1.0 - t );
+			} else if ( blendingMode == BLENDING_ADD ) {
+				return blend( a, min( 1.0, a + b ), t );
+			} else if ( blendingMode == BLENDING_MULTIPLY ) {
+				return blend( a, max( 0.0, a * b ), t );
+			} else if ( blendingMode == BLENDING_LIGHTER ) {
+				return blend( a, max( a, b ), t );
+			} else if ( blendingMode == BLENDING_DARKER ) {
+				return blend( a, min( a, b ), t );
+			} else {
+				return blend( a, b, 1.0 - t );
+			}
+
+		}
+
+		void main() {
+
+			if ( ! disable ) {
+
+		// setup
+				vec2 p = vec2( vUV.x * width, vUV.y * height );
+				vec2 origin = vec2( 0, 0 );
+				float aa = ( radius < 2.5 ) ? radius * 0.5 : 1.25;
+
+		// get channel samples
+				Cell cell_r = getReferenceCell( p, origin, rotateR, radius );
+				Cell cell_g = getReferenceCell( p, origin, rotateG, radius );
+				Cell cell_b = getReferenceCell( p, origin, rotateB, radius );
+				float r = getDotColour( cell_r, p, 0, rotateR, aa );
+				float g = getDotColour( cell_g, p, 1, rotateG, aa );
+				float b = getDotColour( cell_b, p, 2, rotateB, aa );
+
+		// blend with original
+				vec4 colour = texture2D( tDiffuse, vUV );
+				r = blendColour( r, colour.r, blending );
+				g = blendColour( g, colour.g, blending );
+				b = blendColour( b, colour.b, blending );
+
+				if ( greyscale ) {
+					r = g = b = (r + b + g) / 3.0;
+				}
+
+				gl_FragColor = vec4( r, g, b, 1.0 );
+
+			} else {
+
+				gl_FragColor = texture2D( tDiffuse, vUV );
+
+			}
+
+		}`
 	};
 	};
 
 
 	THREE.HalftoneShader = HalftoneShader;
 	THREE.HalftoneShader = HalftoneShader;

+ 30 - 2
examples/js/shaders/HorizontalBlurShader.js

@@ -18,8 +18,36 @@
 				value: 1.0 / 512.0
 				value: 1.0 / 512.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform float h;', 'varying vec2 vUv;', 'void main() {', '	vec4 sum = vec4( 0.0 );', '	sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;', '	sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;', '	sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;', '	sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;', '	sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;', '	sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;', '	sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;', '	sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;', '	gl_FragColor = sum;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform float h;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 sum = vec4( 0.0 );
+
+			sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;
+
+			gl_FragColor = sum;
+
+		}`
 	};
 	};
 
 
 	THREE.HorizontalBlurShader = HorizontalBlurShader;
 	THREE.HorizontalBlurShader = HorizontalBlurShader;

+ 33 - 2
examples/js/shaders/HorizontalTiltShiftShader.js

@@ -20,8 +20,39 @@
 				value: 0.35
 				value: 0.35
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform float h;', 'uniform float r;', 'varying vec2 vUv;', 'void main() {', '	vec4 sum = vec4( 0.0 );', '	float hh = h * abs( r - vUv.y );', '	sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;', '	sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;', '	sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;', '	sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;', '	sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;', '	sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;', '	sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;', '	sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;', '	gl_FragColor = sum;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform float h;
+		uniform float r;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 sum = vec4( 0.0 );
+
+			float hh = h * abs( r - vUv.y );
+
+			sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;
+
+			gl_FragColor = sum;
+
+		}`
 	};
 	};
 
 
 	THREE.HorizontalTiltShiftShader = HorizontalTiltShiftShader;
 	THREE.HorizontalTiltShiftShader = HorizontalTiltShiftShader;

+ 40 - 5
examples/js/shaders/HueSaturationShader.js

@@ -6,7 +6,7 @@
  * hue: -1 to 1 (-1 is 180 degrees in the negative direction, 0 is no change, etc.
  * hue: -1 to 1 (-1 is 180 degrees in the negative direction, 0 is no change, etc.
  * saturation: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast)
  * saturation: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast)
  */
  */
-	var HueSaturationShader = {
+	const HueSaturationShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -18,10 +18,45 @@
 				value: 0
 				value: 0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform float hue;', 'uniform float saturation;', 'varying vec2 vUv;', 'void main() {', '	gl_FragColor = texture2D( tDiffuse, vUv );', // hue
-			'	float angle = hue * 3.14159265;', '	float s = sin(angle), c = cos(angle);', '	vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;', '	float len = length(gl_FragColor.rgb);', '	gl_FragColor.rgb = vec3(', '		dot(gl_FragColor.rgb, weights.xyz),', '		dot(gl_FragColor.rgb, weights.zxy),', '		dot(gl_FragColor.rgb, weights.yzx)', '	);', // saturation
-			'	float average = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / 3.0;', '	if (saturation > 0.0) {', '		gl_FragColor.rgb += (average - gl_FragColor.rgb) * (1.0 - 1.0 / (1.001 - saturation));', '	} else {', '		gl_FragColor.rgb += (average - gl_FragColor.rgb) * (-saturation);', '	}', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform float hue;
+		uniform float saturation;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			gl_FragColor = texture2D( tDiffuse, vUv );
+
+			// hue
+			float angle = hue * 3.14159265;
+			float s = sin(angle), c = cos(angle);
+			vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;
+			float len = length(gl_FragColor.rgb);
+			gl_FragColor.rgb = vec3(
+				dot(gl_FragColor.rgb, weights.xyz),
+				dot(gl_FragColor.rgb, weights.zxy),
+				dot(gl_FragColor.rgb, weights.yzx)
+			);
+
+			// saturation
+			float average = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / 3.0;
+			if (saturation > 0.0) {
+				gl_FragColor.rgb += (average - gl_FragColor.rgb) * (1.0 - 1.0 / (1.001 - saturation));
+			} else {
+				gl_FragColor.rgb += (average - gl_FragColor.rgb) * (-saturation);
+			}
+
+		}`
 	};
 	};
 
 
 	THREE.HueSaturationShader = HueSaturationShader;
 	THREE.HueSaturationShader = HueSaturationShader;

+ 28 - 3
examples/js/shaders/KaleidoShader.js

@@ -9,7 +9,7 @@
  * sides: number of reflections
  * sides: number of reflections
  * angle: initial angle in radians
  * angle: initial angle in radians
  */
  */
-	var KaleidoShader = {
+	const KaleidoShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -21,8 +21,33 @@
 				value: 0.0
 				value: 0.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform float sides;', 'uniform float angle;', 'varying vec2 vUv;', 'void main() {', '	vec2 p = vUv - 0.5;', '	float r = length(p);', '	float a = atan(p.y, p.x) + angle;', '	float tau = 2. * 3.1416 ;', '	a = mod(a, tau/sides);', '	a = abs(a - tau/sides/2.) ;', '	p = r * vec2(cos(a), sin(a));', '	vec4 color = texture2D(tDiffuse, p + 0.5);', '	gl_FragColor = color;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform float sides;
+		uniform float angle;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec2 p = vUv - 0.5;
+			float r = length(p);
+			float a = atan(p.y, p.x) + angle;
+			float tau = 2. * 3.1416 ;
+			a = mod(a, tau/sides);
+			a = abs(a - tau/sides/2.) ;
+			p = r * vec2(cos(a), sin(a));
+			vec4 color = texture2D(tDiffuse, p + 0.5);
+			gl_FragColor = color;
+
+		}`
 	};
 	};
 
 
 	THREE.KaleidoShader = KaleidoShader;
 	THREE.KaleidoShader = KaleidoShader;

+ 33 - 3
examples/js/shaders/LuminosityHighPassShader.js

@@ -5,7 +5,7 @@
  * http://en.wikipedia.org/wiki/Luminosity
  * http://en.wikipedia.org/wiki/Luminosity
  */
  */
 
 
-	var LuminosityHighPassShader = {
+	const LuminosityHighPassShader = {
 		shaderID: 'luminosityHighPass',
 		shaderID: 'luminosityHighPass',
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
@@ -24,8 +24,38 @@
 				value: 0.0
 				value: 0.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform vec3 defaultColor;', 'uniform float defaultOpacity;', 'uniform float luminosityThreshold;', 'uniform float smoothWidth;', 'varying vec2 vUv;', 'void main() {', '	vec4 texel = texture2D( tDiffuse, vUv );', '	vec3 luma = vec3( 0.299, 0.587, 0.114 );', '	float v = dot( texel.xyz, luma );', '	vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );', '	float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );', '	gl_FragColor = mix( outputColor, texel, alpha );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform vec3 defaultColor;
+		uniform float defaultOpacity;
+		uniform float luminosityThreshold;
+		uniform float smoothWidth;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 texel = texture2D( tDiffuse, vUv );
+
+			vec3 luma = vec3( 0.299, 0.587, 0.114 );
+
+			float v = dot( texel.xyz, luma );
+
+			vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );
+
+			float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );
+
+			gl_FragColor = mix( outputColor, texel, alpha );
+
+		}`
 	};
 	};
 
 
 	THREE.LuminosityHighPassShader = LuminosityHighPassShader;
 	THREE.LuminosityHighPassShader = LuminosityHighPassShader;

+ 25 - 3
examples/js/shaders/LuminosityShader.js

@@ -4,14 +4,36 @@
  * Luminosity
  * Luminosity
  * http://en.wikipedia.org/wiki/Luminosity
  * http://en.wikipedia.org/wiki/Luminosity
  */
  */
-	var LuminosityShader = {
+	const LuminosityShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ '#include <common>', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'void main() {', '	vec4 texel = texture2D( tDiffuse, vUv );', '	float l = linearToRelativeLuminance( texel.rgb );', '	gl_FragColor = vec4( l, l, l, texel.w );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `#include <common>
+
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 texel = texture2D( tDiffuse, vUv );
+
+			float l = linearToRelativeLuminance( texel.rgb );
+
+			gl_FragColor = vec4( l, l, l, texel.w );
+
+		}`
 	};
 	};
 
 
 	THREE.LuminosityShader = LuminosityShader;
 	THREE.LuminosityShader = LuminosityShader;

+ 30 - 3
examples/js/shaders/MirrorShader.js

@@ -6,7 +6,7 @@
  *
  *
  * side: side of input to mirror (0 = left, 1 = right, 2 = top, 3 = bottom)
  * side: side of input to mirror (0 = left, 1 = right, 2 = top, 3 = bottom)
  */
  */
-	var MirrorShader = {
+	const MirrorShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -15,8 +15,35 @@
 				value: 1
 				value: 1
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform int side;', 'varying vec2 vUv;', 'void main() {', '	vec2 p = vUv;', '	if (side == 0){', '		if (p.x > 0.5) p.x = 1.0 - p.x;', '	}else if (side == 1){', '		if (p.x < 0.5) p.x = 1.0 - p.x;', '	}else if (side == 2){', '		if (p.y < 0.5) p.y = 1.0 - p.y;', '	}else if (side == 3){', '		if (p.y > 0.5) p.y = 1.0 - p.y;', '	} ', '	vec4 color = texture2D(tDiffuse, p);', '	gl_FragColor = color;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform int side;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec2 p = vUv;
+			if (side == 0){
+				if (p.x > 0.5) p.x = 1.0 - p.x;
+			}else if (side == 1){
+				if (p.x < 0.5) p.x = 1.0 - p.x;
+			}else if (side == 2){
+				if (p.y < 0.5) p.y = 1.0 - p.y;
+			}else if (side == 3){
+				if (p.y > 0.5) p.y = 1.0 - p.y;
+			}
+			vec4 color = texture2D(tDiffuse, p);
+			gl_FragColor = color;
+
+		}`
 	};
 	};
 
 
 	THREE.MirrorShader = MirrorShader;
 	THREE.MirrorShader = MirrorShader;

+ 25 - 3
examples/js/shaders/NormalMapShader.js

@@ -5,7 +5,7 @@
  * - compute normals from heightmap
  * - compute normals from heightmap
  */
  */
 
 
-	var NormalMapShader = {
+	const NormalMapShader = {
 		uniforms: {
 		uniforms: {
 			'heightMap': {
 			'heightMap': {
 				value: null
 				value: null
@@ -20,8 +20,30 @@
 				value: 0.05
 				value: 0.05
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float height;', 'uniform vec2 resolution;', 'uniform sampler2D heightMap;', 'varying vec2 vUv;', 'void main() {', '	float val = texture2D( heightMap, vUv ).x;', '	float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;', '	float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;', '	gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height	) ) + 0.5 ), 1.0 );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float height;
+		uniform vec2 resolution;
+		uniform sampler2D heightMap;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			float val = texture2D( heightMap, vUv ).x;
+
+			float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;
+			float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;
+
+			gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height	) ) + 0.5 ), 1.0 );
+
+		}`
 	};
 	};
 
 
 	THREE.NormalMapShader = NormalMapShader;
 	THREE.NormalMapShader = NormalMapShader;

+ 151 - 19
examples/js/shaders/ParallaxShader.js

@@ -4,7 +4,7 @@
 	//		http://sunandblackcat.com/tipFullView.php?topicid=28
 	//		http://sunandblackcat.com/tipFullView.php?topicid=28
 	// No tangent-space transforms logic based on
 	// No tangent-space transforms logic based on
 	//	 http://mmikkelsen3d.blogspot.sk/2012/02/parallaxpoc-mapping-and-no-tangent.html
 	//	 http://mmikkelsen3d.blogspot.sk/2012/02/parallaxpoc-mapping-and-no-tangent.html
-	var ParallaxShader = {
+	const ParallaxShader = {
 	// Ordered from fastest to best quality.
 	// Ordered from fastest to best quality.
 		modes: {
 		modes: {
 			none: 'NO_PARALLAX',
 			none: 'NO_PARALLAX',
@@ -31,26 +31,158 @@
 				value: null
 				value: null
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'varying vec3 vViewPosition;', 'varying vec3 vNormal;', 'void main() {', '	vUv = uv;', '	vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );', '	vViewPosition = -mvPosition.xyz;', '	vNormal = normalize( normalMatrix * normal );', '	gl_Position = projectionMatrix * mvPosition;', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D bumpMap;', 'uniform sampler2D map;', 'uniform float parallaxScale;', 'uniform float parallaxMinLayers;', 'uniform float parallaxMaxLayers;', 'varying vec2 vUv;', 'varying vec3 vViewPosition;', 'varying vec3 vNormal;', '#ifdef USE_BASIC_PARALLAX', '	vec2 parallaxMap( in vec3 V ) {', '		float initialHeight = texture2D( bumpMap, vUv ).r;', // No Offset Limitting: messy, floating output at grazing angles.
+		vertexShader: `varying vec2 vUv;
+		varying vec3 vViewPosition;
+		varying vec3 vNormal;
+
+		void main() {
+
+			vUv = uv;
+			vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+			vViewPosition = -mvPosition.xyz;
+			vNormal = normalize( normalMatrix * normal );
+			gl_Position = projectionMatrix * mvPosition;
+
+		}`,
+		fragmentShader: `uniform sampler2D bumpMap;
+		uniform sampler2D map;
+
+		uniform float parallaxScale;
+		uniform float parallaxMinLayers;
+		uniform float parallaxMaxLayers;
+
+		varying vec2 vUv;
+		varying vec3 vViewPosition;
+		varying vec3 vNormal;
+
+		#ifdef USE_BASIC_PARALLAX
+
+			vec2 parallaxMap( in vec3 V ) {
+
+				float initialHeight = texture2D( bumpMap, vUv ).r;
+
+				// No Offset Limitting: messy, floating output at grazing angles.
 			//"vec2 texCoordOffset = parallaxScale * V.xy / V.z * initialHeight;",
 			//"vec2 texCoordOffset = parallaxScale * V.xy / V.z * initialHeight;",
+
 			// Offset Limiting
 			// Offset Limiting
-			'		vec2 texCoordOffset = parallaxScale * V.xy * initialHeight;', '		return vUv - texCoordOffset;', '	}', '#else', '	vec2 parallaxMap( in vec3 V ) {', // Determine number of layers from angle between V and N
-			'		float numLayers = mix( parallaxMaxLayers, parallaxMinLayers, abs( dot( vec3( 0.0, 0.0, 1.0 ), V ) ) );', '		float layerHeight = 1.0 / numLayers;', '		float currentLayerHeight = 0.0;', // Shift of texture coordinates for each iteration
-			'		vec2 dtex = parallaxScale * V.xy / V.z / numLayers;', '		vec2 currentTextureCoords = vUv;', '		float heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;', // while ( heightFromTexture > currentLayerHeight )
-			// Infinite loops are not well supported. Do a "large" finite
-			// loop, but not too large, as it slows down some compilers.
-			'		for ( int i = 0; i < 30; i += 1 ) {', '			if ( heightFromTexture <= currentLayerHeight ) {', '				break;', '			}', '			currentLayerHeight += layerHeight;', // Shift texture coordinates along vector V
-			'			currentTextureCoords -= dtex;', '			heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;', '		}', '		#ifdef USE_STEEP_PARALLAX', '			return currentTextureCoords;', '		#elif defined( USE_RELIEF_PARALLAX )', '			vec2 deltaTexCoord = dtex / 2.0;', '			float deltaHeight = layerHeight / 2.0;', // Return to the mid point of previous layer
-			'			currentTextureCoords += deltaTexCoord;', '			currentLayerHeight -= deltaHeight;', // Binary search to increase precision of Steep Parallax Mapping
-			'			const int numSearches = 5;', '			for ( int i = 0; i < numSearches; i += 1 ) {', '				deltaTexCoord /= 2.0;', '				deltaHeight /= 2.0;', '				heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;', // Shift along or against vector V
-			'				if( heightFromTexture > currentLayerHeight ) {', // Below the surface
-			'					currentTextureCoords -= deltaTexCoord;', '					currentLayerHeight += deltaHeight;', '				} else {', // above the surface
-			'					currentTextureCoords += deltaTexCoord;', '					currentLayerHeight -= deltaHeight;', '				}', '			}', '			return currentTextureCoords;', '		#elif defined( USE_OCLUSION_PARALLAX )', '			vec2 prevTCoords = currentTextureCoords + dtex;', // Heights for linear interpolation
-			'			float nextH = heightFromTexture - currentLayerHeight;', '			float prevH = texture2D( bumpMap, prevTCoords ).r - currentLayerHeight + layerHeight;', // Proportions for linear interpolation
-			'			float weight = nextH / ( nextH - prevH );', // Interpolation of texture coordinates
-			'			return prevTCoords * weight + currentTextureCoords * ( 1.0 - weight );', '		#else', // NO_PARALLAX
-			'			return vUv;', '		#endif', '	}', '#endif', 'vec2 perturbUv( vec3 surfPosition, vec3 surfNormal, vec3 viewPosition ) {', '	vec2 texDx = dFdx( vUv );', '	vec2 texDy = dFdy( vUv );', '	vec3 vSigmaX = dFdx( surfPosition );', '	vec3 vSigmaY = dFdy( surfPosition );', '	vec3 vR1 = cross( vSigmaY, surfNormal );', '	vec3 vR2 = cross( surfNormal, vSigmaX );', '	float fDet = dot( vSigmaX, vR1 );', '	vec2 vProjVscr = ( 1.0 / fDet ) * vec2( dot( vR1, viewPosition ), dot( vR2, viewPosition ) );', '	vec3 vProjVtex;', '	vProjVtex.xy = texDx * vProjVscr.x + texDy * vProjVscr.y;', '	vProjVtex.z = dot( surfNormal, viewPosition );', '	return parallaxMap( vProjVtex );', '}', 'void main() {', '	vec2 mapUv = perturbUv( -vViewPosition, normalize( vNormal ), normalize( vViewPosition ) );', '	gl_FragColor = texture2D( map, mapUv );', '}' ].join( '\n' )
+				vec2 texCoordOffset = parallaxScale * V.xy * initialHeight;
+				return vUv - texCoordOffset;
+
+			}
+
+		#else
+
+			vec2 parallaxMap( in vec3 V ) {
+
+				// Determine number of layers from angle between V and N
+				float numLayers = mix( parallaxMaxLayers, parallaxMinLayers, abs( dot( vec3( 0.0, 0.0, 1.0 ), V ) ) );
+
+				float layerHeight = 1.0 / numLayers;
+				float currentLayerHeight = 0.0;
+				// Shift of texture coordinates for each iteration
+				vec2 dtex = parallaxScale * V.xy / V.z / numLayers;
+
+				vec2 currentTextureCoords = vUv;
+
+				float heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;
+
+				// while ( heightFromTexture > currentLayerHeight )
+				// Infinite loops are not well supported. Do a "large" finite
+				// loop, but not too large, as it slows down some compilers.
+				for ( int i = 0; i < 30; i += 1 ) {
+					if ( heightFromTexture <= currentLayerHeight ) {
+						break;
+					}
+					currentLayerHeight += layerHeight;
+					// Shift texture coordinates along vector V
+					currentTextureCoords -= dtex;
+					heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;
+				}
+
+				#ifdef USE_STEEP_PARALLAX
+
+					return currentTextureCoords;
+
+				#elif defined( USE_RELIEF_PARALLAX )
+
+					vec2 deltaTexCoord = dtex / 2.0;
+					float deltaHeight = layerHeight / 2.0;
+
+					// Return to the mid point of previous layer
+					currentTextureCoords += deltaTexCoord;
+					currentLayerHeight -= deltaHeight;
+
+					// Binary search to increase precision of Steep Parallax Mapping
+					const int numSearches = 5;
+					for ( int i = 0; i < numSearches; i += 1 ) {
+
+						deltaTexCoord /= 2.0;
+						deltaHeight /= 2.0;
+						heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;
+						// Shift along or against vector V
+						if( heightFromTexture > currentLayerHeight ) { // Below the surface
+
+							currentTextureCoords -= deltaTexCoord;
+							currentLayerHeight += deltaHeight;
+
+						} else { // above the surface
+
+							currentTextureCoords += deltaTexCoord;
+							currentLayerHeight -= deltaHeight;
+
+						}
+
+					}
+					return currentTextureCoords;
+
+				#elif defined( USE_OCLUSION_PARALLAX )
+
+					vec2 prevTCoords = currentTextureCoords + dtex;
+
+					// Heights for linear interpolation
+					float nextH = heightFromTexture - currentLayerHeight;
+					float prevH = texture2D( bumpMap, prevTCoords ).r - currentLayerHeight + layerHeight;
+
+					// Proportions for linear interpolation
+					float weight = nextH / ( nextH - prevH );
+
+					// Interpolation of texture coordinates
+					return prevTCoords * weight + currentTextureCoords * ( 1.0 - weight );
+
+				#else // NO_PARALLAX
+
+					return vUv;
+
+				#endif
+
+			}
+		#endif
+
+		vec2 perturbUv( vec3 surfPosition, vec3 surfNormal, vec3 viewPosition ) {
+
+ 			vec2 texDx = dFdx( vUv );
+			vec2 texDy = dFdy( vUv );
+
+			vec3 vSigmaX = dFdx( surfPosition );
+			vec3 vSigmaY = dFdy( surfPosition );
+			vec3 vR1 = cross( vSigmaY, surfNormal );
+			vec3 vR2 = cross( surfNormal, vSigmaX );
+			float fDet = dot( vSigmaX, vR1 );
+
+			vec2 vProjVscr = ( 1.0 / fDet ) * vec2( dot( vR1, viewPosition ), dot( vR2, viewPosition ) );
+			vec3 vProjVtex;
+			vProjVtex.xy = texDx * vProjVscr.x + texDy * vProjVscr.y;
+			vProjVtex.z = dot( surfNormal, viewPosition );
+
+			return parallaxMap( vProjVtex );
+		}
+
+		void main() {
+
+			vec2 mapUv = perturbUv( -vViewPosition, normalize( vNormal ), normalize( vViewPosition ) );
+			gl_FragColor = texture2D( map, mapUv );
+
+		}`
 	};
 	};
 
 
 	THREE.ParallaxShader = ParallaxShader;
 	THREE.ParallaxShader = ParallaxShader;

+ 23 - 4
examples/js/shaders/PixelShader.js

@@ -3,7 +3,7 @@
 	/**
 	/**
  * Pixelation shader
  * Pixelation shader
  */
  */
-	var PixelShader = {
+	const PixelShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -12,11 +12,30 @@
 				value: null
 				value: null
 			},
 			},
 			'pixelSize': {
 			'pixelSize': {
-				value: 1.
+				value: 1
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying highp vec2 vUv;', 'void main() {', 'vUv = uv;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform float pixelSize;', 'uniform vec2 resolution;', 'varying highp vec2 vUv;', 'void main(){', 'vec2 dxy = pixelSize / resolution;', 'vec2 coord = dxy * floor( vUv / dxy );', 'gl_FragColor = texture2D(tDiffuse, coord);', '}' ].join( '\n' )
+		vertexShader: `varying highp vec2 vUv;
+
+			void main() {
+
+				vUv = uv;
+				gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform float pixelSize;
+		uniform vec2 resolution;
+
+		varying highp vec2 vUv;
+
+		void main(){
+
+			vec2 dxy = pixelSize / resolution;
+			vec2 coord = dxy * floor( vUv / dxy );
+			gl_FragColor = texture2D(tDiffuse, coord);
+
+		}`
 	};
 	};
 
 
 	THREE.PixelShader = PixelShader;
 	THREE.PixelShader = PixelShader;

+ 24 - 3
examples/js/shaders/RGBShiftShader.js

@@ -9,7 +9,7 @@
  * amount: shift distance (1 is width of input)
  * amount: shift distance (1 is width of input)
  * angle: shift angle in radians
  * angle: shift angle in radians
  */
  */
-	var RGBShiftShader = {
+	const RGBShiftShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -21,8 +21,29 @@
 				value: 0.0
 				value: 0.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform float amount;', 'uniform float angle;', 'varying vec2 vUv;', 'void main() {', '	vec2 offset = amount * vec2( cos(angle), sin(angle));', '	vec4 cr = texture2D(tDiffuse, vUv + offset);', '	vec4 cga = texture2D(tDiffuse, vUv);', '	vec4 cb = texture2D(tDiffuse, vUv - offset);', '	gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform float amount;
+		uniform float angle;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec2 offset = amount * vec2( cos(angle), sin(angle));
+			vec4 cr = texture2D(tDiffuse, vUv + offset);
+			vec4 cga = texture2D(tDiffuse, vUv);
+			vec4 cb = texture2D(tDiffuse, vUv - offset);
+			gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);
+
+		}`
 	};
 	};
 
 
 	THREE.RGBShiftShader = RGBShiftShader;
 	THREE.RGBShiftShader = RGBShiftShader;

File diff suppressed because it is too large
+ 1 - 2
examples/js/shaders/SAOShader.js


+ 378 - 91
examples/js/shaders/SMAAShader.js

@@ -6,7 +6,7 @@
  * https://github.com/iryoku/smaa/releases/tag/v2.8
  * https://github.com/iryoku/smaa/releases/tag/v2.8
  */
  */
 
 
-	var SMAAEdgesShader = {
+	const SMAAEdgesShader = {
 		defines: {
 		defines: {
 			'SMAA_THRESHOLD': '0.1'
 			'SMAA_THRESHOLD': '0.1'
 		},
 		},
@@ -18,21 +18,90 @@
 				value: new THREE.Vector2( 1 / 1024, 1 / 512 )
 				value: new THREE.Vector2( 1 / 1024, 1 / 512 )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'uniform vec2 resolution;', 'varying vec2 vUv;', 'varying vec4 vOffset[ 3 ];', 'void SMAAEdgeDetectionVS( vec2 texcoord ) {', '	vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0,	1.0 );', // WebGL port note: Changed sign in W component
-			'	vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4(	1.0, 0.0, 0.0, -1.0 );', // WebGL port note: Changed sign in W component
-			'	vOffset[ 2 ] = texcoord.xyxy + resolution.xyxy * vec4( -2.0, 0.0, 0.0,	2.0 );', // WebGL port note: Changed sign in W component
-			'}', 'void main() {', '	vUv = uv;', '	SMAAEdgeDetectionVS( vUv );', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'varying vec4 vOffset[ 3 ];', 'vec4 SMAAColorEdgeDetectionPS( vec2 texcoord, vec4 offset[3], sampler2D colorTex ) {', '	vec2 threshold = vec2( SMAA_THRESHOLD, SMAA_THRESHOLD );', // Calculate color deltas:
-			'	vec4 delta;', '	vec3 C = texture2D( colorTex, texcoord ).rgb;', '	vec3 Cleft = texture2D( colorTex, offset[0].xy ).rgb;', '	vec3 t = abs( C - Cleft );', '	delta.x = max( max( t.r, t.g ), t.b );', '	vec3 Ctop = texture2D( colorTex, offset[0].zw ).rgb;', '	t = abs( C - Ctop );', '	delta.y = max( max( t.r, t.g ), t.b );', // We do the usual threshold:
-			'	vec2 edges = step( threshold, delta.xy );', // Then discard if there is no edge:
-			'	if ( dot( edges, vec2( 1.0, 1.0 ) ) == 0.0 )', '		discard;', // Calculate right and bottom deltas:
-			'	vec3 Cright = texture2D( colorTex, offset[1].xy ).rgb;', '	t = abs( C - Cright );', '	delta.z = max( max( t.r, t.g ), t.b );', '	vec3 Cbottom	= texture2D( colorTex, offset[1].zw ).rgb;', '	t = abs( C - Cbottom );', '	delta.w = max( max( t.r, t.g ), t.b );', // Calculate the maximum delta in the direct neighborhood:
-			'	float maxDelta = max( max( max( delta.x, delta.y ), delta.z ), delta.w );', // Calculate left-left and top-top deltas:
-			'	vec3 Cleftleft	= texture2D( colorTex, offset[2].xy ).rgb;', '	t = abs( C - Cleftleft );', '	delta.z = max( max( t.r, t.g ), t.b );', '	vec3 Ctoptop = texture2D( colorTex, offset[2].zw ).rgb;', '	t = abs( C - Ctoptop );', '	delta.w = max( max( t.r, t.g ), t.b );', // Calculate the final maximum delta:
-			'	maxDelta = max( max( maxDelta, delta.z ), delta.w );', // Local contrast adaptation in action:
-			'	edges.xy *= step( 0.5 * maxDelta, delta.xy );', '	return vec4( edges, 0.0, 0.0 );', '}', 'void main() {', '	gl_FragColor = SMAAColorEdgeDetectionPS( vUv, vOffset, tDiffuse );', '}' ].join( '\n' )
+		vertexShader: `uniform vec2 resolution;
+
+		varying vec2 vUv;
+		varying vec4 vOffset[ 3 ];
+
+		void SMAAEdgeDetectionVS( vec2 texcoord ) {
+			vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0,	1.0 ); // WebGL port note: Changed sign in W component
+			vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4(	1.0, 0.0, 0.0, -1.0 ); // WebGL port note: Changed sign in W component
+			vOffset[ 2 ] = texcoord.xyxy + resolution.xyxy * vec4( -2.0, 0.0, 0.0,	2.0 ); // WebGL port note: Changed sign in W component
+		}
+
+		void main() {
+
+			vUv = uv;
+
+			SMAAEdgeDetectionVS( vUv );
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+		varying vec4 vOffset[ 3 ];
+
+		vec4 SMAAColorEdgeDetectionPS( vec2 texcoord, vec4 offset[3], sampler2D colorTex ) {
+			vec2 threshold = vec2( SMAA_THRESHOLD, SMAA_THRESHOLD );
+
+			// Calculate color deltas:
+			vec4 delta;
+			vec3 C = texture2D( colorTex, texcoord ).rgb;
+
+			vec3 Cleft = texture2D( colorTex, offset[0].xy ).rgb;
+			vec3 t = abs( C - Cleft );
+			delta.x = max( max( t.r, t.g ), t.b );
+
+			vec3 Ctop = texture2D( colorTex, offset[0].zw ).rgb;
+			t = abs( C - Ctop );
+			delta.y = max( max( t.r, t.g ), t.b );
+
+			// We do the usual threshold:
+			vec2 edges = step( threshold, delta.xy );
+
+			// Then discard if there is no edge:
+			if ( dot( edges, vec2( 1.0, 1.0 ) ) == 0.0 )
+				discard;
+
+			// Calculate right and bottom deltas:
+			vec3 Cright = texture2D( colorTex, offset[1].xy ).rgb;
+			t = abs( C - Cright );
+			delta.z = max( max( t.r, t.g ), t.b );
+
+			vec3 Cbottom	= texture2D( colorTex, offset[1].zw ).rgb;
+			t = abs( C - Cbottom );
+			delta.w = max( max( t.r, t.g ), t.b );
+
+			// Calculate the maximum delta in the direct neighborhood:
+			float maxDelta = max( max( max( delta.x, delta.y ), delta.z ), delta.w );
+
+			// Calculate left-left and top-top deltas:
+			vec3 Cleftleft	= texture2D( colorTex, offset[2].xy ).rgb;
+			t = abs( C - Cleftleft );
+			delta.z = max( max( t.r, t.g ), t.b );
+
+			vec3 Ctoptop = texture2D( colorTex, offset[2].zw ).rgb;
+			t = abs( C - Ctoptop );
+			delta.w = max( max( t.r, t.g ), t.b );
+
+			// Calculate the final maximum delta:
+			maxDelta = max( max( maxDelta, delta.z ), delta.w );
+
+			// Local contrast adaptation in action:
+			edges.xy *= step( 0.5 * maxDelta, delta.xy );
+
+			return vec4( edges, 0.0, 0.0 );
+		}
+
+		void main() {
+
+			gl_FragColor = SMAAColorEdgeDetectionPS( vUv, vOffset, tDiffuse );
+
+		}`
 	};
 	};
-	var SMAAWeightsShader = {
+	const SMAAWeightsShader = {
 		defines: {
 		defines: {
 			'SMAA_MAX_SEARCH_STEPS': '8',
 			'SMAA_MAX_SEARCH_STEPS': '8',
 			'SMAA_AREATEX_MAX_DISTANCE': '16',
 			'SMAA_AREATEX_MAX_DISTANCE': '16',
@@ -53,73 +122,234 @@
 				value: new THREE.Vector2( 1 / 1024, 1 / 512 )
 				value: new THREE.Vector2( 1 / 1024, 1 / 512 )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'uniform vec2 resolution;', 'varying vec2 vUv;', 'varying vec4 vOffset[ 3 ];', 'varying vec2 vPixcoord;', 'void SMAABlendingWeightCalculationVS( vec2 texcoord ) {', '	vPixcoord = texcoord / resolution;', // We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
-			'	vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.25, 0.125, 1.25, 0.125 );', // WebGL port note: Changed sign in Y and W components
-			'	vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.125, 0.25, -0.125, -1.25 );', // WebGL port note: Changed sign in Y and W components
+		vertexShader: `uniform vec2 resolution;
+
+		varying vec2 vUv;
+		varying vec4 vOffset[ 3 ];
+		varying vec2 vPixcoord;
+
+		void SMAABlendingWeightCalculationVS( vec2 texcoord ) {
+			vPixcoord = texcoord / resolution;
+
+			// We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
+			vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.25, 0.125, 1.25, 0.125 ); // WebGL port note: Changed sign in Y and W components
+			vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.125, 0.25, -0.125, -1.25 ); // WebGL port note: Changed sign in Y and W components
+
 			// And these for the searches, they indicate the ends of the loops:
 			// And these for the searches, they indicate the ends of the loops:
-			'	vOffset[ 2 ] = vec4( vOffset[ 0 ].xz, vOffset[ 1 ].yw ) + vec4( -2.0, 2.0, -2.0, 2.0 ) * resolution.xxyy * float( SMAA_MAX_SEARCH_STEPS );', '}', 'void main() {', '	vUv = uv;', '	SMAABlendingWeightCalculationVS( vUv );', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ '#define SMAASampleLevelZeroOffset( tex, coord, offset ) texture2D( tex, coord + float( offset ) * resolution, 0.0 )', 'uniform sampler2D tDiffuse;', 'uniform sampler2D tArea;', 'uniform sampler2D tSearch;', 'uniform vec2 resolution;', 'varying vec2 vUv;', 'varying vec4 vOffset[3];', 'varying vec2 vPixcoord;', '#if __VERSION__ == 100', 'vec2 round( vec2 x ) {', '	return sign( x ) * floor( abs( x ) + 0.5 );', '}', '#endif', 'float SMAASearchLength( sampler2D searchTex, vec2 e, float bias, float scale ) {', // Not required if searchTex accesses are set to point:
+			vOffset[ 2 ] = vec4( vOffset[ 0 ].xz, vOffset[ 1 ].yw ) + vec4( -2.0, 2.0, -2.0, 2.0 ) * resolution.xxyy * float( SMAA_MAX_SEARCH_STEPS );
+
+		}
+
+		void main() {
+
+			vUv = uv;
+
+			SMAABlendingWeightCalculationVS( vUv );
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `#define SMAASampleLevelZeroOffset( tex, coord, offset ) texture2D( tex, coord + float( offset ) * resolution, 0.0 )
+
+		uniform sampler2D tDiffuse;
+		uniform sampler2D tArea;
+		uniform sampler2D tSearch;
+		uniform vec2 resolution;
+
+		varying vec2 vUv;
+		varying vec4 vOffset[3];
+		varying vec2 vPixcoord;
+
+		#if __VERSION__ == 100
+		vec2 round( vec2 x ) {
+			return sign( x ) * floor( abs( x ) + 0.5 );
+		}
+		#endif
+
+		float SMAASearchLength( sampler2D searchTex, vec2 e, float bias, float scale ) {
+			// Not required if searchTex accesses are set to point:
 			// float2 SEARCH_TEX_PIXEL_SIZE = 1.0 / float2(66.0, 33.0);
 			// float2 SEARCH_TEX_PIXEL_SIZE = 1.0 / float2(66.0, 33.0);
 			// e = float2(bias, 0.0) + 0.5 * SEARCH_TEX_PIXEL_SIZE +
 			// e = float2(bias, 0.0) + 0.5 * SEARCH_TEX_PIXEL_SIZE +
 			//		 e * float2(scale, 1.0) * float2(64.0, 32.0) * SEARCH_TEX_PIXEL_SIZE;
 			//		 e * float2(scale, 1.0) * float2(64.0, 32.0) * SEARCH_TEX_PIXEL_SIZE;
-			'	e.r = bias + e.r * scale;', '	return 255.0 * texture2D( searchTex, e, 0.0 ).r;', '}', 'float SMAASearchXLeft( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {',
+			e.r = bias + e.r * scale;
+			return 255.0 * texture2D( searchTex, e, 0.0 ).r;
+		}
+
+		float SMAASearchXLeft( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {
 			/**
 			/**
-		* @PSEUDO_GATHER4
-		* This texcoord has been offset by (-0.25, -0.125) in the vertex shader to
-		* sample between edge, thus fetching four edges in a row.
-		* Sampling with different offsets in each direction allows to disambiguate
-		* which edges are active from the four fetched ones.
-		*/
-			'	vec2 e = vec2( 0.0, 1.0 );', '	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {', // WebGL port note: Changed while to for
-			'		e = texture2D( edgesTex, texcoord, 0.0 ).rg;', '		texcoord -= vec2( 2.0, 0.0 ) * resolution;', '		if ( ! ( texcoord.x > end && e.g > 0.8281 && e.r == 0.0 ) ) break;', '	}', // We correct the previous (-0.25, -0.125) offset we applied:
-			'	texcoord.x += 0.25 * resolution.x;', // The searches are bias by 1, so adjust the coords accordingly:
-			'	texcoord.x += resolution.x;', // Disambiguate the length added by the last step:
-			'	texcoord.x += 2.0 * resolution.x;', // Undo last step
-			'	texcoord.x -= resolution.x * SMAASearchLength(searchTex, e, 0.0, 0.5);', '	return texcoord.x;', '}', 'float SMAASearchXRight( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {', '	vec2 e = vec2( 0.0, 1.0 );', '	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {', // WebGL port note: Changed while to for
-			'		e = texture2D( edgesTex, texcoord, 0.0 ).rg;', '		texcoord += vec2( 2.0, 0.0 ) * resolution;', '		if ( ! ( texcoord.x < end && e.g > 0.8281 && e.r == 0.0 ) ) break;', '	}', '	texcoord.x -= 0.25 * resolution.x;', '	texcoord.x -= resolution.x;', '	texcoord.x -= 2.0 * resolution.x;', '	texcoord.x += resolution.x * SMAASearchLength( searchTex, e, 0.5, 0.5 );', '	return texcoord.x;', '}', 'float SMAASearchYUp( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {', '	vec2 e = vec2( 1.0, 0.0 );', '	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {', // WebGL port note: Changed while to for
-			'		e = texture2D( edgesTex, texcoord, 0.0 ).rg;', '		texcoord += vec2( 0.0, 2.0 ) * resolution;', // WebGL port note: Changed sign
-			'		if ( ! ( texcoord.y > end && e.r > 0.8281 && e.g == 0.0 ) ) break;', '	}', '	texcoord.y -= 0.25 * resolution.y;', // WebGL port note: Changed sign
-			'	texcoord.y -= resolution.y;', // WebGL port note: Changed sign
-			'	texcoord.y -= 2.0 * resolution.y;', // WebGL port note: Changed sign
-			'	texcoord.y += resolution.y * SMAASearchLength( searchTex, e.gr, 0.0, 0.5 );', // WebGL port note: Changed sign
-			'	return texcoord.y;', '}', 'float SMAASearchYDown( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {', '	vec2 e = vec2( 1.0, 0.0 );', '	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {', // WebGL port note: Changed while to for
-			'		e = texture2D( edgesTex, texcoord, 0.0 ).rg;', '		texcoord -= vec2( 0.0, 2.0 ) * resolution;', // WebGL port note: Changed sign
-			'		if ( ! ( texcoord.y < end && e.r > 0.8281 && e.g == 0.0 ) ) break;', '	}', '	texcoord.y += 0.25 * resolution.y;', // WebGL port note: Changed sign
-			'	texcoord.y += resolution.y;', // WebGL port note: Changed sign
-			'	texcoord.y += 2.0 * resolution.y;', // WebGL port note: Changed sign
-			'	texcoord.y -= resolution.y * SMAASearchLength( searchTex, e.gr, 0.5, 0.5 );', // WebGL port note: Changed sign
-			'	return texcoord.y;', '}', 'vec2 SMAAArea( sampler2D areaTex, vec2 dist, float e1, float e2, float offset ) {', // Rounding prevents precision errors of bilinear filtering:
-			'	vec2 texcoord = float( SMAA_AREATEX_MAX_DISTANCE ) * round( 4.0 * vec2( e1, e2 ) ) + dist;', // We do a scale and bias for mapping to texel space:
-			'	texcoord = SMAA_AREATEX_PIXEL_SIZE * texcoord + ( 0.5 * SMAA_AREATEX_PIXEL_SIZE );', // Move to proper place, according to the subpixel offset:
-			'	texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset;', '	return texture2D( areaTex, texcoord, 0.0 ).rg;', '}', 'vec4 SMAABlendingWeightCalculationPS( vec2 texcoord, vec2 pixcoord, vec4 offset[ 3 ], sampler2D edgesTex, sampler2D areaTex, sampler2D searchTex, ivec4 subsampleIndices ) {', '	vec4 weights = vec4( 0.0, 0.0, 0.0, 0.0 );', '	vec2 e = texture2D( edgesTex, texcoord ).rg;', '	if ( e.g > 0.0 ) {', // Edge at north
-			'		vec2 d;', // Find the distance to the left:
-			'		vec2 coords;', '		coords.x = SMAASearchXLeft( edgesTex, searchTex, offset[ 0 ].xy, offset[ 2 ].x );', '		coords.y = offset[ 1 ].y;', // offset[1].y = texcoord.y - 0.25 * resolution.y (@CROSSING_OFFSET)
-			'		d.x = coords.x;', // Now fetch the left crossing edges, two at a time using bilinear
-			// filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to
-			// discern what value each edge has:
-			'		float e1 = texture2D( edgesTex, coords, 0.0 ).r;', // Find the distance to the right:
-			'		coords.x = SMAASearchXRight( edgesTex, searchTex, offset[ 0 ].zw, offset[ 2 ].y );', '		d.y = coords.x;', // We want the distances to be in pixel units (doing this here allow to
-			// better interleave arithmetic and memory accesses):
-			'		d = d / resolution.x - pixcoord.x;', // SMAAArea below needs a sqrt, as the areas texture is compressed
-			// quadratically:
-			'		vec2 sqrt_d = sqrt( abs( d ) );', // Fetch the right crossing edges:
-			'		coords.y -= 1.0 * resolution.y;', // WebGL port note: Added
-			'		float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 1, 0 ) ).r;', // Ok, we know how this pattern looks like, now it is time for getting
-			// the actual area:
-			'		weights.rg = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.y ) );', '	}', '	if ( e.r > 0.0 ) {', // Edge at west
-			'		vec2 d;', // Find the distance to the top:
-			'		vec2 coords;', '		coords.y = SMAASearchYUp( edgesTex, searchTex, offset[ 1 ].xy, offset[ 2 ].z );', '		coords.x = offset[ 0 ].x;', // offset[1].x = texcoord.x - 0.25 * resolution.x;
-			'		d.x = coords.y;', // Fetch the top crossing edges:
-			'		float e1 = texture2D( edgesTex, coords, 0.0 ).g;', // Find the distance to the bottom:
-			'		coords.y = SMAASearchYDown( edgesTex, searchTex, offset[ 1 ].zw, offset[ 2 ].w );', '		d.y = coords.y;', // We want the distances to be in pixel units:
-			'		d = d / resolution.y - pixcoord.y;', // SMAAArea below needs a sqrt, as the areas texture is compressed
-			// quadratically:
-			'		vec2 sqrt_d = sqrt( abs( d ) );', // Fetch the bottom crossing edges:
-			'		coords.y -= 1.0 * resolution.y;', // WebGL port note: Added
-			'		float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 0, 1 ) ).g;', // Get the area for this direction:
-			'		weights.ba = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.x ) );', '	}', '	return weights;', '}', 'void main() {', '	gl_FragColor = SMAABlendingWeightCalculationPS( vUv, vPixcoord, vOffset, tDiffuse, tArea, tSearch, ivec4( 0.0 ) );', '}' ].join( '\n' )
+				* @PSEUDO_GATHER4
+				* This texcoord has been offset by (-0.25, -0.125) in the vertex shader to
+				* sample between edge, thus fetching four edges in a row.
+				* Sampling with different offsets in each direction allows to disambiguate
+				* which edges are active from the four fetched ones.
+				*/
+			vec2 e = vec2( 0.0, 1.0 );
+
+			for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) { // WebGL port note: Changed while to for
+				e = texture2D( edgesTex, texcoord, 0.0 ).rg;
+				texcoord -= vec2( 2.0, 0.0 ) * resolution;
+				if ( ! ( texcoord.x > end && e.g > 0.8281 && e.r == 0.0 ) ) break;
+			}
+
+			// We correct the previous (-0.25, -0.125) offset we applied:
+			texcoord.x += 0.25 * resolution.x;
+
+			// The searches are bias by 1, so adjust the coords accordingly:
+			texcoord.x += resolution.x;
+
+			// Disambiguate the length added by the last step:
+			texcoord.x += 2.0 * resolution.x; // Undo last step
+			texcoord.x -= resolution.x * SMAASearchLength(searchTex, e, 0.0, 0.5);
+
+			return texcoord.x;
+		}
+
+		float SMAASearchXRight( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {
+			vec2 e = vec2( 0.0, 1.0 );
+
+			for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) { // WebGL port note: Changed while to for
+				e = texture2D( edgesTex, texcoord, 0.0 ).rg;
+				texcoord += vec2( 2.0, 0.0 ) * resolution;
+				if ( ! ( texcoord.x < end && e.g > 0.8281 && e.r == 0.0 ) ) break;
+			}
+
+			texcoord.x -= 0.25 * resolution.x;
+			texcoord.x -= resolution.x;
+			texcoord.x -= 2.0 * resolution.x;
+			texcoord.x += resolution.x * SMAASearchLength( searchTex, e, 0.5, 0.5 );
+
+			return texcoord.x;
+		}
+
+		float SMAASearchYUp( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {
+			vec2 e = vec2( 1.0, 0.0 );
+
+			for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) { // WebGL port note: Changed while to for
+				e = texture2D( edgesTex, texcoord, 0.0 ).rg;
+				texcoord += vec2( 0.0, 2.0 ) * resolution; // WebGL port note: Changed sign
+				if ( ! ( texcoord.y > end && e.r > 0.8281 && e.g == 0.0 ) ) break;
+			}
+
+			texcoord.y -= 0.25 * resolution.y; // WebGL port note: Changed sign
+			texcoord.y -= resolution.y; // WebGL port note: Changed sign
+			texcoord.y -= 2.0 * resolution.y; // WebGL port note: Changed sign
+			texcoord.y += resolution.y * SMAASearchLength( searchTex, e.gr, 0.0, 0.5 ); // WebGL port note: Changed sign
+
+			return texcoord.y;
+		}
+
+		float SMAASearchYDown( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {
+			vec2 e = vec2( 1.0, 0.0 );
+
+			for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) { // WebGL port note: Changed while to for
+				e = texture2D( edgesTex, texcoord, 0.0 ).rg;
+				texcoord -= vec2( 0.0, 2.0 ) * resolution; // WebGL port note: Changed sign
+				if ( ! ( texcoord.y < end && e.r > 0.8281 && e.g == 0.0 ) ) break;
+			}
+
+			texcoord.y += 0.25 * resolution.y; // WebGL port note: Changed sign
+			texcoord.y += resolution.y; // WebGL port note: Changed sign
+			texcoord.y += 2.0 * resolution.y; // WebGL port note: Changed sign
+			texcoord.y -= resolution.y * SMAASearchLength( searchTex, e.gr, 0.5, 0.5 ); // WebGL port note: Changed sign
+
+			return texcoord.y;
+		}
+
+		vec2 SMAAArea( sampler2D areaTex, vec2 dist, float e1, float e2, float offset ) {
+			// Rounding prevents precision errors of bilinear filtering:
+			vec2 texcoord = float( SMAA_AREATEX_MAX_DISTANCE ) * round( 4.0 * vec2( e1, e2 ) ) + dist;
+
+			// We do a scale and bias for mapping to texel space:
+			texcoord = SMAA_AREATEX_PIXEL_SIZE * texcoord + ( 0.5 * SMAA_AREATEX_PIXEL_SIZE );
+
+			// Move to proper place, according to the subpixel offset:
+			texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset;
+
+			return texture2D( areaTex, texcoord, 0.0 ).rg;
+		}
+
+		vec4 SMAABlendingWeightCalculationPS( vec2 texcoord, vec2 pixcoord, vec4 offset[ 3 ], sampler2D edgesTex, sampler2D areaTex, sampler2D searchTex, ivec4 subsampleIndices ) {
+			vec4 weights = vec4( 0.0, 0.0, 0.0, 0.0 );
+
+			vec2 e = texture2D( edgesTex, texcoord ).rg;
+
+			if ( e.g > 0.0 ) { // Edge at north
+				vec2 d;
+
+				// Find the distance to the left:
+				vec2 coords;
+				coords.x = SMAASearchXLeft( edgesTex, searchTex, offset[ 0 ].xy, offset[ 2 ].x );
+				coords.y = offset[ 1 ].y; // offset[1].y = texcoord.y - 0.25 * resolution.y (@CROSSING_OFFSET)
+				d.x = coords.x;
+
+				// Now fetch the left crossing edges, two at a time using bilinear
+				// filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to
+				// discern what value each edge has:
+				float e1 = texture2D( edgesTex, coords, 0.0 ).r;
+
+				// Find the distance to the right:
+				coords.x = SMAASearchXRight( edgesTex, searchTex, offset[ 0 ].zw, offset[ 2 ].y );
+				d.y = coords.x;
+
+				// We want the distances to be in pixel units (doing this here allow to
+				// better interleave arithmetic and memory accesses):
+				d = d / resolution.x - pixcoord.x;
+
+				// SMAAArea below needs a sqrt, as the areas texture is compressed
+				// quadratically:
+				vec2 sqrt_d = sqrt( abs( d ) );
+
+				// Fetch the right crossing edges:
+				coords.y -= 1.0 * resolution.y; // WebGL port note: Added
+				float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 1, 0 ) ).r;
+
+				// Ok, we know how this pattern looks like, now it is time for getting
+				// the actual area:
+				weights.rg = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.y ) );
+			}
+
+			if ( e.r > 0.0 ) { // Edge at west
+				vec2 d;
+
+				// Find the distance to the top:
+				vec2 coords;
+
+				coords.y = SMAASearchYUp( edgesTex, searchTex, offset[ 1 ].xy, offset[ 2 ].z );
+				coords.x = offset[ 0 ].x; // offset[1].x = texcoord.x - 0.25 * resolution.x;
+				d.x = coords.y;
+
+				// Fetch the top crossing edges:
+				float e1 = texture2D( edgesTex, coords, 0.0 ).g;
+
+				// Find the distance to the bottom:
+				coords.y = SMAASearchYDown( edgesTex, searchTex, offset[ 1 ].zw, offset[ 2 ].w );
+				d.y = coords.y;
+
+				// We want the distances to be in pixel units:
+				d = d / resolution.y - pixcoord.y;
+
+				// SMAAArea below needs a sqrt, as the areas texture is compressed
+				// quadratically:
+				vec2 sqrt_d = sqrt( abs( d ) );
+
+				// Fetch the bottom crossing edges:
+				coords.y -= 1.0 * resolution.y; // WebGL port note: Added
+				float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 0, 1 ) ).g;
+
+				// Get the area for this direction:
+				weights.ba = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.x ) );
+			}
+
+			return weights;
+		}
+
+		void main() {
+
+			gl_FragColor = SMAABlendingWeightCalculationPS( vUv, vPixcoord, vOffset, tDiffuse, tArea, tSearch, ivec4( 0.0 ) );
+
+		}`
 	};
 	};
-	var SMAABlendShader = {
+	const SMAABlendShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -131,21 +361,78 @@
 				value: new THREE.Vector2( 1 / 1024, 1 / 512 )
 				value: new THREE.Vector2( 1 / 1024, 1 / 512 )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'uniform vec2 resolution;', 'varying vec2 vUv;', 'varying vec4 vOffset[ 2 ];', 'void SMAANeighborhoodBlendingVS( vec2 texcoord ) {', '	vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0, 1.0 );', // WebGL port note: Changed sign in W component
-			'	vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( 1.0, 0.0, 0.0, -1.0 );', // WebGL port note: Changed sign in W component
-			'}', 'void main() {', '	vUv = uv;', '	SMAANeighborhoodBlendingVS( vUv );', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform sampler2D tColor;', 'uniform vec2 resolution;', 'varying vec2 vUv;', 'varying vec4 vOffset[ 2 ];', 'vec4 SMAANeighborhoodBlendingPS( vec2 texcoord, vec4 offset[ 2 ], sampler2D colorTex, sampler2D blendTex ) {', // Fetch the blending weights for current pixel:
-			'	vec4 a;', '	a.xz = texture2D( blendTex, texcoord ).xz;', '	a.y = texture2D( blendTex, offset[ 1 ].zw ).g;', '	a.w = texture2D( blendTex, offset[ 1 ].xy ).a;', // Is there any blending weight with a value greater than 0.0?
-			'	if ( dot(a, vec4( 1.0, 1.0, 1.0, 1.0 )) < 1e-5 ) {', '		return texture2D( colorTex, texcoord, 0.0 );', '	} else {', // Up to 4 lines can be crossing a pixel (one through each edge). We
-			// favor blending by choosing the line with the maximum weight for each
-			// direction:
-			'		vec2 offset;', '		offset.x = a.a > a.b ? a.a : -a.b;', // left vs. right
-			'		offset.y = a.g > a.r ? -a.g : a.r;', // top vs. bottom // WebGL port note: Changed signs
-			// Then we go in the direction that has the maximum weight:
-			'		if ( abs( offset.x ) > abs( offset.y )) {', // horizontal vs. vertical
-			'			offset.y = 0.0;', '		} else {', '			offset.x = 0.0;', '		}', // Fetch the opposite color and lerp by hand:
-			'		vec4 C = texture2D( colorTex, texcoord, 0.0 );', '		texcoord += sign( offset ) * resolution;', '		vec4 Cop = texture2D( colorTex, texcoord, 0.0 );', '		float s = abs( offset.x ) > abs( offset.y ) ? abs( offset.x ) : abs( offset.y );', // WebGL port note: Added gamma correction
-			'		C.xyz = pow(C.xyz, vec3(2.2));', '		Cop.xyz = pow(Cop.xyz, vec3(2.2));', '		vec4 mixed = mix(C, Cop, s);', '		mixed.xyz = pow(mixed.xyz, vec3(1.0 / 2.2));', '		return mixed;', '	}', '}', 'void main() {', '	gl_FragColor = SMAANeighborhoodBlendingPS( vUv, vOffset, tColor, tDiffuse );', '}' ].join( '\n' )
+		vertexShader: `uniform vec2 resolution;
+
+		varying vec2 vUv;
+		varying vec4 vOffset[ 2 ];
+
+		void SMAANeighborhoodBlendingVS( vec2 texcoord ) {
+			vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0, 1.0 ); // WebGL port note: Changed sign in W component
+			vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( 1.0, 0.0, 0.0, -1.0 ); // WebGL port note: Changed sign in W component
+		}
+
+		void main() {
+
+			vUv = uv;
+
+			SMAANeighborhoodBlendingVS( vUv );
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform sampler2D tColor;
+		uniform vec2 resolution;
+
+		varying vec2 vUv;
+		varying vec4 vOffset[ 2 ];
+
+		vec4 SMAANeighborhoodBlendingPS( vec2 texcoord, vec4 offset[ 2 ], sampler2D colorTex, sampler2D blendTex ) {
+			// Fetch the blending weights for current pixel:
+			vec4 a;
+			a.xz = texture2D( blendTex, texcoord ).xz;
+			a.y = texture2D( blendTex, offset[ 1 ].zw ).g;
+			a.w = texture2D( blendTex, offset[ 1 ].xy ).a;
+
+			// Is there any blending weight with a value greater than 0.0?
+			if ( dot(a, vec4( 1.0, 1.0, 1.0, 1.0 )) < 1e-5 ) {
+				return texture2D( colorTex, texcoord, 0.0 );
+			} else {
+				// Up to 4 lines can be crossing a pixel (one through each edge). We
+				// favor blending by choosing the line with the maximum weight for each
+				// direction:
+				vec2 offset;
+				offset.x = a.a > a.b ? a.a : -a.b; // left vs. right
+				offset.y = a.g > a.r ? -a.g : a.r; // top vs. bottom // WebGL port note: Changed signs
+
+				// Then we go in the direction that has the maximum weight:
+				if ( abs( offset.x ) > abs( offset.y )) { // horizontal vs. vertical
+					offset.y = 0.0;
+				} else {
+					offset.x = 0.0;
+				}
+
+				// Fetch the opposite color and lerp by hand:
+				vec4 C = texture2D( colorTex, texcoord, 0.0 );
+				texcoord += sign( offset ) * resolution;
+				vec4 Cop = texture2D( colorTex, texcoord, 0.0 );
+				float s = abs( offset.x ) > abs( offset.y ) ? abs( offset.x ) : abs( offset.y );
+
+				// WebGL port note: Added gamma correction
+				C.xyz = pow(C.xyz, vec3(2.2));
+				Cop.xyz = pow(Cop.xyz, vec3(2.2));
+				vec4 mixed = mix(C, Cop, s);
+				mixed.xyz = pow(mixed.xyz, vec3(1.0 / 2.2));
+
+				return mixed;
+			}
+		}
+
+		void main() {
+
+			gl_FragColor = SMAANeighborhoodBlendingPS( vUv, vOffset, tColor, tDiffuse );
+
+		}`
 	};
 	};
 
 
 	THREE.SMAABlendShader = SMAABlendShader;
 	THREE.SMAABlendShader = SMAABlendShader;

+ 206 - 19
examples/js/shaders/SSAOShader.js

@@ -7,7 +7,7 @@
  * https://github.com/McNopper/OpenGL/blob/master/Example28/shader/ssao.frag.glsl
  * https://github.com/McNopper/OpenGL/blob/master/Example28/shader/ssao.frag.glsl
  */
  */
 
 
-	var SSAOShader = {
+	const SSAOShader = {
 		defines: {
 		defines: {
 			'PERSPECTIVE_CAMERA': 1,
 			'PERSPECTIVE_CAMERA': 1,
 			'KERNEL_SIZE': 32
 			'KERNEL_SIZE': 32
@@ -53,20 +53,139 @@
 				value: 0.05
 				value: 0.05
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform sampler2D tNormal;', 'uniform sampler2D tDepth;', 'uniform sampler2D tNoise;', 'uniform vec3 kernel[ KERNEL_SIZE ];', 'uniform vec2 resolution;', 'uniform float cameraNear;', 'uniform float cameraFar;', 'uniform mat4 cameraProjectionMatrix;', 'uniform mat4 cameraInverseProjectionMatrix;', 'uniform float kernelRadius;', 'uniform float minDistance;', // avoid artifacts caused by neighbour fragments with minimal depth difference
-			'uniform float maxDistance;', // avoid the influence of fragments which are too far away
-			'varying vec2 vUv;', '#include <packing>', 'float getDepth( const in vec2 screenPosition ) {', '	return texture2D( tDepth, screenPosition ).x;', '}', 'float getLinearDepth( const in vec2 screenPosition ) {', '	#if PERSPECTIVE_CAMERA == 1', '		float fragCoordZ = texture2D( tDepth, screenPosition ).x;', '		float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );', '		return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );', '	#else', '		return texture2D( tDepth, screenPosition ).x;', '	#endif', '}', 'float getViewZ( const in float depth ) {', '	#if PERSPECTIVE_CAMERA == 1', '		return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );', '	#else', '		return orthographicDepthToViewZ( depth, cameraNear, cameraFar );', '	#endif', '}', 'vec3 getViewPosition( const in vec2 screenPosition, const in float depth, const in float viewZ ) {', '	float clipW = cameraProjectionMatrix[2][3] * viewZ + cameraProjectionMatrix[3][3];', '	vec4 clipPosition = vec4( ( vec3( screenPosition, depth ) - 0.5 ) * 2.0, 1.0 );', '	clipPosition *= clipW; // unprojection.', '	return ( cameraInverseProjectionMatrix * clipPosition ).xyz;', '}', 'vec3 getViewNormal( const in vec2 screenPosition ) {', '	return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );', '}', 'void main() {', '	float depth = getDepth( vUv );', '	float viewZ = getViewZ( depth );', '	vec3 viewPosition = getViewPosition( vUv, depth, viewZ );', '	vec3 viewNormal = getViewNormal( vUv );', ' vec2 noiseScale = vec2( resolution.x / 4.0, resolution.y / 4.0 );', '	vec3 random = texture2D( tNoise, vUv * noiseScale ).xyz;', // compute matrix used to reorient a kernel vector
-			'	vec3 tangent = normalize( random - viewNormal * dot( random, viewNormal ) );', '	vec3 bitangent = cross( viewNormal, tangent );', '	mat3 kernelMatrix = mat3( tangent, bitangent, viewNormal );', ' float occlusion = 0.0;', ' for ( int i = 0; i < KERNEL_SIZE; i ++ ) {', '		vec3 sampleVector = kernelMatrix * kernel[ i ];', // reorient sample vector in view space
-			'		vec3 samplePoint = viewPosition + ( sampleVector * kernelRadius );', // calculate sample point
-			'		vec4 samplePointNDC = cameraProjectionMatrix * vec4( samplePoint, 1.0 );', // project point and calculate NDC
-			'		samplePointNDC /= samplePointNDC.w;', '		vec2 samplePointUv = samplePointNDC.xy * 0.5 + 0.5;', // compute uv coordinates
-			'		float realDepth = getLinearDepth( samplePointUv );', // get linear depth from depth texture
-			'		float sampleDepth = viewZToOrthographicDepth( samplePoint.z, cameraNear, cameraFar );', // compute linear depth of the sample view Z value
-			'		float delta = sampleDepth - realDepth;', '		if ( delta > minDistance && delta < maxDistance ) {', // if fragment is before sample point, increase occlusion
-			'			occlusion += 1.0;', '		}', '	}', '	occlusion = clamp( occlusion / float( KERNEL_SIZE ), 0.0, 1.0 );', '	gl_FragColor = vec4( vec3( 1.0 - occlusion ), 1.0 );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform sampler2D tNormal;
+		uniform sampler2D tDepth;
+		uniform sampler2D tNoise;
+
+		uniform vec3 kernel[ KERNEL_SIZE ];
+
+		uniform vec2 resolution;
+
+		uniform float cameraNear;
+		uniform float cameraFar;
+		uniform mat4 cameraProjectionMatrix;
+		uniform mat4 cameraInverseProjectionMatrix;
+
+		uniform float kernelRadius;
+		uniform float minDistance; // avoid artifacts caused by neighbour fragments with minimal depth difference
+		uniform float maxDistance; // avoid the influence of fragments which are too far away
+
+		varying vec2 vUv;
+
+		#include <packing>
+
+		float getDepth( const in vec2 screenPosition ) {
+
+			return texture2D( tDepth, screenPosition ).x;
+
+		}
+
+		float getLinearDepth( const in vec2 screenPosition ) {
+
+			#if PERSPECTIVE_CAMERA == 1
+
+				float fragCoordZ = texture2D( tDepth, screenPosition ).x;
+				float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
+				return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
+
+			#else
+
+				return texture2D( tDepth, screenPosition ).x;
+
+			#endif
+
+		}
+
+		float getViewZ( const in float depth ) {
+
+			#if PERSPECTIVE_CAMERA == 1
+
+				return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );
+
+			#else
+
+				return orthographicDepthToViewZ( depth, cameraNear, cameraFar );
+
+			#endif
+
+		}
+
+		vec3 getViewPosition( const in vec2 screenPosition, const in float depth, const in float viewZ ) {
+
+			float clipW = cameraProjectionMatrix[2][3] * viewZ + cameraProjectionMatrix[3][3];
+
+			vec4 clipPosition = vec4( ( vec3( screenPosition, depth ) - 0.5 ) * 2.0, 1.0 );
+
+			clipPosition *= clipW; // unprojection.
+
+			return ( cameraInverseProjectionMatrix * clipPosition ).xyz;
+
+		}
+
+		vec3 getViewNormal( const in vec2 screenPosition ) {
+
+			return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );
+
+		}
+
+		void main() {
+
+			float depth = getDepth( vUv );
+			float viewZ = getViewZ( depth );
+
+			vec3 viewPosition = getViewPosition( vUv, depth, viewZ );
+			vec3 viewNormal = getViewNormal( vUv );
+
+			vec2 noiseScale = vec2( resolution.x / 4.0, resolution.y / 4.0 );
+			vec3 random = texture2D( tNoise, vUv * noiseScale ).xyz;
+
+			// compute matrix used to reorient a kernel vector
+
+			vec3 tangent = normalize( random - viewNormal * dot( random, viewNormal ) );
+			vec3 bitangent = cross( viewNormal, tangent );
+			mat3 kernelMatrix = mat3( tangent, bitangent, viewNormal );
+
+		 float occlusion = 0.0;
+
+		 for ( int i = 0; i < KERNEL_SIZE; i ++ ) {
+
+				vec3 sampleVector = kernelMatrix * kernel[ i ]; // reorient sample vector in view space
+				vec3 samplePoint = viewPosition + ( sampleVector * kernelRadius ); // calculate sample point
+
+				vec4 samplePointNDC = cameraProjectionMatrix * vec4( samplePoint, 1.0 ); // project point and calculate NDC
+				samplePointNDC /= samplePointNDC.w;
+
+				vec2 samplePointUv = samplePointNDC.xy * 0.5 + 0.5; // compute uv coordinates
+
+				float realDepth = getLinearDepth( samplePointUv ); // get linear depth from depth texture
+				float sampleDepth = viewZToOrthographicDepth( samplePoint.z, cameraNear, cameraFar ); // compute linear depth of the sample view Z value
+				float delta = sampleDepth - realDepth;
+
+				if ( delta > minDistance && delta < maxDistance ) { // if fragment is before sample point, increase occlusion
+
+					occlusion += 1.0;
+
+				}
+
+			}
+
+			occlusion = clamp( occlusion / float( KERNEL_SIZE ), 0.0, 1.0 );
+
+			gl_FragColor = vec4( vec3( 1.0 - occlusion ), 1.0 );
+
+		}`
 	};
 	};
-	var SSAODepthShader = {
+	const SSAODepthShader = {
 		defines: {
 		defines: {
 			'PERSPECTIVE_CAMERA': 1
 			'PERSPECTIVE_CAMERA': 1
 		},
 		},
@@ -81,10 +200,47 @@
 				value: null
 				value: null
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDepth;', 'uniform float cameraNear;', 'uniform float cameraFar;', 'varying vec2 vUv;', '#include <packing>', 'float getLinearDepth( const in vec2 screenPosition ) {', '	#if PERSPECTIVE_CAMERA == 1', '		float fragCoordZ = texture2D( tDepth, screenPosition ).x;', '		float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );', '		return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );', '	#else', '		return texture2D( tDepth, screenPosition ).x;', '	#endif', '}', 'void main() {', '	float depth = getLinearDepth( vUv );', '	gl_FragColor = vec4( vec3( 1.0 - depth ), 1.0 );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDepth;
+
+		uniform float cameraNear;
+		uniform float cameraFar;
+
+		varying vec2 vUv;
+
+		#include <packing>
+
+		float getLinearDepth( const in vec2 screenPosition ) {
+
+			#if PERSPECTIVE_CAMERA == 1
+
+				float fragCoordZ = texture2D( tDepth, screenPosition ).x;
+				float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
+				return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
+
+			#else
+
+				return texture2D( tDepth, screenPosition ).x;
+
+			#endif
+
+		}
+
+		void main() {
+
+			float depth = getLinearDepth( vUv );
+			gl_FragColor = vec4( vec3( 1.0 - depth ), 1.0 );
+
+		}`
 	};
 	};
-	var SSAOBlurShader = {
+	const SSAOBlurShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -93,8 +249,39 @@
 				value: new THREE.Vector2()
 				value: new THREE.Vector2()
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform vec2 resolution;', 'varying vec2 vUv;', 'void main() {', '	vec2 texelSize = ( 1.0 / resolution );', '	float result = 0.0;', '	for ( int i = - 2; i <= 2; i ++ ) {', '		for ( int j = - 2; j <= 2; j ++ ) {', '			vec2 offset = ( vec2( float( i ), float( j ) ) ) * texelSize;', '			result += texture2D( tDiffuse, vUv + offset ).r;', '		}', '	}', '	gl_FragColor = vec4( vec3( result / ( 5.0 * 5.0 ) ), 1.0 );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+
+		uniform vec2 resolution;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec2 texelSize = ( 1.0 / resolution );
+			float result = 0.0;
+
+			for ( int i = - 2; i <= 2; i ++ ) {
+
+				for ( int j = - 2; j <= 2; j ++ ) {
+
+					vec2 offset = ( vec2( float( i ), float( j ) ) ) * texelSize;
+					result += texture2D( tDiffuse, vUv + offset ).r;
+
+				}
+
+			}
+
+			gl_FragColor = vec4( vec3( result / ( 5.0 * 5.0 ) ), 1.0 );
+
+		}`
 	};
 	};
 
 
 	THREE.SSAOBlurShader = SSAOBlurShader;
 	THREE.SSAOBlurShader = SSAOBlurShader;

+ 1 - 1
examples/js/shaders/SSRrShader.js

@@ -1,6 +1,6 @@
 ( function () {
 ( function () {
 
 
-	var SSRrShader = {
+	const SSRrShader = {
 		defines: {
 		defines: {
 			MAX_STEP: 0,
 			MAX_STEP: 0,
 			PERSPECTIVE_CAMERA: true,
 			PERSPECTIVE_CAMERA: true,

+ 27 - 3
examples/js/shaders/SepiaShader.js

@@ -5,7 +5,7 @@
  * based on glfx.js sepia shader
  * based on glfx.js sepia shader
  * https://github.com/evanw/glfx.js
  * https://github.com/evanw/glfx.js
  */
  */
-	var SepiaShader = {
+	const SepiaShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -14,8 +14,32 @@
 				value: 1.0
 				value: 1.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float amount;', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'void main() {', '	vec4 color = texture2D( tDiffuse, vUv );', '	vec3 c = color.rgb;', '	color.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );', '	color.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );', '	color.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );', '	gl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float amount;
+
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 color = texture2D( tDiffuse, vUv );
+			vec3 c = color.rgb;
+
+			color.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );
+			color.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );
+			color.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );
+
+			gl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );
+
+		}`
 	};
 	};
 
 
 	THREE.SepiaShader = SepiaShader;
 	THREE.SepiaShader = SepiaShader;

+ 62 - 13
examples/js/shaders/SobelOperatorShader.js

@@ -7,7 +7,7 @@
  *
  *
  */
  */
 
 
-	var SobelOperatorShader = {
+	const SobelOperatorShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -16,18 +16,67 @@
 				value: new THREE.Vector2()
 				value: new THREE.Vector2()
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform vec2 resolution;', 'varying vec2 vUv;', 'void main() {', '	vec2 texel = vec2( 1.0 / resolution.x, 1.0 / resolution.y );', // kernel definition (in glsl matrices are filled in column-major order)
-			'	const mat3 Gx = mat3( -1, -2, -1, 0, 0, 0, 1, 2, 1 );', // x direction kernel
-			'	const mat3 Gy = mat3( -1, 0, 1, -2, 0, 2, -1, 0, 1 );', // y direction kernel
-			// fetch the 3x3 neighbourhood of a fragment
-			// first column
-			'	float tx0y0 = texture2D( tDiffuse, vUv + texel * vec2( -1, -1 ) ).r;', '	float tx0y1 = texture2D( tDiffuse, vUv + texel * vec2( -1,	0 ) ).r;', '	float tx0y2 = texture2D( tDiffuse, vUv + texel * vec2( -1,	1 ) ).r;', // second column
-			'	float tx1y0 = texture2D( tDiffuse, vUv + texel * vec2(	0, -1 ) ).r;', '	float tx1y1 = texture2D( tDiffuse, vUv + texel * vec2(	0,	0 ) ).r;', '	float tx1y2 = texture2D( tDiffuse, vUv + texel * vec2(	0,	1 ) ).r;', // third column
-			'	float tx2y0 = texture2D( tDiffuse, vUv + texel * vec2(	1, -1 ) ).r;', '	float tx2y1 = texture2D( tDiffuse, vUv + texel * vec2(	1,	0 ) ).r;', '	float tx2y2 = texture2D( tDiffuse, vUv + texel * vec2(	1,	1 ) ).r;', // gradient value in x direction
-			'	float valueGx = Gx[0][0] * tx0y0 + Gx[1][0] * tx1y0 + Gx[2][0] * tx2y0 + ', '		Gx[0][1] * tx0y1 + Gx[1][1] * tx1y1 + Gx[2][1] * tx2y1 + ', '		Gx[0][2] * tx0y2 + Gx[1][2] * tx1y2 + Gx[2][2] * tx2y2; ', // gradient value in y direction
-			'	float valueGy = Gy[0][0] * tx0y0 + Gy[1][0] * tx1y0 + Gy[2][0] * tx2y0 + ', '		Gy[0][1] * tx0y1 + Gy[1][1] * tx1y1 + Gy[2][1] * tx2y1 + ', '		Gy[0][2] * tx0y2 + Gy[1][2] * tx1y2 + Gy[2][2] * tx2y2; ', // magnitute of the total gradient
-			'	float G = sqrt( ( valueGx * valueGx ) + ( valueGy * valueGy ) );', '	gl_FragColor = vec4( vec3( G ), 1 );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform vec2 resolution;
+		varying vec2 vUv;
+
+		void main() {
+
+			vec2 texel = vec2( 1.0 / resolution.x, 1.0 / resolution.y );
+
+		// kernel definition (in glsl matrices are filled in column-major order)
+
+			const mat3 Gx = mat3( -1, -2, -1, 0, 0, 0, 1, 2, 1 ); // x direction kernel
+			const mat3 Gy = mat3( -1, 0, 1, -2, 0, 2, -1, 0, 1 ); // y direction kernel
+
+		// fetch the 3x3 neighbourhood of a fragment
+
+		// first column
+
+			float tx0y0 = texture2D( tDiffuse, vUv + texel * vec2( -1, -1 ) ).r;
+			float tx0y1 = texture2D( tDiffuse, vUv + texel * vec2( -1,	0 ) ).r;
+			float tx0y2 = texture2D( tDiffuse, vUv + texel * vec2( -1,	1 ) ).r;
+
+		// second column
+
+			float tx1y0 = texture2D( tDiffuse, vUv + texel * vec2(	0, -1 ) ).r;
+			float tx1y1 = texture2D( tDiffuse, vUv + texel * vec2(	0,	0 ) ).r;
+			float tx1y2 = texture2D( tDiffuse, vUv + texel * vec2(	0,	1 ) ).r;
+
+		// third column
+
+			float tx2y0 = texture2D( tDiffuse, vUv + texel * vec2(	1, -1 ) ).r;
+			float tx2y1 = texture2D( tDiffuse, vUv + texel * vec2(	1,	0 ) ).r;
+			float tx2y2 = texture2D( tDiffuse, vUv + texel * vec2(	1,	1 ) ).r;
+
+		// gradient value in x direction
+
+			float valueGx = Gx[0][0] * tx0y0 + Gx[1][0] * tx1y0 + Gx[2][0] * tx2y0 +
+				Gx[0][1] * tx0y1 + Gx[1][1] * tx1y1 + Gx[2][1] * tx2y1 +
+				Gx[0][2] * tx0y2 + Gx[1][2] * tx1y2 + Gx[2][2] * tx2y2;
+
+		// gradient value in y direction
+
+			float valueGy = Gy[0][0] * tx0y0 + Gy[1][0] * tx1y0 + Gy[2][0] * tx2y0 +
+				Gy[0][1] * tx0y1 + Gy[1][1] * tx1y1 + Gy[2][1] * tx2y1 +
+				Gy[0][2] * tx0y2 + Gy[1][2] * tx1y2 + Gy[2][2] * tx2y2;
+
+		// magnitute of the total gradient
+
+			float G = sqrt( ( valueGx * valueGx ) + ( valueGy * valueGy ) );
+
+			gl_FragColor = vec4( vec3( G ), 1 );
+
+		}`
 	};
 	};
 
 
 	THREE.SobelOperatorShader = SobelOperatorShader;
 	THREE.SobelOperatorShader = SobelOperatorShader;

+ 3 - 3
examples/js/shaders/SubsurfaceScatteringShader.js

@@ -14,9 +14,9 @@
 
 
 	}
 	}
 
 
-	var meshphong_frag_head = THREE.ShaderChunk[ 'meshphong_frag' ].slice( 0, THREE.ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) );
-	var meshphong_frag_body = THREE.ShaderChunk[ 'meshphong_frag' ].slice( THREE.ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) );
-	var SubsurfaceScatteringShader = {
+	const meshphong_frag_head = THREE.ShaderChunk[ 'meshphong_frag' ].slice( 0, THREE.ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) );
+	const meshphong_frag_body = THREE.ShaderChunk[ 'meshphong_frag' ].slice( THREE.ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) );
+	const SubsurfaceScatteringShader = {
 		uniforms: THREE.UniformsUtils.merge( [ THREE.ShaderLib[ 'phong' ].uniforms, {
 		uniforms: THREE.UniformsUtils.merge( [ THREE.ShaderLib[ 'phong' ].uniforms, {
 			'thicknessMap': {
 			'thicknessMap': {
 				value: null
 				value: null

+ 20 - 3
examples/js/shaders/TechnicolorShader.js

@@ -6,14 +6,31 @@
  * More historical info here: http://www.widescreenmuseum.com/oldcolor/technicolor1.htm
  * More historical info here: http://www.widescreenmuseum.com/oldcolor/technicolor1.htm
  * Demo here: http://charliehoey.com/technicolor_shader/shader_test.html
  * Demo here: http://charliehoey.com/technicolor_shader/shader_test.html
  */
  */
-	var TechnicolorShader = {
+	const TechnicolorShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'void main() {', '	vec4 tex = texture2D( tDiffuse, vec2( vUv.x, vUv.y ) );', '	vec4 newTex = vec4(tex.r, (tex.g + tex.b) * .5, (tex.g + tex.b) * .5, 1.0);', '	gl_FragColor = newTex;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 tex = texture2D( tDiffuse, vec2( vUv.x, vUv.y ) );
+			vec4 newTex = vec4(tex.r, (tex.g + tex.b) * .5, (tex.g + tex.b) * .5, 1.0);
+
+			gl_FragColor = newTex;
+
+		}`
 	};
 	};
 
 
 	THREE.TechnicolorShader = TechnicolorShader;
 	THREE.TechnicolorShader = TechnicolorShader;

+ 48 - 5
examples/js/shaders/ToneMapShader.js

@@ -24,11 +24,54 @@
 				value: 0.6
 				value: 0.6
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ '#include <common>', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'uniform float middleGrey;', 'uniform float minLuminance;', 'uniform float maxLuminance;', '#ifdef ADAPTED_LUMINANCE', '	uniform sampler2D luminanceMap;', '#else', '	uniform float averageLuminance;', '#endif', 'vec3 ToneMap( vec3 vColor ) {', '	#ifdef ADAPTED_LUMINANCE', // Get the calculated average luminance
-			'		float fLumAvg = texture2D(luminanceMap, vec2(0.5, 0.5)).r;', '	#else', '		float fLumAvg = averageLuminance;', '	#endif', // Calculate the luminance of the current pixel
-			'	float fLumPixel = linearToRelativeLuminance( vColor );', // Apply the modified operator (Eq. 4)
-			'	float fLumScaled = (fLumPixel * middleGrey) / max( minLuminance, fLumAvg );', '	float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (maxLuminance * maxLuminance)))) / (1.0 + fLumScaled);', '	return fLumCompressed * vColor;', '}', 'void main() {', '	vec4 texel = texture2D( tDiffuse, vUv );', '	gl_FragColor = vec4( ToneMap( texel.xyz ), texel.w );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `#include <common>
+
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		uniform float middleGrey;
+		uniform float minLuminance;
+		uniform float maxLuminance;
+		#ifdef ADAPTED_LUMINANCE
+			uniform sampler2D luminanceMap;
+		#else
+			uniform float averageLuminance;
+		#endif
+
+		vec3 ToneMap( vec3 vColor ) {
+			#ifdef ADAPTED_LUMINANCE
+				// Get the calculated average luminance
+				float fLumAvg = texture2D(luminanceMap, vec2(0.5, 0.5)).r;
+			#else
+				float fLumAvg = averageLuminance;
+			#endif
+
+			// Calculate the luminance of the current pixel
+			float fLumPixel = linearToRelativeLuminance( vColor );
+
+			// Apply the modified operator (Eq. 4)
+			float fLumScaled = (fLumPixel * middleGrey) / max( minLuminance, fLumAvg );
+
+			float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (maxLuminance * maxLuminance)))) / (1.0 + fLumScaled);
+			return fLumCompressed * vColor;
+		}
+
+		void main() {
+
+			vec4 texel = texture2D( tDiffuse, vUv );
+
+			gl_FragColor = vec4( ToneMap( texel.xyz ), texel.w );
+
+		}`
 	};
 	};
 
 
 	THREE.ToneMapShader = ToneMapShader;
 	THREE.ToneMapShader = ToneMapShader;

+ 214 - 12
examples/js/shaders/ToonShader.js

@@ -9,7 +9,7 @@
  *	dotted
  *	dotted
  */
  */
 
 
-	var ToonShader1 = {
+	const ToonShader1 = {
 		uniforms: {
 		uniforms: {
 			'uDirLightPos': {
 			'uDirLightPos': {
 				value: new THREE.Vector3()
 				value: new THREE.Vector3()
@@ -24,10 +24,59 @@
 				value: new THREE.Color( 0xffffff )
 				value: new THREE.Color( 0xffffff )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec3 vNormal;', 'varying vec3 vRefract;', 'void main() {', '	vec4 worldPosition = modelMatrix * vec4( position, 1.0 );', '	vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );', '	vec3 worldNormal = normalize ( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );', '	vNormal = normalize( normalMatrix * normal );', '	vec3 I = worldPosition.xyz - cameraPosition;', '	vRefract = refract( normalize( I ), worldNormal, 1.02 );', '	gl_Position = projectionMatrix * mvPosition;', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform vec3 uBaseColor;', 'uniform vec3 uDirLightPos;', 'uniform vec3 uDirLightColor;', 'uniform vec3 uAmbientLightColor;', 'varying vec3 vNormal;', 'varying vec3 vRefract;', 'void main() {', '	float directionalLightWeighting = max( dot( normalize( vNormal ), uDirLightPos ), 0.0);', '	vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;', '	float intensity = smoothstep( - 0.5, 1.0, pow( length(lightWeighting), 20.0 ) );', '	intensity += length(lightWeighting) * 0.2;', '	float cameraWeighting = dot( normalize( vNormal ), vRefract );', '	intensity += pow( 1.0 - length( cameraWeighting ), 6.0 );', '	intensity = intensity * 0.2 + 0.3;', '	if ( intensity < 0.50 ) {', '		gl_FragColor = vec4( 2.0 * intensity * uBaseColor, 1.0 );', '	} else {', '		gl_FragColor = vec4( 1.0 - 2.0 * ( 1.0 - intensity ) * ( 1.0 - uBaseColor ), 1.0 );', '}', '}' ].join( '\n' )
+		vertexShader: `varying vec3 vNormal;
+		varying vec3 vRefract;
+
+		void main() {
+
+			vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
+			vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+			vec3 worldNormal = normalize ( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
+
+			vNormal = normalize( normalMatrix * normal );
+
+			vec3 I = worldPosition.xyz - cameraPosition;
+			vRefract = refract( normalize( I ), worldNormal, 1.02 );
+
+			gl_Position = projectionMatrix * mvPosition;
+
+		}`,
+		fragmentShader: `uniform vec3 uBaseColor;
+
+		uniform vec3 uDirLightPos;
+		uniform vec3 uDirLightColor;
+
+		uniform vec3 uAmbientLightColor;
+
+		varying vec3 vNormal;
+
+		varying vec3 vRefract;
+
+		void main() {
+
+			float directionalLightWeighting = max( dot( normalize( vNormal ), uDirLightPos ), 0.0);
+			vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;
+
+			float intensity = smoothstep( - 0.5, 1.0, pow( length(lightWeighting), 20.0 ) );
+			intensity += length(lightWeighting) * 0.2;
+
+			float cameraWeighting = dot( normalize( vNormal ), vRefract );
+			intensity += pow( 1.0 - length( cameraWeighting ), 6.0 );
+			intensity = intensity * 0.2 + 0.3;
+
+			if ( intensity < 0.50 ) {
+
+				gl_FragColor = vec4( 2.0 * intensity * uBaseColor, 1.0 );
+
+			} else {
+
+				gl_FragColor = vec4( 1.0 - 2.0 * ( 1.0 - intensity ) * ( 1.0 - uBaseColor ), 1.0 );
+
+		}
+
+		}`
 	};
 	};
-	var ToonShader2 = {
+	const ToonShader2 = {
 		uniforms: {
 		uniforms: {
 			'uDirLightPos': {
 			'uDirLightPos': {
 				value: new THREE.Vector3()
 				value: new THREE.Vector3()
@@ -54,10 +103,49 @@
 				value: new THREE.Color( 0x000000 )
 				value: new THREE.Color( 0x000000 )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec3 vNormal;', 'void main() {', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '	vNormal = normalize( normalMatrix * normal );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform vec3 uBaseColor;', 'uniform vec3 uLineColor1;', 'uniform vec3 uLineColor2;', 'uniform vec3 uLineColor3;', 'uniform vec3 uLineColor4;', 'uniform vec3 uDirLightPos;', 'uniform vec3 uDirLightColor;', 'uniform vec3 uAmbientLightColor;', 'varying vec3 vNormal;', 'void main() {', '	float camera = max( dot( normalize( vNormal ), vec3( 0.0, 0.0, 1.0 ) ), 0.4);', '	float light = max( dot( normalize( vNormal ), uDirLightPos ), 0.0);', '	gl_FragColor = vec4( uBaseColor, 1.0 );', '	if ( length(uAmbientLightColor + uDirLightColor * light) < 1.00 ) {', '		gl_FragColor *= vec4( uLineColor1, 1.0 );', '	}', '	if ( length(uAmbientLightColor + uDirLightColor * camera) < 0.50 ) {', '		gl_FragColor *= vec4( uLineColor2, 1.0 );', '	}', '}' ].join( '\n' )
+		vertexShader: `varying vec3 vNormal;
+
+		void main() {
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+			vNormal = normalize( normalMatrix * normal );
+
+		}`,
+		fragmentShader: `uniform vec3 uBaseColor;
+		uniform vec3 uLineColor1;
+		uniform vec3 uLineColor2;
+		uniform vec3 uLineColor3;
+		uniform vec3 uLineColor4;
+
+		uniform vec3 uDirLightPos;
+		uniform vec3 uDirLightColor;
+
+		uniform vec3 uAmbientLightColor;
+
+		varying vec3 vNormal;
+
+		void main() {
+
+			float camera = max( dot( normalize( vNormal ), vec3( 0.0, 0.0, 1.0 ) ), 0.4);
+			float light = max( dot( normalize( vNormal ), uDirLightPos ), 0.0);
+
+			gl_FragColor = vec4( uBaseColor, 1.0 );
+
+			if ( length(uAmbientLightColor + uDirLightColor * light) < 1.00 ) {
+
+				gl_FragColor *= vec4( uLineColor1, 1.0 );
+
+			}
+
+			if ( length(uAmbientLightColor + uDirLightColor * camera) < 0.50 ) {
+
+				gl_FragColor *= vec4( uLineColor2, 1.0 );
+
+			}
+
+		}`
 	};
 	};
-	var ToonShaderHatching = {
+	const ToonShaderHatching = {
 		uniforms: {
 		uniforms: {
 			'uDirLightPos': {
 			'uDirLightPos': {
 				value: new THREE.Vector3()
 				value: new THREE.Vector3()
@@ -84,10 +172,77 @@
 				value: new THREE.Color( 0x000000 )
 				value: new THREE.Color( 0x000000 )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec3 vNormal;', 'void main() {', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '	vNormal = normalize( normalMatrix * normal );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform vec3 uBaseColor;', 'uniform vec3 uLineColor1;', 'uniform vec3 uLineColor2;', 'uniform vec3 uLineColor3;', 'uniform vec3 uLineColor4;', 'uniform vec3 uDirLightPos;', 'uniform vec3 uDirLightColor;', 'uniform vec3 uAmbientLightColor;', 'varying vec3 vNormal;', 'void main() {', '	float directionalLightWeighting = max( dot( normalize(vNormal), uDirLightPos ), 0.0);', '	vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;', '	gl_FragColor = vec4( uBaseColor, 1.0 );', '	if ( length(lightWeighting) < 1.00 ) {', '		if ( mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {', '			gl_FragColor = vec4( uLineColor1, 1.0 );', '		}', '	}', '	if ( length(lightWeighting) < 0.75 ) {', '		if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {', '			gl_FragColor = vec4( uLineColor2, 1.0 );', '		}', '	}', '	if ( length(lightWeighting) < 0.50 ) {', '		if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {', '			gl_FragColor = vec4( uLineColor3, 1.0 );', '		}', '	}', '	if ( length(lightWeighting) < 0.3465 ) {', '		if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {', '			gl_FragColor = vec4( uLineColor4, 1.0 );', '	}', '	}', '}' ].join( '\n' )
+		vertexShader: `varying vec3 vNormal;
+
+		void main() {
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+			vNormal = normalize( normalMatrix * normal );
+
+		}`,
+		fragmentShader: `uniform vec3 uBaseColor;
+		uniform vec3 uLineColor1;
+		uniform vec3 uLineColor2;
+		uniform vec3 uLineColor3;
+		uniform vec3 uLineColor4;
+
+		uniform vec3 uDirLightPos;
+		uniform vec3 uDirLightColor;
+
+		uniform vec3 uAmbientLightColor;
+
+		varying vec3 vNormal;
+
+		void main() {
+
+			float directionalLightWeighting = max( dot( normalize(vNormal), uDirLightPos ), 0.0);
+			vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;
+
+			gl_FragColor = vec4( uBaseColor, 1.0 );
+
+			if ( length(lightWeighting) < 1.00 ) {
+
+				if ( mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {
+
+					gl_FragColor = vec4( uLineColor1, 1.0 );
+
+				}
+
+			}
+
+			if ( length(lightWeighting) < 0.75 ) {
+
+				if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {
+
+					gl_FragColor = vec4( uLineColor2, 1.0 );
+
+				}
+
+			}
+
+			if ( length(lightWeighting) < 0.50 ) {
+
+				if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {
+
+					gl_FragColor = vec4( uLineColor3, 1.0 );
+
+				}
+
+			}
+
+			if ( length(lightWeighting) < 0.3465 ) {
+
+				if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {
+
+					gl_FragColor = vec4( uLineColor4, 1.0 );
+
+			}
+
+			}
+
+		}`
 	};
 	};
-	var ToonShaderDotted = {
+	const ToonShaderDotted = {
 		uniforms: {
 		uniforms: {
 			'uDirLightPos': {
 			'uDirLightPos': {
 				value: new THREE.Vector3()
 				value: new THREE.Vector3()
@@ -105,8 +260,55 @@
 				value: new THREE.Color( 0x000000 )
 				value: new THREE.Color( 0x000000 )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec3 vNormal;', 'void main() {', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '	vNormal = normalize( normalMatrix * normal );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform vec3 uBaseColor;', 'uniform vec3 uLineColor1;', 'uniform vec3 uLineColor2;', 'uniform vec3 uLineColor3;', 'uniform vec3 uLineColor4;', 'uniform vec3 uDirLightPos;', 'uniform vec3 uDirLightColor;', 'uniform vec3 uAmbientLightColor;', 'varying vec3 vNormal;', 'void main() {', 'float directionalLightWeighting = max( dot( normalize(vNormal), uDirLightPos ), 0.0);', 'vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;', 'gl_FragColor = vec4( uBaseColor, 1.0 );', 'if ( length(lightWeighting) < 1.00 ) {', '		if ( ( mod(gl_FragCoord.x, 4.001) + mod(gl_FragCoord.y, 4.0) ) > 6.00 ) {', '			gl_FragColor = vec4( uLineColor1, 1.0 );', '		}', '	}', '	if ( length(lightWeighting) < 0.50 ) {', '		if ( ( mod(gl_FragCoord.x + 2.0, 4.001) + mod(gl_FragCoord.y + 2.0, 4.0) ) > 6.00 ) {', '			gl_FragColor = vec4( uLineColor1, 1.0 );', '		}', '	}', '}' ].join( '\n' )
+		vertexShader: `varying vec3 vNormal;
+
+		void main() {
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+			vNormal = normalize( normalMatrix * normal );
+
+		}`,
+		fragmentShader: `uniform vec3 uBaseColor;
+		uniform vec3 uLineColor1;
+		uniform vec3 uLineColor2;
+		uniform vec3 uLineColor3;
+		uniform vec3 uLineColor4;
+
+		uniform vec3 uDirLightPos;
+		uniform vec3 uDirLightColor;
+
+		uniform vec3 uAmbientLightColor;
+
+		varying vec3 vNormal;
+
+		void main() {
+
+		float directionalLightWeighting = max( dot( normalize(vNormal), uDirLightPos ), 0.0);
+		vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;
+
+		gl_FragColor = vec4( uBaseColor, 1.0 );
+
+		if ( length(lightWeighting) < 1.00 ) {
+
+				if ( ( mod(gl_FragCoord.x, 4.001) + mod(gl_FragCoord.y, 4.0) ) > 6.00 ) {
+
+					gl_FragColor = vec4( uLineColor1, 1.0 );
+
+				}
+
+			}
+
+			if ( length(lightWeighting) < 0.50 ) {
+
+				if ( ( mod(gl_FragCoord.x + 2.0, 4.001) + mod(gl_FragCoord.y + 2.0, 4.0) ) > 6.00 ) {
+
+					gl_FragColor = vec4( uLineColor1, 1.0 );
+
+				}
+
+			}
+
+		}`
 	};
 	};
 
 
 	THREE.ToonShader1 = ToonShader1;
 	THREE.ToonShader1 = ToonShader1;

+ 41 - 4
examples/js/shaders/TriangleBlurShader.js

@@ -10,7 +10,7 @@
  * perpendicular triangle filters.
  * perpendicular triangle filters.
  */
  */
 
 
-	var TriangleBlurShader = {
+	const TriangleBlurShader = {
 		uniforms: {
 		uniforms: {
 			'texture': {
 			'texture': {
 				value: null
 				value: null
@@ -19,9 +19,46 @@
 				value: new THREE.Vector2( 1, 1 )
 				value: new THREE.Vector2( 1, 1 )
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ '#include <common>', '#define ITERATIONS 10.0', 'uniform sampler2D texture;', 'uniform vec2 delta;', 'varying vec2 vUv;', 'void main() {', '	vec4 color = vec4( 0.0 );', '	float total = 0.0;', // randomize the lookup values to hide the fixed number of samples
-			'	float offset = rand( vUv );', '	for ( float t = -ITERATIONS; t <= ITERATIONS; t ++ ) {', '		float percent = ( t + offset - 0.5 ) / ITERATIONS;', '		float weight = 1.0 - abs( percent );', '		color += texture2D( texture, vUv + delta * percent ) * weight;', '		total += weight;', '	}', '	gl_FragColor = color / total;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `#include <common>
+
+		#define ITERATIONS 10.0
+
+		uniform sampler2D texture;
+		uniform vec2 delta;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 color = vec4( 0.0 );
+
+			float total = 0.0;
+
+		// randomize the lookup values to hide the fixed number of samples
+
+			float offset = rand( vUv );
+
+			for ( float t = -ITERATIONS; t <= ITERATIONS; t ++ ) {
+
+				float percent = ( t + offset - 0.5 ) / ITERATIONS;
+				float weight = 1.0 - abs( percent );
+
+				color += texture2D( texture, vUv + delta * percent ) * weight;
+				total += weight;
+
+			}
+
+			gl_FragColor = color / total;
+
+		}`
 	};
 	};
 
 
 	THREE.TriangleBlurShader = TriangleBlurShader;
 	THREE.TriangleBlurShader = TriangleBlurShader;

+ 23 - 3
examples/js/shaders/UnpackDepthRGBAShader.js

@@ -4,7 +4,7 @@
  * Unpack RGBA depth shader
  * Unpack RGBA depth shader
  * - show RGBA encoded depth as monochrome color
  * - show RGBA encoded depth as monochrome color
  */
  */
-	var UnpackDepthRGBAShader = {
+	const UnpackDepthRGBAShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -13,8 +13,28 @@
 				value: 1.0
 				value: 1.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float opacity;', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', '#include <packing>', 'void main() {', '	float depth = 1.0 - unpackRGBAToDepth( texture2D( tDiffuse, vUv ) );', '	gl_FragColor = vec4( vec3( depth ), opacity );', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float opacity;
+
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		#include <packing>
+
+		void main() {
+
+			float depth = 1.0 - unpackRGBAToDepth( texture2D( tDiffuse, vUv ) );
+			gl_FragColor = vec4( vec3( depth ), opacity );
+
+		}`
 	};
 	};
 
 
 	THREE.UnpackDepthRGBAShader = UnpackDepthRGBAShader;
 	THREE.UnpackDepthRGBAShader = UnpackDepthRGBAShader;

+ 31 - 3
examples/js/shaders/VerticalBlurShader.js

@@ -9,7 +9,7 @@
  * - standard deviation 2.7
  * - standard deviation 2.7
  * - "h" and "v" parameters should be set to "1 / width" and "1 / height"
  * - "h" and "v" parameters should be set to "1 / width" and "1 / height"
  */
  */
-	var VerticalBlurShader = {
+	const VerticalBlurShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -18,8 +18,36 @@
 				value: 1.0 / 512.0
 				value: 1.0 / 512.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform float v;', 'varying vec2 vUv;', 'void main() {', '	vec4 sum = vec4( 0.0 );', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;', '	gl_FragColor = sum;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform float v;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 sum = vec4( 0.0 );
+
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;
+
+			gl_FragColor = sum;
+
+		}`
 	};
 	};
 
 
 	THREE.VerticalBlurShader = VerticalBlurShader;
 	THREE.VerticalBlurShader = VerticalBlurShader;

+ 34 - 3
examples/js/shaders/VerticalTiltShiftShader.js

@@ -8,7 +8,7 @@
  * - "h" and "v" parameters should be set to "1 / width" and "1 / height"
  * - "h" and "v" parameters should be set to "1 / width" and "1 / height"
  * - "r" parameter control where "focused" horizontal line lies
  * - "r" parameter control where "focused" horizontal line lies
  */
  */
-	var VerticalTiltShiftShader = {
+	const VerticalTiltShiftShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -20,8 +20,39 @@
 				value: 0.35
 				value: 0.35
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform sampler2D tDiffuse;', 'uniform float v;', 'uniform float r;', 'varying vec2 vUv;', 'void main() {', '	vec4 sum = vec4( 0.0 );', '	float vv = v * abs( r - vUv.y );', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;', '	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;', '	gl_FragColor = sum;', '}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform sampler2D tDiffuse;
+		uniform float v;
+		uniform float r;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			vec4 sum = vec4( 0.0 );
+
+			float vv = v * abs( r - vUv.y );
+
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;
+
+			gl_FragColor = sum;
+
+		}`
 	};
 	};
 
 
 	THREE.VerticalTiltShiftShader = VerticalTiltShiftShader;
 	THREE.VerticalTiltShiftShader = VerticalTiltShiftShader;

+ 25 - 13
examples/js/shaders/VignetteShader.js

@@ -5,7 +5,7 @@
  * based on PaintEffect postprocess from ro.me
  * based on PaintEffect postprocess from ro.me
  * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js
  * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js
  */
  */
-	var VignetteShader = {
+	const VignetteShader = {
 		uniforms: {
 		uniforms: {
 			'tDiffuse': {
 			'tDiffuse': {
 				value: null
 				value: null
@@ -17,18 +17,30 @@
 				value: 1.0
 				value: 1.0
 			}
 			}
 		},
 		},
-		vertexShader: [ 'varying vec2 vUv;', 'void main() {', '	vUv = uv;', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform float offset;', 'uniform float darkness;', 'uniform sampler2D tDiffuse;', 'varying vec2 vUv;', 'void main() {', // Eskil's vignette
-			'	vec4 texel = texture2D( tDiffuse, vUv );', '	vec2 uv = ( vUv - vec2( 0.5 ) ) * vec2( offset );', '	gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );',
-			/*
-	// alternative version from glfx.js
-	// this one makes more "dusty" look (as opposed to "burned")
-		"	vec4 color = texture2D( tDiffuse, vUv );",
-	"	float dist = distance( vUv, vec2( 0.5 ) );",
-	"	color.rgb *= smoothstep( 0.8, offset * 0.799, dist *( darkness + offset ) );",
-	"	gl_FragColor = color;",
-	*/
-			'}' ].join( '\n' )
+		vertexShader: `varying vec2 vUv;
+
+		void main() {
+
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform float offset;
+		uniform float darkness;
+
+		uniform sampler2D tDiffuse;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			// Eskil's vignette
+
+			vec4 texel = texture2D( tDiffuse, vUv );
+			vec2 uv = ( vUv - vec2( 0.5 ) ) * vec2( offset );
+			gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );
+
+		}`
 	};
 	};
 
 
 	THREE.VignetteShader = VignetteShader;
 	THREE.VignetteShader = VignetteShader;

+ 259 - 50
examples/js/shaders/VolumeShader.js

@@ -6,7 +6,7 @@
  * This is not the only approach, therefore it's marked 1.
  * This is not the only approach, therefore it's marked 1.
  */
  */
 
 
-	var VolumeRenderShader1 = {
+	const VolumeRenderShader1 = {
 		uniforms: {
 		uniforms: {
 			'u_size': {
 			'u_size': {
 				value: new THREE.Vector3( 1, 1, 1 )
 				value: new THREE.Vector3( 1, 1, 1 )
@@ -27,55 +27,264 @@
 				value: null
 				value: null
 			}
 			}
 		},
 		},
-		vertexShader: [ '		varying vec4 v_nearpos;', '		varying vec4 v_farpos;', '		varying vec3 v_position;', '		void main() {', // Prepare transforms to map to "camera view". See also:
-			// https://threejs.org/docs/#api/renderers/webgl/WebGLProgram
-			'				mat4 viewtransformf = modelViewMatrix;', '				mat4 viewtransformi = inverse(modelViewMatrix);', // Project local vertex coordinate to camera position. Then do a step
-			// backward (in cam coords) to the near clipping plane, and project back. Do
-			// the same for the far clipping plane. This gives us all the information we
-			// need to calculate the ray and truncate it to the viewing cone.
-			'				vec4 position4 = vec4(position, 1.0);', '				vec4 pos_in_cam = viewtransformf * position4;', // Intersection of ray and near clipping plane (z = -1 in clip coords)
-			'				pos_in_cam.z = -pos_in_cam.w;', '				v_nearpos = viewtransformi * pos_in_cam;', // Intersection of ray and far clipping plane (z = +1 in clip coords)
-			'				pos_in_cam.z = pos_in_cam.w;', '				v_farpos = viewtransformi * pos_in_cam;', // Set varyings and output pos
-			'				v_position = position;', '				gl_Position = projectionMatrix * viewMatrix * modelMatrix * position4;', '		}' ].join( '\n' ),
-		fragmentShader: [ '		precision highp float;', '		precision mediump sampler3D;', '		uniform vec3 u_size;', '		uniform int u_renderstyle;', '		uniform float u_renderthreshold;', '		uniform vec2 u_clim;', '		uniform sampler3D u_data;', '		uniform sampler2D u_cmdata;', '		varying vec3 v_position;', '		varying vec4 v_nearpos;', '		varying vec4 v_farpos;', // The maximum distance through our rendering volume is sqrt(3).
-			'		const int MAX_STEPS = 887;	// 887 for 512^3, 1774 for 1024^3', '		const int REFINEMENT_STEPS = 4;', '		const float relative_step_size = 1.0;', '		const vec4 ambient_color = vec4(0.2, 0.4, 0.2, 1.0);', '		const vec4 diffuse_color = vec4(0.8, 0.2, 0.2, 1.0);', '		const vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);', '		const float shininess = 40.0;', '		void cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);', '		void cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);', '		float sample1(vec3 texcoords);', '		vec4 apply_colormap(float val);', '		vec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray);', '		void main() {', // Normalize clipping plane info
-			'				vec3 farpos = v_farpos.xyz / v_farpos.w;', '				vec3 nearpos = v_nearpos.xyz / v_nearpos.w;', // Calculate unit vector pointing in the view direction through this fragment.
-			'				vec3 view_ray = normalize(nearpos.xyz - farpos.xyz);', // Compute the (negative) distance to the front surface or near clipping plane.
-			// v_position is the back face of the cuboid, so the initial distance calculated in the dot
-			// product below is the distance from near clip plane to the back of the cuboid
-			'				float distance = dot(nearpos - v_position, view_ray);', '				distance = max(distance, min((-0.5 - v_position.x) / view_ray.x,', '																		(u_size.x - 0.5 - v_position.x) / view_ray.x));', '				distance = max(distance, min((-0.5 - v_position.y) / view_ray.y,', '																		(u_size.y - 0.5 - v_position.y) / view_ray.y));', '				distance = max(distance, min((-0.5 - v_position.z) / view_ray.z,', '																		(u_size.z - 0.5 - v_position.z) / view_ray.z));', // Now we have the starting position on the front surface
-			'				vec3 front = v_position + view_ray * distance;', // Decide how many steps to take
-			'				int nsteps = int(-distance / relative_step_size + 0.5);', '				if ( nsteps < 1 )', '						discard;', // Get starting location and step vector in texture coordinates
-			'				vec3 step = ((v_position - front) / u_size) / float(nsteps);', '				vec3 start_loc = front / u_size;', // For testing: show the number of steps. This helps to establish
-			// whether the rays are correctly oriented
-			//'gl_FragColor = vec4(0.0, float(nsteps) / 1.0 / u_size.x, 1.0, 1.0);',
-			//'return;',
-			'				if (u_renderstyle == 0)', '						cast_mip(start_loc, step, nsteps, view_ray);', '				else if (u_renderstyle == 1)', '						cast_iso(start_loc, step, nsteps, view_ray);', '				if (gl_FragColor.a < 0.05)', '						discard;', '		}', '		float sample1(vec3 texcoords) {', '				/* Sample float value from a 3D texture. Assumes intensity data. */', '				return texture(u_data, texcoords.xyz).r;', '		}', '		vec4 apply_colormap(float val) {', '				val = (val - u_clim[0]) / (u_clim[1] - u_clim[0]);', '				return texture2D(u_cmdata, vec2(val, 0.5));', '		}', '		void cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {', '				float max_val = -1e6;', '				int max_i = 100;', '				vec3 loc = start_loc;', // Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with
-			// non-constant expression. So we use a hard-coded max, and an additional condition
-			// inside the loop.
-			'				for (int iter=0; iter<MAX_STEPS; iter++) {', '						if (iter >= nsteps)', '								break;', // Sample from the 3D texture
-			'						float val = sample1(loc);', // Apply MIP operation
-			'						if (val > max_val) {', '								max_val = val;', '								max_i = iter;', '						}', // Advance location deeper into the volume
-			'						loc += step;', '				}', // Refine location, gives crispier images
-			'				vec3 iloc = start_loc + step * (float(max_i) - 0.5);', '				vec3 istep = step / float(REFINEMENT_STEPS);', '				for (int i=0; i<REFINEMENT_STEPS; i++) {', '						max_val = max(max_val, sample1(iloc));', '						iloc += istep;', '				}', // Resolve final color
-			'				gl_FragColor = apply_colormap(max_val);', '		}', '		void cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {', '				gl_FragColor = vec4(0.0);	// init transparent', '				vec4 color3 = vec4(0.0);	// final color', '				vec3 dstep = 1.5 / u_size;	// step to sample derivative', '				vec3 loc = start_loc;', '				float low_threshold = u_renderthreshold - 0.02 * (u_clim[1] - u_clim[0]);', // Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with
-			// non-constant expression. So we use a hard-coded max, and an additional condition
-			// inside the loop.
-			'				for (int iter=0; iter<MAX_STEPS; iter++) {', '						if (iter >= nsteps)', '								break;', // Sample from the 3D texture
-			'						float val = sample1(loc);', '						if (val > low_threshold) {', // Take the last interval in smaller steps
-			'								vec3 iloc = loc - 0.5 * step;', '								vec3 istep = step / float(REFINEMENT_STEPS);', '								for (int i=0; i<REFINEMENT_STEPS; i++) {', '										val = sample1(iloc);', '										if (val > u_renderthreshold) {', '												gl_FragColor = add_lighting(val, iloc, dstep, view_ray);', '												return;', '										}', '										iloc += istep;', '								}', '						}', // Advance location deeper into the volume
-			'						loc += step;', '				}', '		}', '		vec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray)', '		{', // Calculate color by incorporating lighting
-			// View direction
-			'				vec3 V = normalize(view_ray);', // calculate normal vector from gradient
-			'				vec3 N;', '				float val1, val2;', '				val1 = sample1(loc + vec3(-step[0], 0.0, 0.0));', '				val2 = sample1(loc + vec3(+step[0], 0.0, 0.0));', '				N[0] = val1 - val2;', '				val = max(max(val1, val2), val);', '				val1 = sample1(loc + vec3(0.0, -step[1], 0.0));', '				val2 = sample1(loc + vec3(0.0, +step[1], 0.0));', '				N[1] = val1 - val2;', '				val = max(max(val1, val2), val);', '				val1 = sample1(loc + vec3(0.0, 0.0, -step[2]));', '				val2 = sample1(loc + vec3(0.0, 0.0, +step[2]));', '				N[2] = val1 - val2;', '				val = max(max(val1, val2), val);', '				float gm = length(N); // gradient magnitude', '				N = normalize(N);', // Flip normal so it points towards viewer
-			'				float Nselect = float(dot(N, V) > 0.0);', '				N = (2.0 * Nselect - 1.0) * N;	// ==	Nselect * N - (1.0-Nselect)*N;', // Init colors
-			'				vec4 ambient_color = vec4(0.0, 0.0, 0.0, 0.0);', '				vec4 diffuse_color = vec4(0.0, 0.0, 0.0, 0.0);', '				vec4 specular_color = vec4(0.0, 0.0, 0.0, 0.0);', // note: could allow multiple lights
-			'				for (int i=0; i<1; i++)', '				{', // Get light direction (make sure to prevent zero devision)
-			'						vec3 L = normalize(view_ray);	//lightDirs[i];', '						float lightEnabled = float( length(L) > 0.0 );', '						L = normalize(L + (1.0 - lightEnabled));', // Calculate lighting properties
-			'						float lambertTerm = clamp(dot(N, L), 0.0, 1.0);', '						vec3 H = normalize(L+V); // Halfway vector', '						float specularTerm = pow(max(dot(H, N), 0.0), shininess);', // Calculate mask
-			'						float mask1 = lightEnabled;', // Calculate colors
-			'						ambient_color +=	mask1 * ambient_color;	// * gl_LightSource[i].ambient;', '						diffuse_color +=	mask1 * lambertTerm;', '						specular_color += mask1 * specularTerm * specular_color;', '				}', // Calculate final color by componing different components
-			'				vec4 final_color;', '				vec4 color = apply_colormap(val);', '				final_color = color * (ambient_color + diffuse_color) + specular_color;', '				final_color.a = color.a;', '				return final_color;', '		}' ].join( '\n' )
+		vertexShader: `varying vec4 v_nearpos;
+		varying vec4 v_farpos;
+		varying vec3 v_position;
+
+		void main() {
+				// Prepare transforms to map to "camera view". See also:
+				// https://threejs.org/docs/#api/renderers/webgl/WebGLProgram
+				mat4 viewtransformf = modelViewMatrix;
+				mat4 viewtransformi = inverse(modelViewMatrix);
+
+				// Project local vertex coordinate to camera position. Then do a step
+				// backward (in cam coords) to the near clipping plane, and project back. Do
+				// the same for the far clipping plane. This gives us all the information we
+				// need to calculate the ray and truncate it to the viewing cone.
+				vec4 position4 = vec4(position, 1.0);
+				vec4 pos_in_cam = viewtransformf * position4;
+
+				// Intersection of ray and near clipping plane (z = -1 in clip coords)
+				pos_in_cam.z = -pos_in_cam.w;
+				v_nearpos = viewtransformi * pos_in_cam;
+
+				// Intersection of ray and far clipping plane (z = +1 in clip coords)
+				pos_in_cam.z = pos_in_cam.w;
+				v_farpos = viewtransformi * pos_in_cam;
+
+				// Set varyings and output pos
+				v_position = position;
+				gl_Position = projectionMatrix * viewMatrix * modelMatrix * position4;
+		}`,
+		fragmentShader: `precision highp float;
+				precision mediump sampler3D;
+
+				uniform vec3 u_size;
+				uniform int u_renderstyle;
+				uniform float u_renderthreshold;
+				uniform vec2 u_clim;
+
+				uniform sampler3D u_data;
+				uniform sampler2D u_cmdata;
+
+				varying vec3 v_position;
+				varying vec4 v_nearpos;
+				varying vec4 v_farpos;
+
+				// The maximum distance through our rendering volume is sqrt(3).
+				const int MAX_STEPS = 887;	// 887 for 512^3, 1774 for 1024^3
+				const int REFINEMENT_STEPS = 4;
+				const float relative_step_size = 1.0;
+				const vec4 ambient_color = vec4(0.2, 0.4, 0.2, 1.0);
+				const vec4 diffuse_color = vec4(0.8, 0.2, 0.2, 1.0);
+				const vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);
+				const float shininess = 40.0;
+
+				void cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);
+				void cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);
+
+				float sample1(vec3 texcoords);
+				vec4 apply_colormap(float val);
+				vec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray);
+
+
+				void main() {
+						// Normalize clipping plane info
+						vec3 farpos = v_farpos.xyz / v_farpos.w;
+						vec3 nearpos = v_nearpos.xyz / v_nearpos.w;
+
+						// Calculate unit vector pointing in the view direction through this fragment.
+						vec3 view_ray = normalize(nearpos.xyz - farpos.xyz);
+
+						// Compute the (negative) distance to the front surface or near clipping plane.
+						// v_position is the back face of the cuboid, so the initial distance calculated in the dot
+						// product below is the distance from near clip plane to the back of the cuboid
+						float distance = dot(nearpos - v_position, view_ray);
+						distance = max(distance, min((-0.5 - v_position.x) / view_ray.x,
+																				(u_size.x - 0.5 - v_position.x) / view_ray.x));
+						distance = max(distance, min((-0.5 - v_position.y) / view_ray.y,
+																				(u_size.y - 0.5 - v_position.y) / view_ray.y));
+						distance = max(distance, min((-0.5 - v_position.z) / view_ray.z,
+																				(u_size.z - 0.5 - v_position.z) / view_ray.z));
+
+						// Now we have the starting position on the front surface
+						vec3 front = v_position + view_ray * distance;
+
+						// Decide how many steps to take
+						int nsteps = int(-distance / relative_step_size + 0.5);
+						if ( nsteps < 1 )
+								discard;
+
+						// Get starting location and step vector in texture coordinates
+						vec3 step = ((v_position - front) / u_size) / float(nsteps);
+						vec3 start_loc = front / u_size;
+
+						// For testing: show the number of steps. This helps to establish
+						// whether the rays are correctly oriented
+						//'gl_FragColor = vec4(0.0, float(nsteps) / 1.0 / u_size.x, 1.0, 1.0);
+						//'return;
+
+						if (u_renderstyle == 0)
+								cast_mip(start_loc, step, nsteps, view_ray);
+						else if (u_renderstyle == 1)
+								cast_iso(start_loc, step, nsteps, view_ray);
+
+						if (gl_FragColor.a < 0.05)
+								discard;
+				}
+
+
+				float sample1(vec3 texcoords) {
+						/* Sample float value from a 3D texture. Assumes intensity data. */
+						return texture(u_data, texcoords.xyz).r;
+				}
+
+
+				vec4 apply_colormap(float val) {
+						val = (val - u_clim[0]) / (u_clim[1] - u_clim[0]);
+						return texture2D(u_cmdata, vec2(val, 0.5));
+				}
+
+
+				void cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {
+
+						float max_val = -1e6;
+						int max_i = 100;
+						vec3 loc = start_loc;
+
+						// Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with
+						// non-constant expression. So we use a hard-coded max, and an additional condition
+						// inside the loop.
+						for (int iter=0; iter<MAX_STEPS; iter++) {
+								if (iter >= nsteps)
+										break;
+								// Sample from the 3D texture
+								float val = sample1(loc);
+								// Apply MIP operation
+								if (val > max_val) {
+										max_val = val;
+										max_i = iter;
+								}
+								// Advance location deeper into the volume
+								loc += step;
+						}
+
+						// Refine location, gives crispier images
+						vec3 iloc = start_loc + step * (float(max_i) - 0.5);
+						vec3 istep = step / float(REFINEMENT_STEPS);
+						for (int i=0; i<REFINEMENT_STEPS; i++) {
+								max_val = max(max_val, sample1(iloc));
+								iloc += istep;
+						}
+
+						// Resolve final color
+						gl_FragColor = apply_colormap(max_val);
+				}
+
+
+				void cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {
+
+						gl_FragColor = vec4(0.0);	// init transparent
+						vec4 color3 = vec4(0.0);	// final color
+						vec3 dstep = 1.5 / u_size;	// step to sample derivative
+						vec3 loc = start_loc;
+
+						float low_threshold = u_renderthreshold - 0.02 * (u_clim[1] - u_clim[0]);
+
+						// Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with
+						// non-constant expression. So we use a hard-coded max, and an additional condition
+						// inside the loop.
+						for (int iter=0; iter<MAX_STEPS; iter++) {
+								if (iter >= nsteps)
+										break;
+
+								// Sample from the 3D texture
+								float val = sample1(loc);
+
+								if (val > low_threshold) {
+										// Take the last interval in smaller steps
+										vec3 iloc = loc - 0.5 * step;
+										vec3 istep = step / float(REFINEMENT_STEPS);
+										for (int i=0; i<REFINEMENT_STEPS; i++) {
+												val = sample1(iloc);
+												if (val > u_renderthreshold) {
+														gl_FragColor = add_lighting(val, iloc, dstep, view_ray);
+														return;
+												}
+												iloc += istep;
+										}
+								}
+
+								// Advance location deeper into the volume
+								loc += step;
+						}
+				}
+
+
+				vec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray)
+				{
+					// Calculate color by incorporating lighting
+
+						// View direction
+						vec3 V = normalize(view_ray);
+
+						// calculate normal vector from gradient
+						vec3 N;
+						float val1, val2;
+						val1 = sample1(loc + vec3(-step[0], 0.0, 0.0));
+						val2 = sample1(loc + vec3(+step[0], 0.0, 0.0));
+						N[0] = val1 - val2;
+						val = max(max(val1, val2), val);
+						val1 = sample1(loc + vec3(0.0, -step[1], 0.0));
+						val2 = sample1(loc + vec3(0.0, +step[1], 0.0));
+						N[1] = val1 - val2;
+						val = max(max(val1, val2), val);
+						val1 = sample1(loc + vec3(0.0, 0.0, -step[2]));
+						val2 = sample1(loc + vec3(0.0, 0.0, +step[2]));
+						N[2] = val1 - val2;
+						val = max(max(val1, val2), val);
+
+						float gm = length(N); // gradient magnitude
+						N = normalize(N);
+
+						// Flip normal so it points towards viewer
+						float Nselect = float(dot(N, V) > 0.0);
+						N = (2.0 * Nselect - 1.0) * N;	// ==	Nselect * N - (1.0-Nselect)*N;
+
+						// Init colors
+						vec4 ambient_color = vec4(0.0, 0.0, 0.0, 0.0);
+						vec4 diffuse_color = vec4(0.0, 0.0, 0.0, 0.0);
+						vec4 specular_color = vec4(0.0, 0.0, 0.0, 0.0);
+
+						// note: could allow multiple lights
+						for (int i=0; i<1; i++)
+						{
+								 // Get light direction (make sure to prevent zero devision)
+								vec3 L = normalize(view_ray);	//lightDirs[i];
+								float lightEnabled = float( length(L) > 0.0 );
+								L = normalize(L + (1.0 - lightEnabled));
+
+								// Calculate lighting properties
+								float lambertTerm = clamp(dot(N, L), 0.0, 1.0);
+								vec3 H = normalize(L+V); // Halfway vector
+								float specularTerm = pow(max(dot(H, N), 0.0), shininess);
+
+								// Calculate mask
+								float mask1 = lightEnabled;
+
+								// Calculate colors
+								ambient_color +=	mask1 * ambient_color;	// * gl_LightSource[i].ambient;
+								diffuse_color +=	mask1 * lambertTerm;
+								specular_color += mask1 * specularTerm * specular_color;
+						}
+
+						// Calculate final color by componing different components
+						vec4 final_color;
+						vec4 color = apply_colormap(val);
+						final_color = color * (ambient_color + diffuse_color) + specular_color;
+						final_color.a = color.a;
+						return final_color;
+				}`
 	};
 	};
 
 
 	THREE.VolumeRenderShader1 = VolumeRenderShader1;
 	THREE.VolumeRenderShader1 = VolumeRenderShader1;

+ 56 - 5
examples/js/shaders/WaterRefractionShader.js

@@ -1,6 +1,6 @@
 ( function () {
 ( function () {
 
 
-	var WaterRefractionShader = {
+	const WaterRefractionShader = {
 		uniforms: {
 		uniforms: {
 			'color': {
 			'color': {
 				value: null
 				value: null
@@ -18,10 +18,61 @@
 				value: null
 				value: null
 			}
 			}
 		},
 		},
-		vertexShader: [ 'uniform mat4 textureMatrix;', 'varying vec2 vUv;', 'varying vec4 vUvRefraction;', 'void main() {', '	vUv = uv;', '	vUvRefraction = textureMatrix * vec4( position, 1.0 );', '	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ),
-		fragmentShader: [ 'uniform vec3 color;', 'uniform float time;', 'uniform sampler2D tDiffuse;', 'uniform sampler2D tDudv;', 'varying vec2 vUv;', 'varying vec4 vUvRefraction;', 'float blendOverlay( float base, float blend ) {', '	return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );', '}', 'vec3 blendOverlay( vec3 base, vec3 blend ) {', '	return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ),blendOverlay( base.b, blend.b ) );', '}', 'void main() {', ' float waveStrength = 0.1;', ' float waveSpeed = 0.03;', // simple distortion (ripple) via dudv map (see https://www.youtube.com/watch?v=6B7IF6GOu7s)
-			'	vec2 distortedUv = texture2D( tDudv, vec2( vUv.x + time * waveSpeed, vUv.y ) ).rg * waveStrength;', '	distortedUv = vUv.xy + vec2( distortedUv.x, distortedUv.y + time * waveSpeed );', '	vec2 distortion = ( texture2D( tDudv, distortedUv ).rg * 2.0 - 1.0 ) * waveStrength;', // new uv coords
-			' vec4 uv = vec4( vUvRefraction );', ' uv.xy += distortion;', '	vec4 base = texture2DProj( tDiffuse, uv );', '	gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );', '}' ].join( '\n' )
+		vertexShader: `uniform mat4 textureMatrix;
+
+		varying vec2 vUv;
+		varying vec4 vUvRefraction;
+
+		void main() {
+
+			vUv = uv;
+
+			vUvRefraction = textureMatrix * vec4( position, 1.0 );
+
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+		}`,
+		fragmentShader: `uniform vec3 color;
+		uniform float time;
+		uniform sampler2D tDiffuse;
+		uniform sampler2D tDudv;
+
+		varying vec2 vUv;
+		varying vec4 vUvRefraction;
+
+		float blendOverlay( float base, float blend ) {
+
+			return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
+
+		}
+
+		vec3 blendOverlay( vec3 base, vec3 blend ) {
+
+			return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ),blendOverlay( base.b, blend.b ) );
+
+		}
+
+		void main() {
+
+		 float waveStrength = 0.1;
+		 float waveSpeed = 0.03;
+
+			// simple distortion (ripple) via dudv map (see https://www.youtube.com/watch?v=6B7IF6GOu7s)
+
+			vec2 distortedUv = texture2D( tDudv, vec2( vUv.x + time * waveSpeed, vUv.y ) ).rg * waveStrength;
+			distortedUv = vUv.xy + vec2( distortedUv.x, distortedUv.y + time * waveSpeed );
+			vec2 distortion = ( texture2D( tDudv, distortedUv ).rg * 2.0 - 1.0 ) * waveStrength;
+
+			// new uv coords
+
+		 vec4 uv = vec4( vUvRefraction );
+		 uv.xy += distortion;
+
+			vec4 base = texture2DProj( tDiffuse, uv );
+
+			gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
+
+		}`
 	};
 	};
 
 
 	THREE.WaterRefractionShader = WaterRefractionShader;
 	THREE.WaterRefractionShader = WaterRefractionShader;

+ 38 - 42
examples/jsm/shaders/ACESFilmicToneMappingShader.js

@@ -6,7 +6,7 @@
  * the scale factor of 1/0.6 is subjective. see discussion in #19621.
  * the scale factor of 1/0.6 is subjective. see discussion in #19621.
  */
  */
 
 
-var ACESFilmicToneMappingShader = {
+const ACESFilmicToneMappingShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -15,76 +15,72 @@ var ACESFilmicToneMappingShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`#define saturate(a) clamp( a, 0.0, 1.0 )
 
 
-		'#define saturate(a) clamp( a, 0.0, 1.0 )',
+		uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		uniform float exposure;
 
 
-		'uniform float exposure;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		vec3 RRTAndODTFit( vec3 v ) {
 
 
-		'vec3 RRTAndODTFit( vec3 v ) {',
+			vec3 a = v * ( v + 0.0245786 ) - 0.000090537;
+			vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;
+			return a / b;
 
 
-		'	vec3 a = v * ( v + 0.0245786 ) - 0.000090537;',
-		'	vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;',
-		'	return a / b;',
+		}
 
 
-		'}',
-
-		'vec3 ACESFilmicToneMapping( vec3 color ) {',
+		vec3 ACESFilmicToneMapping( vec3 color ) {
 
 
 		// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
 		// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
-		'	const mat3 ACESInputMat = mat3(',
-		'		vec3( 0.59719, 0.07600, 0.02840 ),', // transposed from source
-		'		vec3( 0.35458, 0.90834, 0.13383 ),',
-		'		vec3( 0.04823, 0.01566, 0.83777 )',
-		'	);',
+			const mat3 ACESInputMat = mat3(
+				vec3( 0.59719, 0.07600, 0.02840 ), // transposed from source
+				vec3( 0.35458, 0.90834, 0.13383 ),
+				vec3( 0.04823, 0.01566, 0.83777 )
+			);
 
 
 		// ODT_SAT => XYZ => D60_2_D65 => sRGB
 		// ODT_SAT => XYZ => D60_2_D65 => sRGB
-		'	const mat3 ACESOutputMat = mat3(',
-		'		vec3(  1.60475, -0.10208, -0.00327 ),', // transposed from source
-		'		vec3( -0.53108,  1.10813, -0.07276 ),',
-		'		vec3( -0.07367, -0.00605,  1.07602 )',
-		'	);',
+			const mat3 ACESOutputMat = mat3(
+				vec3(  1.60475, -0.10208, -0.00327 ), // transposed from source
+				vec3( -0.53108,  1.10813, -0.07276 ),
+				vec3( -0.07367, -0.00605,  1.07602 )
+			);
 
 
-		'	color = ACESInputMat * color;',
+			color = ACESInputMat * color;
 
 
 		// Apply RRT and ODT
 		// Apply RRT and ODT
-		'	color = RRTAndODTFit( color );',
+			color = RRTAndODTFit( color );
 
 
-		'	color = ACESOutputMat * color;',
+			color = ACESOutputMat * color;
 
 
 		// Clamp to [0, 1]
 		// Clamp to [0, 1]
-		'	return saturate( color );',
-
-		'}',
+			return saturate( color );
 
 
-		'void main() {',
+		}
 
 
-		'	vec4 tex = texture2D( tDiffuse, vUv );',
+		void main() {
 
 
-		'	tex.rgb *= exposure / 0.6;', // pre-exposed, outside of the tone mapping function
+			vec4 tex = texture2D( tDiffuse, vUv );
 
 
-		'	gl_FragColor = vec4( ACESFilmicToneMapping( tex.rgb ), tex.a );',
+			tex.rgb *= exposure / 0.6; // pre-exposed, outside of the tone mapping function
 
 
-		'}'
+			gl_FragColor = vec4( ACESFilmicToneMapping( tex.rgb ), tex.a );
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 21 - 25
examples/jsm/shaders/AfterimageShader.js

@@ -4,7 +4,7 @@
  * https://codepen.io/brunoimbrizi/pen/MoRJaN?page=1&
  * https://codepen.io/brunoimbrizi/pen/MoRJaN?page=1&
  */
  */
 
 
-var AfterimageShader = {
+const AfterimageShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -14,46 +14,42 @@ var AfterimageShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform float damp;
 
 
-		'uniform float damp;',
+		uniform sampler2D tOld;
+		uniform sampler2D tNew;
 
 
-		'uniform sampler2D tOld;',
-		'uniform sampler2D tNew;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		vec4 when_gt( vec4 x, float y ) {
 
 
-		'vec4 when_gt( vec4 x, float y ) {',
+			return max( sign( x - y ), 0.0 );
 
 
-		'	return max( sign( x - y ), 0.0 );',
+		}
 
 
-		'}',
+		void main() {
 
 
-		'void main() {',
+			vec4 texelOld = texture2D( tOld, vUv );
+			vec4 texelNew = texture2D( tNew, vUv );
 
 
-		'	vec4 texelOld = texture2D( tOld, vUv );',
-		'	vec4 texelNew = texture2D( tNew, vUv );',
+			texelOld *= damp * when_gt( texelOld, 0.1 );
 
 
-		'	texelOld *= damp * when_gt( texelOld, 0.1 );',
+			gl_FragColor = max(texelNew, texelOld);
 
 
-		'	gl_FragColor = max(texelNew, texelOld);',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 9 - 13
examples/jsm/shaders/BasicShader.js

@@ -2,29 +2,25 @@
  * Simple test shader
  * Simple test shader
  */
  */
 
 
-var BasicShader = {
+const BasicShader = {
 
 
 	uniforms: {},
 	uniforms: {},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'void main() {',
+		`void main() {
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`void main() {
 
 
-		'void main() {',
+			gl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5 );
 
 
-		'	gl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5 );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 25 - 29
examples/jsm/shaders/BleachBypassShader.js

@@ -4,7 +4,7 @@
  * http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html#post_bleach_bypass
  * http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html#post_bleach_bypass
  */
  */
 
 
-var BleachBypassShader = {
+const BleachBypassShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -13,51 +13,47 @@ var BleachBypassShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform float opacity;
 
 
-		'uniform float opacity;',
+		uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 base = texture2D( tDiffuse, vUv );
 
 
-		'	vec4 base = texture2D( tDiffuse, vUv );',
+			vec3 lumCoeff = vec3( 0.25, 0.65, 0.1 );
+			float lum = dot( lumCoeff, base.rgb );
+			vec3 blend = vec3( lum );
 
 
-		'	vec3 lumCoeff = vec3( 0.25, 0.65, 0.1 );',
-		'	float lum = dot( lumCoeff, base.rgb );',
-		'	vec3 blend = vec3( lum );',
+			float L = min( 1.0, max( 0.0, 10.0 * ( lum - 0.45 ) ) );
 
 
-		'	float L = min( 1.0, max( 0.0, 10.0 * ( lum - 0.45 ) ) );',
+			vec3 result1 = 2.0 * base.rgb * blend;
+			vec3 result2 = 1.0 - 2.0 * ( 1.0 - blend ) * ( 1.0 - base.rgb );
 
 
-		'	vec3 result1 = 2.0 * base.rgb * blend;',
-		'	vec3 result2 = 1.0 - 2.0 * ( 1.0 - blend ) * ( 1.0 - base.rgb );',
+			vec3 newColor = mix( result1, result2, L );
 
 
-		'	vec3 newColor = mix( result1, result2, L );',
+			float A2 = opacity * base.a;
+			vec3 mixRGB = A2 * newColor.rgb;
+			mixRGB += ( ( 1.0 - A2 ) * base.rgb );
 
 
-		'	float A2 = opacity * base.a;',
-		'	vec3 mixRGB = A2 * newColor.rgb;',
-		'	mixRGB += ( ( 1.0 - A2 ) * base.rgb );',
+			gl_FragColor = vec4( mixRGB, base.a );
 
 
-		'	gl_FragColor = vec4( mixRGB, base.a );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 18 - 22
examples/jsm/shaders/BlendShader.js

@@ -2,7 +2,7 @@
  * Blend two textures
  * Blend two textures
  */
  */
 
 
-var BlendShader = {
+const BlendShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -13,38 +13,34 @@ var BlendShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform float opacity;
+		uniform float mixRatio;
 
 
-		'uniform float opacity;',
-		'uniform float mixRatio;',
+		uniform sampler2D tDiffuse1;
+		uniform sampler2D tDiffuse2;
 
 
-		'uniform sampler2D tDiffuse1;',
-		'uniform sampler2D tDiffuse2;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 texel1 = texture2D( tDiffuse1, vUv );
+			vec4 texel2 = texture2D( tDiffuse2, vUv );
+			gl_FragColor = opacity * mix( texel1, texel2, mixRatio );
 
 
-		'	vec4 texel1 = texture2D( tDiffuse1, vUv );',
-		'	vec4 texel2 = texture2D( tDiffuse2, vUv );',
-		'	gl_FragColor = opacity * mix( texel1, texel2, mixRatio );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 88 - 92
examples/jsm/shaders/BokehShader.js

@@ -4,7 +4,7 @@
  * http://artmartinsh.blogspot.com/2010/02/glsl-lens-blur-filter-with-bokeh.html
  * http://artmartinsh.blogspot.com/2010/02/glsl-lens-blur-filter-with-bokeh.html
  */
  */
 
 
-var BokehShader = {
+const BokehShader = {
 
 
 	defines: {
 	defines: {
 		'DEPTH_PACKING': 1,
 		'DEPTH_PACKING': 1,
@@ -24,122 +24,118 @@ var BokehShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
+		`#include <common>
 
 
-	fragmentShader: [
-		'#include <common>',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		uniform sampler2D tColor;
+		uniform sampler2D tDepth;
 
 
-		'uniform sampler2D tColor;',
-		'uniform sampler2D tDepth;',
+		uniform float maxblur; // max blur amount
+		uniform float aperture; // aperture - bigger values for shallower depth of field
 
 
-		'uniform float maxblur;', // max blur amount
-		'uniform float aperture;', // aperture - bigger values for shallower depth of field
+		uniform float nearClip;
+		uniform float farClip;
 
 
-		'uniform float nearClip;',
-		'uniform float farClip;',
+		uniform float focus;
+		uniform float aspect;
 
 
-		'uniform float focus;',
-		'uniform float aspect;',
+		#include <packing>
 
 
-		'#include <packing>',
+		float getDepth( const in vec2 screenPosition ) {
+			#if DEPTH_PACKING == 1
+			return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );
+			#else
+			return texture2D( tDepth, screenPosition ).x;
+			#endif
+		}
 
 
-		'float getDepth( const in vec2 screenPosition ) {',
-		'	#if DEPTH_PACKING == 1',
-		'	return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );',
-		'	#else',
-		'	return texture2D( tDepth, screenPosition ).x;',
-		'	#endif',
-		'}',
+		float getViewZ( const in float depth ) {
+			#if PERSPECTIVE_CAMERA == 1
+			return perspectiveDepthToViewZ( depth, nearClip, farClip );
+			#else
+			return orthographicDepthToViewZ( depth, nearClip, farClip );
+			#endif
+		}
 
 
-		'float getViewZ( const in float depth ) {',
-		'	#if PERSPECTIVE_CAMERA == 1',
-		'	return perspectiveDepthToViewZ( depth, nearClip, farClip );',
-		'	#else',
-		'	return orthographicDepthToViewZ( depth, nearClip, farClip );',
-		'	#endif',
-		'}',
 
 
+		void main() {
 
 
-		'void main() {',
+			vec2 aspectcorrect = vec2( 1.0, aspect );
 
 
-		'	vec2 aspectcorrect = vec2( 1.0, aspect );',
+			float viewZ = getViewZ( getDepth( vUv ) );
 
 
-		'	float viewZ = getViewZ( getDepth( vUv ) );',
+			float factor = ( focus + viewZ ); // viewZ is <= 0, so this is a difference equation
 
 
-		'	float factor = ( focus + viewZ );', // viewZ is <= 0, so this is a difference equation
+			vec2 dofblur = vec2 ( clamp( factor * aperture, -maxblur, maxblur ) );
 
 
-		'	vec2 dofblur = vec2 ( clamp( factor * aperture, -maxblur, maxblur ) );',
+			vec2 dofblur9 = dofblur * 0.9;
+			vec2 dofblur7 = dofblur * 0.7;
+			vec2 dofblur4 = dofblur * 0.4;
 
 
-		'	vec2 dofblur9 = dofblur * 0.9;',
-		'	vec2 dofblur7 = dofblur * 0.7;',
-		'	vec2 dofblur4 = dofblur * 0.4;',
+			vec4 col = vec4( 0.0 );
 
 
-		'	vec4 col = vec4( 0.0 );',
+			col += texture2D( tColor, vUv.xy );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.0,   0.4  ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.15,  0.37 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.29,  0.29 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.37,  0.15 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.40,  0.0  ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.37, -0.15 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.29, -0.29 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.0,  -0.4  ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.15,  0.37 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.29,  0.29 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.37,  0.15 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.4,   0.0  ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.15, -0.37 ) * aspectcorrect ) * dofblur );
 
 
-		'	col += texture2D( tColor, vUv.xy );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.0,   0.4  ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.15,  0.37 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.29,  0.29 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.37,  0.15 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.40,  0.0  ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.37, -0.15 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.29, -0.29 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.0,  -0.4  ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.15,  0.37 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.29,  0.29 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.37,  0.15 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.4,   0.0  ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.15, -0.37 ) * aspectcorrect ) * dofblur );',
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.15,  0.37 ) * aspectcorrect ) * dofblur9 );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.37,  0.15 ) * aspectcorrect ) * dofblur9 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.37, -0.15 ) * aspectcorrect ) * dofblur9 );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.15,  0.37 ) * aspectcorrect ) * dofblur9 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.37,  0.15 ) * aspectcorrect ) * dofblur9 );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.15, -0.37 ) * aspectcorrect ) * dofblur9 );
 
 
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.15,  0.37 ) * aspectcorrect ) * dofblur9 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.37,  0.15 ) * aspectcorrect ) * dofblur9 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.37, -0.15 ) * aspectcorrect ) * dofblur9 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.15,  0.37 ) * aspectcorrect ) * dofblur9 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.37,  0.15 ) * aspectcorrect ) * dofblur9 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.15, -0.37 ) * aspectcorrect ) * dofblur9 );',
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.29,  0.29 ) * aspectcorrect ) * dofblur7 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.40,  0.0  ) * aspectcorrect ) * dofblur7 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.29, -0.29 ) * aspectcorrect ) * dofblur7 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.0,  -0.4  ) * aspectcorrect ) * dofblur7 );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.29,  0.29 ) * aspectcorrect ) * dofblur7 );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.4,   0.0  ) * aspectcorrect ) * dofblur7 );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.0,   0.4  ) * aspectcorrect ) * dofblur7 );
 
 
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.29,  0.29 ) * aspectcorrect ) * dofblur7 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.40,  0.0  ) * aspectcorrect ) * dofblur7 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.29, -0.29 ) * aspectcorrect ) * dofblur7 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.0,  -0.4  ) * aspectcorrect ) * dofblur7 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.29,  0.29 ) * aspectcorrect ) * dofblur7 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.4,   0.0  ) * aspectcorrect ) * dofblur7 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.0,   0.4  ) * aspectcorrect ) * dofblur7 );',
-
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.29,  0.29 ) * aspectcorrect ) * dofblur4 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.4,   0.0  ) * aspectcorrect ) * dofblur4 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.29, -0.29 ) * aspectcorrect ) * dofblur4 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.0,  -0.4  ) * aspectcorrect ) * dofblur4 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.29,  0.29 ) * aspectcorrect ) * dofblur4 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.4,   0.0  ) * aspectcorrect ) * dofblur4 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 );',
-		'	col += texture2D( tColor, vUv.xy + ( vec2(  0.0,   0.4  ) * aspectcorrect ) * dofblur4 );',
-
-		'	gl_FragColor = col / 41.0;',
-		'	gl_FragColor.a = 1.0;',
-
-		'}'
-
-	].join( '\n' )
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.29,  0.29 ) * aspectcorrect ) * dofblur4 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.4,   0.0  ) * aspectcorrect ) * dofblur4 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.29, -0.29 ) * aspectcorrect ) * dofblur4 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.0,  -0.4  ) * aspectcorrect ) * dofblur4 );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.29,  0.29 ) * aspectcorrect ) * dofblur4 );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.4,   0.0  ) * aspectcorrect ) * dofblur4 );
+			col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 );
+			col += texture2D( tColor, vUv.xy + ( vec2(  0.0,   0.4  ) * aspectcorrect ) * dofblur4 );
+
+			gl_FragColor = col / 41.0;
+			gl_FragColor.a = 1.0;
+
+		}`
 
 
 };
 };
 
 

+ 229 - 241
examples/jsm/shaders/BokehShader2.js

@@ -9,10 +9,7 @@ import {
  *
  *
  * Requires #define RINGS and SAMPLES integers
  * Requires #define RINGS and SAMPLES integers
  */
  */
-
-
-
-var BokehShader = {
+const BokehShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -51,313 +48,308 @@ var BokehShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
-
-		'varying vec2 vUv;',
+	vertexShader:
 
 
-		'void main() {',
+		`varying vec2 vUv;
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+		void main() {
 
 
-		'}'
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-	].join( '\n' ),
+		}`,
 
 
-	fragmentShader: [
+	fragmentShader:
 
 
-		'#include <common>',
+		`#include <common>
 
 
-		'varying vec2 vUv;',
+		varying vec2 vUv;
 
 
-		'uniform sampler2D tColor;',
-		'uniform sampler2D tDepth;',
-		'uniform float textureWidth;',
-		'uniform float textureHeight;',
+		uniform sampler2D tColor;
+		uniform sampler2D tDepth;
+		uniform float textureWidth;
+		uniform float textureHeight;
 
 
-		'uniform float focalDepth;  //focal distance value in meters, but you may use autofocus option below',
-		'uniform float focalLength; //focal length in mm',
-		'uniform float fstop; //f-stop value',
-		'uniform bool showFocus; //show debug focus point and focal range (red = focal point, green = focal range)',
+		uniform float focalDepth;  //focal distance value in meters, but you may use autofocus option below
+		uniform float focalLength; //focal length in mm
+		uniform float fstop; //f-stop value
+		uniform bool showFocus; //show debug focus point and focal range (red = focal point, green = focal range)
 
 
-		'/*',
-		'make sure that these two values are the same for your camera, otherwise distances will be wrong.',
-		'*/',
+		/*
+		make sure that these two values are the same for your camera, otherwise distances will be wrong.
+		*/
 
 
-		'uniform float znear; // camera clipping start',
-		'uniform float zfar; // camera clipping end',
+		uniform float znear; // camera clipping start
+		uniform float zfar; // camera clipping end
 
 
-		'//------------------------------------------',
-		'//user variables',
+		//------------------------------------------
+		//user variables
 
 
-		'const int samples = SAMPLES; //samples on the first ring',
-		'const int rings = RINGS; //ring count',
+		const int samples = SAMPLES; //samples on the first ring
+		const int rings = RINGS; //ring count
 
 
-		'const int maxringsamples = rings * samples;',
+		const int maxringsamples = rings * samples;
 
 
-		'uniform bool manualdof; // manual dof calculation',
-		'float ndofstart = 1.0; // near dof blur start',
-		'float ndofdist = 2.0; // near dof blur falloff distance',
-		'float fdofstart = 1.0; // far dof blur start',
-		'float fdofdist = 3.0; // far dof blur falloff distance',
+		uniform bool manualdof; // manual dof calculation
+		float ndofstart = 1.0; // near dof blur start
+		float ndofdist = 2.0; // near dof blur falloff distance
+		float fdofstart = 1.0; // far dof blur start
+		float fdofdist = 3.0; // far dof blur falloff distance
 
 
-		'float CoC = 0.03; //circle of confusion size in mm (35mm film = 0.03mm)',
+		float CoC = 0.03; //circle of confusion size in mm (35mm film = 0.03mm)
 
 
-		'uniform bool vignetting; // use optical lens vignetting',
+		uniform bool vignetting; // use optical lens vignetting
 
 
-		'float vignout = 1.3; // vignetting outer border',
-		'float vignin = 0.0; // vignetting inner border',
-		'float vignfade = 22.0; // f-stops till vignete fades',
+		float vignout = 1.3; // vignetting outer border
+		float vignin = 0.0; // vignetting inner border
+		float vignfade = 22.0; // f-stops till vignete fades
 
 
-		'uniform bool shaderFocus;',
-		'// disable if you use external focalDepth value',
+		uniform bool shaderFocus;
+		// disable if you use external focalDepth value
 
 
-		'uniform vec2 focusCoords;',
-		'// autofocus point on screen (0.0,0.0 - left lower corner, 1.0,1.0 - upper right)',
-		'// if center of screen use vec2(0.5, 0.5);',
+		uniform vec2 focusCoords;
+		// autofocus point on screen (0.0,0.0 - left lower corner, 1.0,1.0 - upper right)
+		// if center of screen use vec2(0.5, 0.5);
 
 
-		'uniform float maxblur;',
-		'//clamp value of max blur (0.0 = no blur, 1.0 default)',
+		uniform float maxblur;
+		//clamp value of max blur (0.0 = no blur, 1.0 default)
 
 
-		'uniform float threshold; // highlight threshold;',
-		'uniform float gain; // highlight gain;',
+		uniform float threshold; // highlight threshold;
+		uniform float gain; // highlight gain;
 
 
-		'uniform float bias; // bokeh edge bias',
-		'uniform float fringe; // bokeh chromatic aberration / fringing',
+		uniform float bias; // bokeh edge bias
+		uniform float fringe; // bokeh chromatic aberration / fringing
 
 
-		'uniform bool noise; //use noise instead of pattern for sample dithering',
+		uniform bool noise; //use noise instead of pattern for sample dithering
 
 
-		'uniform float dithering;',
+		uniform float dithering;
 
 
-		'uniform bool depthblur; // blur the depth buffer',
-		'float dbsize = 1.25; // depth blur size',
+		uniform bool depthblur; // blur the depth buffer
+		float dbsize = 1.25; // depth blur size
 
 
-		'/*',
-		'next part is experimental',
-		'not looking good with small sample and ring count',
-		'looks okay starting from samples = 4, rings = 4',
-		'*/',
+		/*
+		next part is experimental
+		not looking good with small sample and ring count
+		looks okay starting from samples = 4, rings = 4
+		*/
 
 
-		'uniform bool pentagon; //use pentagon as bokeh shape?',
-		'float feather = 0.4; //pentagon shape feather',
+		uniform bool pentagon; //use pentagon as bokeh shape?
+		float feather = 0.4; //pentagon shape feather
 
 
-		'//------------------------------------------',
+		//------------------------------------------
 
 
-		'float penta(vec2 coords) {',
-		'	//pentagonal shape',
-		'	float scale = float(rings) - 1.3;',
-		'	vec4  HS0 = vec4( 1.0,         0.0,         0.0,  1.0);',
-		'	vec4  HS1 = vec4( 0.309016994, 0.951056516, 0.0,  1.0);',
-		'	vec4  HS2 = vec4(-0.809016994, 0.587785252, 0.0,  1.0);',
-		'	vec4  HS3 = vec4(-0.809016994,-0.587785252, 0.0,  1.0);',
-		'	vec4  HS4 = vec4( 0.309016994,-0.951056516, 0.0,  1.0);',
-		'	vec4  HS5 = vec4( 0.0        ,0.0         , 1.0,  1.0);',
+		float penta(vec2 coords) {
+			//pentagonal shape
+			float scale = float(rings) - 1.3;
+			vec4  HS0 = vec4( 1.0,         0.0,         0.0,  1.0);
+			vec4  HS1 = vec4( 0.309016994, 0.951056516, 0.0,  1.0);
+			vec4  HS2 = vec4(-0.809016994, 0.587785252, 0.0,  1.0);
+			vec4  HS3 = vec4(-0.809016994,-0.587785252, 0.0,  1.0);
+			vec4  HS4 = vec4( 0.309016994,-0.951056516, 0.0,  1.0);
+			vec4  HS5 = vec4( 0.0        ,0.0         , 1.0,  1.0);
 
 
-		'	vec4  one = vec4( 1.0 );',
+			vec4  one = vec4( 1.0 );
 
 
-		'	vec4 P = vec4((coords),vec2(scale, scale));',
+			vec4 P = vec4((coords),vec2(scale, scale));
 
 
-		'	vec4 dist = vec4(0.0);',
-		'	float inorout = -4.0;',
+			vec4 dist = vec4(0.0);
+			float inorout = -4.0;
 
 
-		'	dist.x = dot( P, HS0 );',
-		'	dist.y = dot( P, HS1 );',
-		'	dist.z = dot( P, HS2 );',
-		'	dist.w = dot( P, HS3 );',
+			dist.x = dot( P, HS0 );
+			dist.y = dot( P, HS1 );
+			dist.z = dot( P, HS2 );
+			dist.w = dot( P, HS3 );
 
 
-		'	dist = smoothstep( -feather, feather, dist );',
+			dist = smoothstep( -feather, feather, dist );
 
 
-		'	inorout += dot( dist, one );',
+			inorout += dot( dist, one );
 
 
-		'	dist.x = dot( P, HS4 );',
-		'	dist.y = HS5.w - abs( P.z );',
+			dist.x = dot( P, HS4 );
+			dist.y = HS5.w - abs( P.z );
 
 
-		'	dist = smoothstep( -feather, feather, dist );',
-		'	inorout += dist.x;',
+			dist = smoothstep( -feather, feather, dist );
+			inorout += dist.x;
 
 
-		'	return clamp( inorout, 0.0, 1.0 );',
-		'}',
+			return clamp( inorout, 0.0, 1.0 );
+		}
 
 
-		'float bdepth(vec2 coords) {',
-		'	// Depth buffer blur',
-		'	float d = 0.0;',
-		'	float kernel[9];',
-		'	vec2 offset[9];',
+		float bdepth(vec2 coords) {
+			// Depth buffer blur
+			float d = 0.0;
+			float kernel[9];
+			vec2 offset[9];
 
 
-		'	vec2 wh = vec2(1.0/textureWidth,1.0/textureHeight) * dbsize;',
+			vec2 wh = vec2(1.0/textureWidth,1.0/textureHeight) * dbsize;
 
 
-		'	offset[0] = vec2(-wh.x,-wh.y);',
-		'	offset[1] = vec2( 0.0, -wh.y);',
-		'	offset[2] = vec2( wh.x -wh.y);',
+			offset[0] = vec2(-wh.x,-wh.y);
+			offset[1] = vec2( 0.0, -wh.y);
+			offset[2] = vec2( wh.x -wh.y);
 
 
-		'	offset[3] = vec2(-wh.x,  0.0);',
-		'	offset[4] = vec2( 0.0,   0.0);',
-		'	offset[5] = vec2( wh.x,  0.0);',
+			offset[3] = vec2(-wh.x,  0.0);
+			offset[4] = vec2( 0.0,   0.0);
+			offset[5] = vec2( wh.x,  0.0);
 
 
-		'	offset[6] = vec2(-wh.x, wh.y);',
-		'	offset[7] = vec2( 0.0,  wh.y);',
-		'	offset[8] = vec2( wh.x, wh.y);',
+			offset[6] = vec2(-wh.x, wh.y);
+			offset[7] = vec2( 0.0,  wh.y);
+			offset[8] = vec2( wh.x, wh.y);
 
 
-		'	kernel[0] = 1.0/16.0;   kernel[1] = 2.0/16.0;   kernel[2] = 1.0/16.0;',
-		'	kernel[3] = 2.0/16.0;   kernel[4] = 4.0/16.0;   kernel[5] = 2.0/16.0;',
-		'	kernel[6] = 1.0/16.0;   kernel[7] = 2.0/16.0;   kernel[8] = 1.0/16.0;',
+			kernel[0] = 1.0/16.0;   kernel[1] = 2.0/16.0;   kernel[2] = 1.0/16.0;
+			kernel[3] = 2.0/16.0;   kernel[4] = 4.0/16.0;   kernel[5] = 2.0/16.0;
+			kernel[6] = 1.0/16.0;   kernel[7] = 2.0/16.0;   kernel[8] = 1.0/16.0;
 
 
 
 
-		'	for( int i=0; i<9; i++ ) {',
-		'		float tmp = texture2D(tDepth, coords + offset[i]).r;',
-		'		d += tmp * kernel[i];',
-		'	}',
+			for( int i=0; i<9; i++ ) {
+				float tmp = texture2D(tDepth, coords + offset[i]).r;
+				d += tmp * kernel[i];
+			}
 
 
-		'	return d;',
-		'}',
+			return d;
+		}
 
 
 
 
-		'vec3 color(vec2 coords,float blur) {',
-		'	//processing the sample',
+		vec3 color(vec2 coords,float blur) {
+			//processing the sample
 
 
-		'	vec3 col = vec3(0.0);',
-		'	vec2 texel = vec2(1.0/textureWidth,1.0/textureHeight);',
+			vec3 col = vec3(0.0);
+			vec2 texel = vec2(1.0/textureWidth,1.0/textureHeight);
 
 
-		'	col.r = texture2D(tColor,coords + vec2(0.0,1.0)*texel*fringe*blur).r;',
-		'	col.g = texture2D(tColor,coords + vec2(-0.866,-0.5)*texel*fringe*blur).g;',
-		'	col.b = texture2D(tColor,coords + vec2(0.866,-0.5)*texel*fringe*blur).b;',
+			col.r = texture2D(tColor,coords + vec2(0.0,1.0)*texel*fringe*blur).r;
+			col.g = texture2D(tColor,coords + vec2(-0.866,-0.5)*texel*fringe*blur).g;
+			col.b = texture2D(tColor,coords + vec2(0.866,-0.5)*texel*fringe*blur).b;
 
 
-		'	vec3 lumcoeff = vec3(0.299,0.587,0.114);',
-		'	float lum = dot(col.rgb, lumcoeff);',
-		'	float thresh = max((lum-threshold)*gain, 0.0);',
-		'	return col+mix(vec3(0.0),col,thresh*blur);',
-		'}',
+			vec3 lumcoeff = vec3(0.299,0.587,0.114);
+			float lum = dot(col.rgb, lumcoeff);
+			float thresh = max((lum-threshold)*gain, 0.0);
+			return col+mix(vec3(0.0),col,thresh*blur);
+		}
 
 
-		'vec3 debugFocus(vec3 col, float blur, float depth) {',
-		'	float edge = 0.002*depth; //distance based edge smoothing',
-		'	float m = clamp(smoothstep(0.0,edge,blur),0.0,1.0);',
-		'	float e = clamp(smoothstep(1.0-edge,1.0,blur),0.0,1.0);',
+		vec3 debugFocus(vec3 col, float blur, float depth) {
+			float edge = 0.002*depth; //distance based edge smoothing
+			float m = clamp(smoothstep(0.0,edge,blur),0.0,1.0);
+			float e = clamp(smoothstep(1.0-edge,1.0,blur),0.0,1.0);
 
 
-		'	col = mix(col,vec3(1.0,0.5,0.0),(1.0-m)*0.6);',
-		'	col = mix(col,vec3(0.0,0.5,1.0),((1.0-e)-(1.0-m))*0.2);',
+			col = mix(col,vec3(1.0,0.5,0.0),(1.0-m)*0.6);
+			col = mix(col,vec3(0.0,0.5,1.0),((1.0-e)-(1.0-m))*0.2);
 
 
-		'	return col;',
-		'}',
+			return col;
+		}
 
 
-		'float linearize(float depth) {',
-		'	return -zfar * znear / (depth * (zfar - znear) - zfar);',
-		'}',
+		float linearize(float depth) {
+			return -zfar * znear / (depth * (zfar - znear) - zfar);
+		}
 
 
+		float vignette() {
+			float dist = distance(vUv.xy, vec2(0.5,0.5));
+			dist = smoothstep(vignout+(fstop/vignfade), vignin+(fstop/vignfade), dist);
+			return clamp(dist,0.0,1.0);
+		}
 
 
-		'float vignette() {',
-		'	float dist = distance(vUv.xy, vec2(0.5,0.5));',
-		'	dist = smoothstep(vignout+(fstop/vignfade), vignin+(fstop/vignfade), dist);',
-		'	return clamp(dist,0.0,1.0);',
-		'}',
+		float gather(float i, float j, int ringsamples, inout vec3 col, float w, float h, float blur) {
+			float rings2 = float(rings);
+			float step = PI*2.0 / float(ringsamples);
+			float pw = cos(j*step)*i;
+			float ph = sin(j*step)*i;
+			float p = 1.0;
+			if (pentagon) {
+				p = penta(vec2(pw,ph));
+			}
+			col += color(vUv.xy + vec2(pw*w,ph*h), blur) * mix(1.0, i/rings2, bias) * p;
+			return 1.0 * mix(1.0, i /rings2, bias) * p;
+		}
 
 
-		'float gather(float i, float j, int ringsamples, inout vec3 col, float w, float h, float blur) {',
-		'	float rings2 = float(rings);',
-		'	float step = PI*2.0 / float(ringsamples);',
-		'	float pw = cos(j*step)*i;',
-		'	float ph = sin(j*step)*i;',
-		'	float p = 1.0;',
-		'	if (pentagon) {',
-		'		p = penta(vec2(pw,ph));',
-		'	}',
-		'	col += color(vUv.xy + vec2(pw*w,ph*h), blur) * mix(1.0, i/rings2, bias) * p;',
-		'	return 1.0 * mix(1.0, i /rings2, bias) * p;',
-		'}',
+		void main() {
+			//scene depth calculation
 
 
-		'void main() {',
-		'	//scene depth calculation',
+			float depth = linearize(texture2D(tDepth,vUv.xy).x);
 
 
-		'	float depth = linearize(texture2D(tDepth,vUv.xy).x);',
+			// Blur depth?
+			if ( depthblur ) {
+				depth = linearize(bdepth(vUv.xy));
+			}
 
 
-		'	// Blur depth?',
-		'	if ( depthblur ) {',
-		'		depth = linearize(bdepth(vUv.xy));',
-		'	}',
+			//focal plane calculation
 
 
-		'	//focal plane calculation',
+			float fDepth = focalDepth;
 
 
-		'	float fDepth = focalDepth;',
+			if (shaderFocus) {
 
 
-		'	if (shaderFocus) {',
+				fDepth = linearize(texture2D(tDepth,focusCoords).x);
 
 
-		'		fDepth = linearize(texture2D(tDepth,focusCoords).x);',
+			}
 
 
-		'	}',
+			// dof blur factor calculation
 
 
-		'	// dof blur factor calculation',
+			float blur = 0.0;
 
 
-		'	float blur = 0.0;',
+			if (manualdof) {
+				float a = depth-fDepth; // Focal plane
+				float b = (a-fdofstart)/fdofdist; // Far DoF
+				float c = (-a-ndofstart)/ndofdist; // Near Dof
+				blur = (a>0.0) ? b : c;
+			} else {
+				float f = focalLength; // focal length in mm
+				float d = fDepth*1000.0; // focal plane in mm
+				float o = depth*1000.0; // depth in mm
 
 
-		'	if (manualdof) {',
-		'		float a = depth-fDepth; // Focal plane',
-		'		float b = (a-fdofstart)/fdofdist; // Far DoF',
-		'		float c = (-a-ndofstart)/ndofdist; // Near Dof',
-		'		blur = (a>0.0) ? b : c;',
-		'	} else {',
-		'		float f = focalLength; // focal length in mm',
-		'		float d = fDepth*1000.0; // focal plane in mm',
-		'		float o = depth*1000.0; // depth in mm',
+				float a = (o*f)/(o-f);
+				float b = (d*f)/(d-f);
+				float c = (d-f)/(d*fstop*CoC);
 
 
-		'		float a = (o*f)/(o-f);',
-		'		float b = (d*f)/(d-f);',
-		'		float c = (d-f)/(d*fstop*CoC);',
+				blur = abs(a-b)*c;
+			}
 
 
-		'		blur = abs(a-b)*c;',
-		'	}',
+			blur = clamp(blur,0.0,1.0);
 
 
-		'	blur = clamp(blur,0.0,1.0);',
+			// calculation of pattern for dithering
 
 
-		'	// calculation of pattern for dithering',
+			vec2 noise = vec2(rand(vUv.xy), rand( vUv.xy + vec2( 0.4, 0.6 ) ) )*dithering*blur;
 
 
-		'	vec2 noise = vec2(rand(vUv.xy), rand( vUv.xy + vec2( 0.4, 0.6 ) ) )*dithering*blur;',
+			// getting blur x and y step factor
 
 
-		'	// getting blur x and y step factor',
+			float w = (1.0/textureWidth)*blur*maxblur+noise.x;
+			float h = (1.0/textureHeight)*blur*maxblur+noise.y;
 
 
-		'	float w = (1.0/textureWidth)*blur*maxblur+noise.x;',
-		'	float h = (1.0/textureHeight)*blur*maxblur+noise.y;',
+			// calculation of final color
 
 
-		'	// calculation of final color',
+			vec3 col = vec3(0.0);
 
 
-		'	vec3 col = vec3(0.0);',
+			if(blur < 0.05) {
+				//some optimization thingy
+				col = texture2D(tColor, vUv.xy).rgb;
+			} else {
+				col = texture2D(tColor, vUv.xy).rgb;
+				float s = 1.0;
+				int ringsamples;
 
 
-		'	if(blur < 0.05) {',
-		'		//some optimization thingy',
-		'		col = texture2D(tColor, vUv.xy).rgb;',
-		'	} else {',
-		'		col = texture2D(tColor, vUv.xy).rgb;',
-		'		float s = 1.0;',
-		'		int ringsamples;',
+				for (int i = 1; i <= rings; i++) {
+					/*unboxstart*/
+					ringsamples = i * samples;
 
 
-		'		for (int i = 1; i <= rings; i++) {',
-		'			/*unboxstart*/',
-		'			ringsamples = i * samples;',
+					for (int j = 0 ; j < maxringsamples ; j++) {
+						if (j >= ringsamples) break;
+						s += gather(float(i), float(j), ringsamples, col, w, h, blur);
+					}
+					/*unboxend*/
+				}
 
 
-		'			for (int j = 0 ; j < maxringsamples ; j++) {',
-		'				if (j >= ringsamples) break;',
-		'				s += gather(float(i), float(j), ringsamples, col, w, h, blur);',
-		'			}',
-		'			/*unboxend*/',
-		'		}',
+				col /= s; //divide by sample count
+			}
 
 
-		'		col /= s; //divide by sample count',
-		'	}',
+			if (showFocus) {
+				col = debugFocus(col, blur, depth);
+			}
 
 
-		'	if (showFocus) {',
-		'		col = debugFocus(col, blur, depth);',
-		'	}',
+			if (vignetting) {
+				col *= vignette();
+			}
 
 
-		'	if (vignetting) {',
-		'		col *= vignette();',
-		'	}',
-
-		'	gl_FragColor.rgb = col;',
-		'	gl_FragColor.a = 1.0;',
-		'} '
-
-	].join( '\n' )
+			gl_FragColor.rgb = col;
+			gl_FragColor.a = 1.0;
+		}`
 
 
 };
 };
 
 
-var BokehDepthShader = {
+const BokehDepthShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -366,36 +358,32 @@ var BokehDepthShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
-
-		'varying float vViewZDepth;',
-
-		'void main() {',
+	vertexShader:
 
 
-		'	#include <begin_vertex>',
-		'	#include <project_vertex>',
+		`varying float vViewZDepth;
 
 
-		'	vViewZDepth = - mvPosition.z;',
+		void main() {
 
 
-		'}'
+			#include <begin_vertex>
+			#include <project_vertex>
 
 
-	].join( '\n' ),
+			vViewZDepth = - mvPosition.z;
 
 
-	fragmentShader: [
+		}`,
 
 
-		'uniform float mNear;',
-		'uniform float mFar;',
+	fragmentShader:
 
 
-		'varying float vViewZDepth;',
+		`uniform float mNear;
+		uniform float mFar;
 
 
-		'void main() {',
+		varying float vViewZDepth;
 
 
-		'	float color = 1.0 - smoothstep( mNear, mFar, vViewZDepth );',
-		'	gl_FragColor = vec4( vec3( color ), 1.0 );',
+		void main() {
 
 
-		'} '
+			float color = 1.0 - smoothstep( mNear, mFar, vViewZDepth );
+			gl_FragColor = vec4( vec3( color ), 1.0 );
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 21 - 25
examples/jsm/shaders/BrightnessContrastShader.js

@@ -5,7 +5,7 @@
  * contrast: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast)
  * contrast: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast)
  */
  */
 
 
-var BrightnessContrastShader = {
+const BrightnessContrastShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -15,43 +15,39 @@ var BrightnessContrastShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
+			vUv = uv;
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform float brightness;
+		uniform float contrast;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform float brightness;',
-		'uniform float contrast;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			gl_FragColor = texture2D( tDiffuse, vUv );
 
 
-		'	gl_FragColor = texture2D( tDiffuse, vUv );',
+			gl_FragColor.rgb += brightness;
 
 
-		'	gl_FragColor.rgb += brightness;',
+			if (contrast > 0.0) {
+				gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) / (1.0 - contrast) + 0.5;
+			} else {
+				gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) * (1.0 + contrast) + 0.5;
+			}
 
 
-		'	if (contrast > 0.0) {',
-		'		gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) / (1.0 - contrast) + 0.5;',
-		'	} else {',
-		'		gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) * (1.0 + contrast) + 0.5;',
-		'	}',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 17 - 21
examples/jsm/shaders/ColorCorrectionShader.js

@@ -6,7 +6,7 @@ import {
  * Color correction
  * Color correction
  */
  */
 
 
-var ColorCorrectionShader = {
+const ColorCorrectionShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -17,37 +17,33 @@ var ColorCorrectionShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
+			vUv = uv;
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform vec3 powRGB;
+		uniform vec3 mulRGB;
+		uniform vec3 addRGB;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform vec3 powRGB;',
-		'uniform vec3 mulRGB;',
-		'uniform vec3 addRGB;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			gl_FragColor = texture2D( tDiffuse, vUv );
+			gl_FragColor.rgb = mulRGB * pow( ( gl_FragColor.rgb + addRGB ), powRGB );
 
 
-		'	gl_FragColor = texture2D( tDiffuse, vUv );',
-		'	gl_FragColor.rgb = mulRGB * pow( ( gl_FragColor.rgb + addRGB ), powRGB );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 17 - 21
examples/jsm/shaders/ColorifyShader.js

@@ -6,7 +6,7 @@ import {
  * Colorify shader
  * Colorify shader
  */
  */
 
 
-var ColorifyShader = {
+const ColorifyShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -15,38 +15,34 @@ var ColorifyShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform vec3 color;
+		uniform sampler2D tDiffuse;
 
 
-		'uniform vec3 color;',
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 texel = texture2D( tDiffuse, vUv );
 
 
-		'	vec4 texel = texture2D( tDiffuse, vUv );',
+			vec3 luma = vec3( 0.299, 0.587, 0.114 );
+			float v = dot( texel.xyz, luma );
 
 
-		'	vec3 luma = vec3( 0.299, 0.587, 0.114 );',
-		'	float v = dot( texel.xyz, luma );',
+			gl_FragColor = vec4( v * color, texel.w );
 
 
-		'	gl_FragColor = vec4( v * color, texel.w );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 36 - 39
examples/jsm/shaders/ConvolutionShader.js

@@ -8,7 +8,7 @@ import {
  * http://o3d.googlecode.com/svn/trunk/samples/convolution.html
  * http://o3d.googlecode.com/svn/trunk/samples/convolution.html
  */
  */
 
 
-var ConvolutionShader = {
+const ConvolutionShader = {
 
 
 	defines: {
 	defines: {
 
 
@@ -25,67 +25,58 @@ var ConvolutionShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'uniform vec2 uImageIncrement;',
+		`uniform vec2 uImageIncrement;
 
 
-		'varying vec2 vUv;',
+		varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform float cKernel[ KERNEL_SIZE_INT ];
 
 
-		'uniform float cKernel[ KERNEL_SIZE_INT ];',
+		uniform sampler2D tDiffuse;
+		uniform vec2 uImageIncrement;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform vec2 uImageIncrement;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec2 imageCoord = vUv;
+			vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );
 
 
-		'	vec2 imageCoord = vUv;',
-		'	vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );',
+			for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {
 
 
-		'	for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {',
+				sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];
+				imageCoord += uImageIncrement;
 
 
-		'		sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];',
-		'		imageCoord += uImageIncrement;',
+			}
 
 
-		'	}',
+			gl_FragColor = sum;
 
 
-		'	gl_FragColor = sum;',
-
-		'}'
-
-
-	].join( '\n' ),
+		}`,
 
 
 	buildKernel: function ( sigma ) {
 	buildKernel: function ( sigma ) {
 
 
 		// We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway.
 		// We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway.
 
 
-		function gauss( x, sigma ) {
-
-			return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) );
-
-		}
-
-		var i, values, sum, halfWidth, kMaxKernelSize = 25, kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1;
+		const kMaxKernelSize = 25;
+		let kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1;
 
 
 		if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize;
 		if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize;
-		halfWidth = ( kernelSize - 1 ) * 0.5;
 
 
-		values = new Array( kernelSize );
-		sum = 0.0;
-		for ( i = 0; i < kernelSize; ++ i ) {
+		const halfWidth = ( kernelSize - 1 ) * 0.5;
+
+		const values = new Array( kernelSize );
+		let sum = 0.0;
+		for ( let i = 0; i < kernelSize; ++ i ) {
 
 
 			values[ i ] = gauss( i - halfWidth, sigma );
 			values[ i ] = gauss( i - halfWidth, sigma );
 			sum += values[ i ];
 			sum += values[ i ];
@@ -94,7 +85,7 @@ var ConvolutionShader = {
 
 
 		// normalize the kernel
 		// normalize the kernel
 
 
-		for ( i = 0; i < kernelSize; ++ i ) values[ i ] /= sum;
+		for ( let i = 0; i < kernelSize; ++ i ) values[ i ] /= sum;
 
 
 		return values;
 		return values;
 
 
@@ -102,4 +93,10 @@ var ConvolutionShader = {
 
 
 };
 };
 
 
+function gauss( x, sigma ) {
+
+	return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) );
+
+}
+
 export { ConvolutionShader };
 export { ConvolutionShader };

+ 14 - 18
examples/jsm/shaders/CopyShader.js

@@ -11,35 +11,31 @@ var CopyShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform float opacity;
 
 
-		'uniform float opacity;',
+		uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 texel = texture2D( tDiffuse, vUv );
+			gl_FragColor = opacity * texel;
 
 
-		'	vec4 texel = texture2D( tDiffuse, vUv );',
-		'	gl_FragColor = opacity * texel;',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 20 - 24
examples/jsm/shaders/DOFMipMapShader.js

@@ -4,7 +4,7 @@
  * - requires power-of-2 sized render target with enabled mipmaps
  * - requires power-of-2 sized render target with enabled mipmaps
  */
  */
 
 
-var DOFMipMapShader = {
+const DOFMipMapShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -15,43 +15,39 @@ var DOFMipMapShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform float focus;
+		uniform float maxblur;
 
 
-		'uniform float focus;',
-		'uniform float maxblur;',
+		uniform sampler2D tColor;
+		uniform sampler2D tDepth;
 
 
-		'uniform sampler2D tColor;',
-		'uniform sampler2D tDepth;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 depth = texture2D( tDepth, vUv );
 
 
-		'	vec4 depth = texture2D( tDepth, vUv );',
+			float factor = depth.x - focus;
 
 
-		'	float factor = depth.x - focus;',
+			vec4 col = texture2D( tColor, vUv, 2.0 * maxblur * abs( focus - depth.x ) );
 
 
-		'	vec4 col = texture2D( tColor, vUv, 2.0 * maxblur * abs( focus - depth.x ) );',
+			gl_FragColor = col;
+			gl_FragColor.a = 1.0;
 
 
-		'	gl_FragColor = col;',
-		'	gl_FragColor.a = 1.0;',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 79 - 79
examples/jsm/shaders/DepthLimitedBlurShader.js

@@ -6,7 +6,7 @@ import {
  * TODO
  * TODO
  */
  */
 
 
-var DepthLimitedBlurShader = {
+const DepthLimitedBlurShader = {
 	defines: {
 	defines: {
 		'KERNEL_RADIUS': 4,
 		'KERNEL_RADIUS': 4,
 		'DEPTH_PACKING': 1,
 		'DEPTH_PACKING': 1,
@@ -22,112 +22,106 @@ var DepthLimitedBlurShader = {
 		'cameraFar': { value: 1000 },
 		'cameraFar': { value: 1000 },
 		'depthCutoff': { value: 10 },
 		'depthCutoff': { value: 10 },
 	},
 	},
-	vertexShader: [
-		'#include <common>',
+	vertexShader:
+		`#include <common>
 
 
-		'uniform vec2 size;',
+		uniform vec2 size;
 
 
-		'varying vec2 vUv;',
-		'varying vec2 vInvSize;',
+		varying vec2 vUv;
+		varying vec2 vInvSize;
 
 
-		'void main() {',
-		'	vUv = uv;',
-		'	vInvSize = 1.0 / size;',
+		void main() {
+			vUv = uv;
+			vInvSize = 1.0 / size;
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
-		'}'
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+		}`,
 
 
-	].join( '\n' ),
-	fragmentShader: [
-		'#include <common>',
-		'#include <packing>',
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform sampler2D tDepth;',
+	fragmentShader:
+		`#include <common>
+		#include <packing>
 
 
-		'uniform float cameraNear;',
-		'uniform float cameraFar;',
-		'uniform float depthCutoff;',
+		uniform sampler2D tDiffuse;
+		uniform sampler2D tDepth;
 
 
-		'uniform vec2 sampleUvOffsets[ KERNEL_RADIUS + 1 ];',
-		'uniform float sampleWeights[ KERNEL_RADIUS + 1 ];',
+		uniform float cameraNear;
+		uniform float cameraFar;
+		uniform float depthCutoff;
 
 
-		'varying vec2 vUv;',
-		'varying vec2 vInvSize;',
+		uniform vec2 sampleUvOffsets[ KERNEL_RADIUS + 1 ];
+		uniform float sampleWeights[ KERNEL_RADIUS + 1 ];
 
 
-		'float getDepth( const in vec2 screenPosition ) {',
-		'	#if DEPTH_PACKING == 1',
-		'	return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );',
-		'	#else',
-		'	return texture2D( tDepth, screenPosition ).x;',
-		'	#endif',
-		'}',
+		varying vec2 vUv;
+		varying vec2 vInvSize;
 
 
-		'float getViewZ( const in float depth ) {',
-		'	#if PERSPECTIVE_CAMERA == 1',
-		'	return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );',
-		'	#else',
-		'	return orthographicDepthToViewZ( depth, cameraNear, cameraFar );',
-		'	#endif',
-		'}',
+		float getDepth( const in vec2 screenPosition ) {
+			#if DEPTH_PACKING == 1
+			return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );
+			#else
+			return texture2D( tDepth, screenPosition ).x;
+			#endif
+		}
 
 
-		'void main() {',
-		'	float depth = getDepth( vUv );',
-		'	if( depth >= ( 1.0 - EPSILON ) ) {',
-		'		discard;',
-		'	}',
+		float getViewZ( const in float depth ) {
+			#if PERSPECTIVE_CAMERA == 1
+			return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );
+			#else
+			return orthographicDepthToViewZ( depth, cameraNear, cameraFar );
+			#endif
+		}
 
 
-		'	float centerViewZ = -getViewZ( depth );',
-		'	bool rBreak = false, lBreak = false;',
+		void main() {
+			float depth = getDepth( vUv );
+			if( depth >= ( 1.0 - EPSILON ) ) {
+				discard;
+			}
 
 
-		'	float weightSum = sampleWeights[0];',
-		'	vec4 diffuseSum = texture2D( tDiffuse, vUv ) * weightSum;',
+			float centerViewZ = -getViewZ( depth );
+			bool rBreak = false, lBreak = false;
 
 
-		'	for( int i = 1; i <= KERNEL_RADIUS; i ++ ) {',
+			float weightSum = sampleWeights[0];
+			vec4 diffuseSum = texture2D( tDiffuse, vUv ) * weightSum;
 
 
-		'		float sampleWeight = sampleWeights[i];',
-		'		vec2 sampleUvOffset = sampleUvOffsets[i] * vInvSize;',
+			for( int i = 1; i <= KERNEL_RADIUS; i ++ ) {
 
 
-		'		vec2 sampleUv = vUv + sampleUvOffset;',
-		'		float viewZ = -getViewZ( getDepth( sampleUv ) );',
+				float sampleWeight = sampleWeights[i];
+				vec2 sampleUvOffset = sampleUvOffsets[i] * vInvSize;
 
 
-		'		if( abs( viewZ - centerViewZ ) > depthCutoff ) rBreak = true;',
+				vec2 sampleUv = vUv + sampleUvOffset;
+				float viewZ = -getViewZ( getDepth( sampleUv ) );
 
 
-		'		if( ! rBreak ) {',
-		'			diffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;',
-		'			weightSum += sampleWeight;',
-		'		}',
+				if( abs( viewZ - centerViewZ ) > depthCutoff ) rBreak = true;
 
 
-		'		sampleUv = vUv - sampleUvOffset;',
-		'		viewZ = -getViewZ( getDepth( sampleUv ) );',
+				if( ! rBreak ) {
+					diffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;
+					weightSum += sampleWeight;
+				}
 
 
-		'		if( abs( viewZ - centerViewZ ) > depthCutoff ) lBreak = true;',
+				sampleUv = vUv - sampleUvOffset;
+				viewZ = -getViewZ( getDepth( sampleUv ) );
 
 
-		'		if( ! lBreak ) {',
-		'			diffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;',
-		'			weightSum += sampleWeight;',
-		'		}',
+				if( abs( viewZ - centerViewZ ) > depthCutoff ) lBreak = true;
 
 
-		'	}',
+				if( ! lBreak ) {
+					diffuseSum += texture2D( tDiffuse, sampleUv ) * sampleWeight;
+					weightSum += sampleWeight;
+				}
 
 
-		'	gl_FragColor = diffuseSum / weightSum;',
-		'}'
-	].join( '\n' )
-};
+			}
 
 
-var BlurShaderUtils = {
-
-	createSampleWeights: function ( kernelRadius, stdDev ) {
+			gl_FragColor = diffuseSum / weightSum;
+		}`
 
 
-		var gaussian = function ( x, stdDev ) {
+};
 
 
-			return Math.exp( - ( x * x ) / ( 2.0 * ( stdDev * stdDev ) ) ) / ( Math.sqrt( 2.0 * Math.PI ) * stdDev );
+const BlurShaderUtils = {
 
 
-		};
+	createSampleWeights: function ( kernelRadius, stdDev ) {
 
 
-		var weights = [];
+		const weights = [];
 
 
-		for ( var i = 0; i <= kernelRadius; i ++ ) {
+		for ( let i = 0; i <= kernelRadius; i ++ ) {
 
 
 			weights.push( gaussian( i, stdDev ) );
 			weights.push( gaussian( i, stdDev ) );
 
 
@@ -139,9 +133,9 @@ var BlurShaderUtils = {
 
 
 	createSampleOffsets: function ( kernelRadius, uvIncrement ) {
 	createSampleOffsets: function ( kernelRadius, uvIncrement ) {
 
 
-		var offsets = [];
+		const offsets = [];
 
 
-		for ( var i = 0; i <= kernelRadius; i ++ ) {
+		for ( let i = 0; i <= kernelRadius; i ++ ) {
 
 
 			offsets.push( uvIncrement.clone().multiplyScalar( i ) );
 			offsets.push( uvIncrement.clone().multiplyScalar( i ) );
 
 
@@ -162,4 +156,10 @@ var BlurShaderUtils = {
 
 
 };
 };
 
 
+function gaussian( x, stdDev ) {
+
+	return Math.exp( - ( x * x ) / ( 2.0 * ( stdDev * stdDev ) ) ) / ( Math.sqrt( 2.0 * Math.PI ) * stdDev );
+
+}
+
 export { DepthLimitedBlurShader, BlurShaderUtils };
 export { DepthLimitedBlurShader, BlurShaderUtils };

+ 62 - 65
examples/jsm/shaders/DigitalGlitch.js

@@ -8,7 +8,7 @@
  * angle: shift angle in radians
  * angle: shift angle in radians
  */
  */
 
 
-var DigitalGlitch = {
+const DigitalGlitch = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -25,78 +25,75 @@ var DigitalGlitch = {
 		'col_s': { value: 0.05 }
 		'col_s': { value: 0.05 }
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
-		'void main() {',
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
-		'}'
-	].join( '\n' ),
+		`varying vec2 vUv;
+		void main() {
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+		}`,
 
 
-	fragmentShader: [
-		'uniform int byp;', //should we apply the glitch ?
+	fragmentShader:
+		`uniform int byp; //should we apply the glitch ?
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform sampler2D tDisp;',
+		uniform sampler2D tDiffuse;
+		uniform sampler2D tDisp;
 
 
-		'uniform float amount;',
-		'uniform float angle;',
-		'uniform float seed;',
-		'uniform float seed_x;',
-		'uniform float seed_y;',
-		'uniform float distortion_x;',
-		'uniform float distortion_y;',
-		'uniform float col_s;',
+		uniform float amount;
+		uniform float angle;
+		uniform float seed;
+		uniform float seed_x;
+		uniform float seed_y;
+		uniform float distortion_x;
+		uniform float distortion_y;
+		uniform float col_s;
 
 
-		'varying vec2 vUv;',
+		varying vec2 vUv;
 
 
 
 
-		'float rand(vec2 co){',
-		'	return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);',
-		'}',
+		float rand(vec2 co){
+			return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
+		}
 
 
-		'void main() {',
-		'	if(byp<1) {',
-		'		vec2 p = vUv;',
-		'		float xs = floor(gl_FragCoord.x / 0.5);',
-		'		float ys = floor(gl_FragCoord.y / 0.5);',
-		//based on staffantans glitch shader for unity https://github.com/staffantan/unityglitch
-		'		vec4 normal = texture2D (tDisp, p*seed*seed);',
-		'		if(p.y<distortion_x+col_s && p.y>distortion_x-col_s*seed) {',
-		'			if(seed_x>0.){',
-		'				p.y = 1. - (p.y + distortion_y);',
-		'			}',
-		'			else {',
-		'				p.y = distortion_y;',
-		'			}',
-		'		}',
-		'		if(p.x<distortion_y+col_s && p.x>distortion_y-col_s*seed) {',
-		'			if(seed_y>0.){',
-		'				p.x=distortion_x;',
-		'			}',
-		'			else {',
-		'				p.x = 1. - (p.x + distortion_x);',
-		'			}',
-		'		}',
-		'		p.x+=normal.x*seed_x*(seed/5.);',
-		'		p.y+=normal.y*seed_y*(seed/5.);',
-		//base from RGB shift shader
-		'		vec2 offset = amount * vec2( cos(angle), sin(angle));',
-		'		vec4 cr = texture2D(tDiffuse, p + offset);',
-		'		vec4 cga = texture2D(tDiffuse, p);',
-		'		vec4 cb = texture2D(tDiffuse, p - offset);',
-		'		gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);',
-		//add noise
-		'		vec4 snow = 200.*amount*vec4(rand(vec2(xs * seed,ys * seed*50.))*0.2);',
-		'		gl_FragColor = gl_FragColor+ snow;',
-		'	}',
-		'	else {',
-		'		gl_FragColor=texture2D (tDiffuse, vUv);',
-		'	}',
-		'}'
-
-	].join( '\n' )
+		void main() {
+			if(byp<1) {
+				vec2 p = vUv;
+				float xs = floor(gl_FragCoord.x / 0.5);
+				float ys = floor(gl_FragCoord.y / 0.5);
+				//based on staffantans glitch shader for unity https://github.com/staffantan/unityglitch
+				vec4 normal = texture2D (tDisp, p*seed*seed);
+				if(p.y<distortion_x+col_s && p.y>distortion_x-col_s*seed) {
+					if(seed_x>0.){
+						p.y = 1. - (p.y + distortion_y);
+					}
+					else {
+						p.y = distortion_y;
+					}
+				}
+				if(p.x<distortion_y+col_s && p.x>distortion_y-col_s*seed) {
+					if(seed_y>0.){
+						p.x=distortion_x;
+					}
+					else {
+						p.x = 1. - (p.x + distortion_x);
+					}
+				}
+				p.x+=normal.x*seed_x*(seed/5.);
+				p.y+=normal.y*seed_y*(seed/5.);
+				//base from RGB shift shader
+				vec2 offset = amount * vec2( cos(angle), sin(angle));
+				vec4 cr = texture2D(tDiffuse, p + offset);
+				vec4 cga = texture2D(tDiffuse, p);
+				vec4 cb = texture2D(tDiffuse, p - offset);
+				gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);
+				//add noise
+				vec4 snow = 200.*amount*vec4(rand(vec2(xs * seed,ys * seed*50.))*0.2);
+				gl_FragColor = gl_FragColor+ snow;
+			}
+			else {
+				gl_FragColor=texture2D (tDiffuse, vUv);
+			}
+		}`
 
 
 };
 };
 
 

+ 25 - 29
examples/jsm/shaders/DotScreenShader.js

@@ -8,7 +8,7 @@ import {
  * https://github.com/evanw/glfx.js
  * https://github.com/evanw/glfx.js
  */
  */
 
 
-var DotScreenShader = {
+const DotScreenShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -20,52 +20,48 @@ var DotScreenShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform vec2 center;
+		uniform float angle;
+		uniform float scale;
+		uniform vec2 tSize;
 
 
-		'uniform vec2 center;',
-		'uniform float angle;',
-		'uniform float scale;',
-		'uniform vec2 tSize;',
+		uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		float pattern() {
 
 
-		'float pattern() {',
+			float s = sin( angle ), c = cos( angle );
 
 
-		'	float s = sin( angle ), c = cos( angle );',
+			vec2 tex = vUv * tSize - center;
+			vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;
 
 
-		'	vec2 tex = vUv * tSize - center;',
-		'	vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;',
+			return ( sin( point.x ) * sin( point.y ) ) * 4.0;
 
 
-		'	return ( sin( point.x ) * sin( point.y ) ) * 4.0;',
+		}
 
 
-		'}',
+		void main() {
 
 
-		'void main() {',
+			vec4 color = texture2D( tDiffuse, vUv );
 
 
-		'	vec4 color = texture2D( tDiffuse, vUv );',
+			float average = ( color.r + color.g + color.b ) / 3.0;
 
 
-		'	float average = ( color.r + color.g + color.b ) / 3.0;',
+			gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );
 
 
-		'	gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 1087 - 1089
examples/jsm/shaders/FXAAShader.js

@@ -9,7 +9,7 @@ import {
  * http://www.glge.org/demos/fxaa/
  * http://www.glge.org/demos/fxaa/
  */
  */
 
 
-var FXAAShader = {
+const FXAAShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -18,1100 +18,1098 @@ var FXAAShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
-		'precision highp float;',
-		'',
-		'uniform sampler2D tDiffuse;',
-		'',
-		'uniform vec2 resolution;',
-		'',
-		'varying vec2 vUv;',
-		'',
-		'// FXAA 3.11 implementation by NVIDIA, ported to WebGL by Agost Biro ([email protected])',
-		'',
-		'//----------------------------------------------------------------------------------',
-		'// File:        es3-kepler\FXAA\assets\shaders/FXAA_DefaultES.frag',
-		'// SDK Version: v3.00',
-		'// Email:       [email protected]',
-		'// Site:        http://developer.nvidia.com/',
-		'//',
-		'// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.',
-		'//',
-		'// Redistribution and use in source and binary forms, with or without',
-		'// modification, are permitted provided that the following conditions',
-		'// are met:',
-		'//  * Redistributions of source code must retain the above copyright',
-		'//    notice, this list of conditions and the following disclaimer.',
-		'//  * Redistributions in binary form must reproduce the above copyright',
-		'//    notice, this list of conditions and the following disclaimer in the',
-		'//    documentation and/or other materials provided with the distribution.',
-		'//  * Neither the name of NVIDIA CORPORATION nor the names of its',
-		'//    contributors may be used to endorse or promote products derived',
-		'//    from this software without specific prior written permission.',
-		'//',
-		'// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS\'\' AND ANY',
-		'// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE',
-		'// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR',
-		'// PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR',
-		'// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,',
-		'// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,',
-		'// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR',
-		'// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY',
-		'// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT',
-		'// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE',
-		'// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.',
-		'//',
-		'//----------------------------------------------------------------------------------',
-		'',
-		'#define FXAA_PC 1',
-		'#define FXAA_GLSL_100 1',
-		'#define FXAA_QUALITY_PRESET 12',
-		'',
-		'#define FXAA_GREEN_AS_LUMA 1',
-		'',
-		'/*--------------------------------------------------------------------------*/',
-		'#ifndef FXAA_PC_CONSOLE',
-		'    //',
-		'    // The console algorithm for PC is included',
-		'    // for developers targeting really low spec machines.',
-		'    // Likely better to just run FXAA_PC, and use a really low preset.',
-		'    //',
-		'    #define FXAA_PC_CONSOLE 0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#ifndef FXAA_GLSL_120',
-		'    #define FXAA_GLSL_120 0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#ifndef FXAA_GLSL_130',
-		'    #define FXAA_GLSL_130 0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#ifndef FXAA_HLSL_3',
-		'    #define FXAA_HLSL_3 0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#ifndef FXAA_HLSL_4',
-		'    #define FXAA_HLSL_4 0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#ifndef FXAA_HLSL_5',
-		'    #define FXAA_HLSL_5 0',
-		'#endif',
-		'/*==========================================================================*/',
-		'#ifndef FXAA_GREEN_AS_LUMA',
-		'    //',
-		'    // For those using non-linear color,',
-		'    // and either not able to get luma in alpha, or not wanting to,',
-		'    // this enables FXAA to run using green as a proxy for luma.',
-		'    // So with this enabled, no need to pack luma in alpha.',
-		'    //',
-		'    // This will turn off AA on anything which lacks some amount of green.',
-		'    // Pure red and blue or combination of only R and B, will get no AA.',
-		'    //',
-		'    // Might want to lower the settings for both,',
-		'    //    fxaaConsoleEdgeThresholdMin',
-		'    //    fxaaQualityEdgeThresholdMin',
-		'    // In order to insure AA does not get turned off on colors',
-		'    // which contain a minor amount of green.',
-		'    //',
-		'    // 1 = On.',
-		'    // 0 = Off.',
-		'    //',
-		'    #define FXAA_GREEN_AS_LUMA 0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#ifndef FXAA_EARLY_EXIT',
-		'    //',
-		'    // Controls algorithm\'s early exit path.',
-		'    // On PS3 turning this ON adds 2 cycles to the shader.',
-		'    // On 360 turning this OFF adds 10ths of a millisecond to the shader.',
-		'    // Turning this off on console will result in a more blurry image.',
-		'    // So this defaults to on.',
-		'    //',
-		'    // 1 = On.',
-		'    // 0 = Off.',
-		'    //',
-		'    #define FXAA_EARLY_EXIT 1',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#ifndef FXAA_DISCARD',
-		'    //',
-		'    // Only valid for PC OpenGL currently.',
-		'    // Probably will not work when FXAA_GREEN_AS_LUMA = 1.',
-		'    //',
-		'    // 1 = Use discard on pixels which don\'t need AA.',
-		'    //     For APIs which enable concurrent TEX+ROP from same surface.',
-		'    // 0 = Return unchanged color on pixels which don\'t need AA.',
-		'    //',
-		'    #define FXAA_DISCARD 0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#ifndef FXAA_FAST_PIXEL_OFFSET',
-		'    //',
-		'    // Used for GLSL 120 only.',
-		'    //',
-		'    // 1 = GL API supports fast pixel offsets',
-		'    // 0 = do not use fast pixel offsets',
-		'    //',
-		'    #ifdef GL_EXT_gpu_shader4',
-		'        #define FXAA_FAST_PIXEL_OFFSET 1',
-		'    #endif',
-		'    #ifdef GL_NV_gpu_shader5',
-		'        #define FXAA_FAST_PIXEL_OFFSET 1',
-		'    #endif',
-		'    #ifdef GL_ARB_gpu_shader5',
-		'        #define FXAA_FAST_PIXEL_OFFSET 1',
-		'    #endif',
-		'    #ifndef FXAA_FAST_PIXEL_OFFSET',
-		'        #define FXAA_FAST_PIXEL_OFFSET 0',
-		'    #endif',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#ifndef FXAA_GATHER4_ALPHA',
-		'    //',
-		'    // 1 = API supports gather4 on alpha channel.',
-		'    // 0 = API does not support gather4 on alpha channel.',
-		'    //',
-		'    #if (FXAA_HLSL_5 == 1)',
-		'        #define FXAA_GATHER4_ALPHA 1',
-		'    #endif',
-		'    #ifdef GL_ARB_gpu_shader5',
-		'        #define FXAA_GATHER4_ALPHA 1',
-		'    #endif',
-		'    #ifdef GL_NV_gpu_shader5',
-		'        #define FXAA_GATHER4_ALPHA 1',
-		'    #endif',
-		'    #ifndef FXAA_GATHER4_ALPHA',
-		'        #define FXAA_GATHER4_ALPHA 0',
-		'    #endif',
-		'#endif',
-		'',
-		'',
-		'/*============================================================================',
-		'                        FXAA QUALITY - TUNING KNOBS',
-		'------------------------------------------------------------------------------',
-		'NOTE the other tuning knobs are now in the shader function inputs!',
-		'============================================================================*/',
-		'#ifndef FXAA_QUALITY_PRESET',
-		'    //',
-		'    // Choose the quality preset.',
-		'    // This needs to be compiled into the shader as it effects code.',
-		'    // Best option to include multiple presets is to',
-		'    // in each shader define the preset, then include this file.',
-		'    //',
-		'    // OPTIONS',
-		'    // -----------------------------------------------------------------------',
-		'    // 10 to 15 - default medium dither (10=fastest, 15=highest quality)',
-		'    // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)',
-		'    // 39       - no dither, very expensive',
-		'    //',
-		'    // NOTES',
-		'    // -----------------------------------------------------------------------',
-		'    // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)',
-		'    // 13 = about same speed as FXAA 3.9 and better than 12',
-		'    // 23 = closest to FXAA 3.9 visually and performance wise',
-		'    //  _ = the lowest digit is directly related to performance',
-		'    // _  = the highest digit is directly related to style',
-		'    //',
-		'    #define FXAA_QUALITY_PRESET 12',
-		'#endif',
-		'',
-		'',
-		'/*============================================================================',
-		'',
-		'                           FXAA QUALITY - PRESETS',
-		'',
-		'============================================================================*/',
-		'',
-		'/*============================================================================',
-		'                     FXAA QUALITY - MEDIUM DITHER PRESETS',
-		'============================================================================*/',
-		'#if (FXAA_QUALITY_PRESET == 10)',
-		'    #define FXAA_QUALITY_PS 3',
-		'    #define FXAA_QUALITY_P0 1.5',
-		'    #define FXAA_QUALITY_P1 3.0',
-		'    #define FXAA_QUALITY_P2 12.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 11)',
-		'    #define FXAA_QUALITY_PS 4',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 3.0',
-		'    #define FXAA_QUALITY_P3 12.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 12)',
-		'    #define FXAA_QUALITY_PS 5',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 4.0',
-		'    #define FXAA_QUALITY_P4 12.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 13)',
-		'    #define FXAA_QUALITY_PS 6',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 4.0',
-		'    #define FXAA_QUALITY_P5 12.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 14)',
-		'    #define FXAA_QUALITY_PS 7',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 2.0',
-		'    #define FXAA_QUALITY_P5 4.0',
-		'    #define FXAA_QUALITY_P6 12.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 15)',
-		'    #define FXAA_QUALITY_PS 8',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 2.0',
-		'    #define FXAA_QUALITY_P5 2.0',
-		'    #define FXAA_QUALITY_P6 4.0',
-		'    #define FXAA_QUALITY_P7 12.0',
-		'#endif',
-		'',
-		'/*============================================================================',
-		'                     FXAA QUALITY - LOW DITHER PRESETS',
-		'============================================================================*/',
-		'#if (FXAA_QUALITY_PRESET == 20)',
-		'    #define FXAA_QUALITY_PS 3',
-		'    #define FXAA_QUALITY_P0 1.5',
-		'    #define FXAA_QUALITY_P1 2.0',
-		'    #define FXAA_QUALITY_P2 8.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 21)',
-		'    #define FXAA_QUALITY_PS 4',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 8.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 22)',
-		'    #define FXAA_QUALITY_PS 5',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 8.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 23)',
-		'    #define FXAA_QUALITY_PS 6',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 2.0',
-		'    #define FXAA_QUALITY_P5 8.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 24)',
-		'    #define FXAA_QUALITY_PS 7',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 2.0',
-		'    #define FXAA_QUALITY_P5 3.0',
-		'    #define FXAA_QUALITY_P6 8.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 25)',
-		'    #define FXAA_QUALITY_PS 8',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 2.0',
-		'    #define FXAA_QUALITY_P5 2.0',
-		'    #define FXAA_QUALITY_P6 4.0',
-		'    #define FXAA_QUALITY_P7 8.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 26)',
-		'    #define FXAA_QUALITY_PS 9',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 2.0',
-		'    #define FXAA_QUALITY_P5 2.0',
-		'    #define FXAA_QUALITY_P6 2.0',
-		'    #define FXAA_QUALITY_P7 4.0',
-		'    #define FXAA_QUALITY_P8 8.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 27)',
-		'    #define FXAA_QUALITY_PS 10',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 2.0',
-		'    #define FXAA_QUALITY_P5 2.0',
-		'    #define FXAA_QUALITY_P6 2.0',
-		'    #define FXAA_QUALITY_P7 2.0',
-		'    #define FXAA_QUALITY_P8 4.0',
-		'    #define FXAA_QUALITY_P9 8.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 28)',
-		'    #define FXAA_QUALITY_PS 11',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 2.0',
-		'    #define FXAA_QUALITY_P5 2.0',
-		'    #define FXAA_QUALITY_P6 2.0',
-		'    #define FXAA_QUALITY_P7 2.0',
-		'    #define FXAA_QUALITY_P8 2.0',
-		'    #define FXAA_QUALITY_P9 4.0',
-		'    #define FXAA_QUALITY_P10 8.0',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_QUALITY_PRESET == 29)',
-		'    #define FXAA_QUALITY_PS 12',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.5',
-		'    #define FXAA_QUALITY_P2 2.0',
-		'    #define FXAA_QUALITY_P3 2.0',
-		'    #define FXAA_QUALITY_P4 2.0',
-		'    #define FXAA_QUALITY_P5 2.0',
-		'    #define FXAA_QUALITY_P6 2.0',
-		'    #define FXAA_QUALITY_P7 2.0',
-		'    #define FXAA_QUALITY_P8 2.0',
-		'    #define FXAA_QUALITY_P9 2.0',
-		'    #define FXAA_QUALITY_P10 4.0',
-		'    #define FXAA_QUALITY_P11 8.0',
-		'#endif',
-		'',
-		'/*============================================================================',
-		'                     FXAA QUALITY - EXTREME QUALITY',
-		'============================================================================*/',
-		'#if (FXAA_QUALITY_PRESET == 39)',
-		'    #define FXAA_QUALITY_PS 12',
-		'    #define FXAA_QUALITY_P0 1.0',
-		'    #define FXAA_QUALITY_P1 1.0',
-		'    #define FXAA_QUALITY_P2 1.0',
-		'    #define FXAA_QUALITY_P3 1.0',
-		'    #define FXAA_QUALITY_P4 1.0',
-		'    #define FXAA_QUALITY_P5 1.5',
-		'    #define FXAA_QUALITY_P6 2.0',
-		'    #define FXAA_QUALITY_P7 2.0',
-		'    #define FXAA_QUALITY_P8 2.0',
-		'    #define FXAA_QUALITY_P9 2.0',
-		'    #define FXAA_QUALITY_P10 4.0',
-		'    #define FXAA_QUALITY_P11 8.0',
-		'#endif',
-		'',
-		'',
-		'',
-		'/*============================================================================',
-		'',
-		'                                API PORTING',
-		'',
-		'============================================================================*/',
-		'#if (FXAA_GLSL_100 == 1) || (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)',
-		'    #define FxaaBool bool',
-		'    #define FxaaDiscard discard',
-		'    #define FxaaFloat float',
-		'    #define FxaaFloat2 vec2',
-		'    #define FxaaFloat3 vec3',
-		'    #define FxaaFloat4 vec4',
-		'    #define FxaaHalf float',
-		'    #define FxaaHalf2 vec2',
-		'    #define FxaaHalf3 vec3',
-		'    #define FxaaHalf4 vec4',
-		'    #define FxaaInt2 ivec2',
-		'    #define FxaaSat(x) clamp(x, 0.0, 1.0)',
-		'    #define FxaaTex sampler2D',
-		'#else',
-		'    #define FxaaBool bool',
-		'    #define FxaaDiscard clip(-1)',
-		'    #define FxaaFloat float',
-		'    #define FxaaFloat2 float2',
-		'    #define FxaaFloat3 float3',
-		'    #define FxaaFloat4 float4',
-		'    #define FxaaHalf half',
-		'    #define FxaaHalf2 half2',
-		'    #define FxaaHalf3 half3',
-		'    #define FxaaHalf4 half4',
-		'    #define FxaaSat(x) saturate(x)',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_GLSL_100 == 1)',
-		'  #define FxaaTexTop(t, p) texture2D(t, p, 0.0)',
-		'  #define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r), 0.0)',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_GLSL_120 == 1)',
-		'    // Requires,',
-		'    //  #version 120',
-		'    // And at least,',
-		'    //  #extension GL_EXT_gpu_shader4 : enable',
-		'    //  (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)',
-		'    #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)',
-		'    #if (FXAA_FAST_PIXEL_OFFSET == 1)',
-		'        #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)',
-		'    #else',
-		'        #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)',
-		'    #endif',
-		'    #if (FXAA_GATHER4_ALPHA == 1)',
-		'        // use #extension GL_ARB_gpu_shader5 : enable',
-		'        #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)',
-		'        #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)',
-		'        #define FxaaTexGreen4(t, p) textureGather(t, p, 1)',
-		'        #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)',
-		'    #endif',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_GLSL_130 == 1)',
-		'    // Requires "#version 130" or better',
-		'    #define FxaaTexTop(t, p) textureLod(t, p, 0.0)',
-		'    #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)',
-		'    #if (FXAA_GATHER4_ALPHA == 1)',
-		'        // use #extension GL_ARB_gpu_shader5 : enable',
-		'        #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)',
-		'        #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)',
-		'        #define FxaaTexGreen4(t, p) textureGather(t, p, 1)',
-		'        #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)',
-		'    #endif',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_HLSL_3 == 1)',
-		'    #define FxaaInt2 float2',
-		'    #define FxaaTex sampler2D',
-		'    #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))',
-		'    #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_HLSL_4 == 1)',
-		'    #define FxaaInt2 int2',
-		'    struct FxaaTex { SamplerState smpl; Texture2D tex; };',
-		'    #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)',
-		'    #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)',
-		'#endif',
-		'/*--------------------------------------------------------------------------*/',
-		'#if (FXAA_HLSL_5 == 1)',
-		'    #define FxaaInt2 int2',
-		'    struct FxaaTex { SamplerState smpl; Texture2D tex; };',
-		'    #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)',
-		'    #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)',
-		'    #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)',
-		'    #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)',
-		'    #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)',
-		'    #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)',
-		'#endif',
-		'',
-		'',
-		'/*============================================================================',
-		'                   GREEN AS LUMA OPTION SUPPORT FUNCTION',
-		'============================================================================*/',
-		'#if (FXAA_GREEN_AS_LUMA == 0)',
-		'    FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }',
-		'#else',
-		'    FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }',
-		'#endif',
-		'',
-		'',
-		'',
-		'',
-		'/*============================================================================',
-		'',
-		'                             FXAA3 QUALITY - PC',
-		'',
-		'============================================================================*/',
-		'#if (FXAA_PC == 1)',
-		'/*--------------------------------------------------------------------------*/',
-		'FxaaFloat4 FxaaPixelShader(',
-		'    //',
-		'    // Use noperspective interpolation here (turn off perspective interpolation).',
-		'    // {xy} = center of pixel',
-		'    FxaaFloat2 pos,',
-		'    //',
-		'    // Used only for FXAA Console, and not used on the 360 version.',
-		'    // Use noperspective interpolation here (turn off perspective interpolation).',
-		'    // {xy_} = upper left of pixel',
-		'    // {_zw} = lower right of pixel',
-		'    FxaaFloat4 fxaaConsolePosPos,',
-		'    //',
-		'    // Input color texture.',
-		'    // {rgb_} = color in linear or perceptual color space',
-		'    // if (FXAA_GREEN_AS_LUMA == 0)',
-		'    //     {__a} = luma in perceptual color space (not linear)',
-		'    FxaaTex tex,',
-		'    //',
-		'    // Only used on the optimized 360 version of FXAA Console.',
-		'    // For everything but 360, just use the same input here as for "tex".',
-		'    // For 360, same texture, just alias with a 2nd sampler.',
-		'    // This sampler needs to have an exponent bias of -1.',
-		'    FxaaTex fxaaConsole360TexExpBiasNegOne,',
-		'    //',
-		'    // Only used on the optimized 360 version of FXAA Console.',
-		'    // For everything but 360, just use the same input here as for "tex".',
-		'    // For 360, same texture, just alias with a 3nd sampler.',
-		'    // This sampler needs to have an exponent bias of -2.',
-		'    FxaaTex fxaaConsole360TexExpBiasNegTwo,',
-		'    //',
-		'    // Only used on FXAA Quality.',
-		'    // This must be from a constant/uniform.',
-		'    // {x_} = 1.0/screenWidthInPixels',
-		'    // {_y} = 1.0/screenHeightInPixels',
-		'    FxaaFloat2 fxaaQualityRcpFrame,',
-		'    //',
-		'    // Only used on FXAA Console.',
-		'    // This must be from a constant/uniform.',
-		'    // This effects sub-pixel AA quality and inversely sharpness.',
-		'    //   Where N ranges between,',
-		'    //     N = 0.50 (default)',
-		'    //     N = 0.33 (sharper)',
-		'    // {x__} = -N/screenWidthInPixels',
-		'    // {_y_} = -N/screenHeightInPixels',
-		'    // {_z_} =  N/screenWidthInPixels',
-		'    // {__w} =  N/screenHeightInPixels',
-		'    FxaaFloat4 fxaaConsoleRcpFrameOpt,',
-		'    //',
-		'    // Only used on FXAA Console.',
-		'    // Not used on 360, but used on PS3 and PC.',
-		'    // This must be from a constant/uniform.',
-		'    // {x__} = -2.0/screenWidthInPixels',
-		'    // {_y_} = -2.0/screenHeightInPixels',
-		'    // {_z_} =  2.0/screenWidthInPixels',
-		'    // {__w} =  2.0/screenHeightInPixels',
-		'    FxaaFloat4 fxaaConsoleRcpFrameOpt2,',
-		'    //',
-		'    // Only used on FXAA Console.',
-		'    // Only used on 360 in place of fxaaConsoleRcpFrameOpt2.',
-		'    // This must be from a constant/uniform.',
-		'    // {x__} =  8.0/screenWidthInPixels',
-		'    // {_y_} =  8.0/screenHeightInPixels',
-		'    // {_z_} = -4.0/screenWidthInPixels',
-		'    // {__w} = -4.0/screenHeightInPixels',
-		'    FxaaFloat4 fxaaConsole360RcpFrameOpt2,',
-		'    //',
-		'    // Only used on FXAA Quality.',
-		'    // This used to be the FXAA_QUALITY_SUBPIX define.',
-		'    // It is here now to allow easier tuning.',
-		'    // Choose the amount of sub-pixel aliasing removal.',
-		'    // This can effect sharpness.',
-		'    //   1.00 - upper limit (softer)',
-		'    //   0.75 - default amount of filtering',
-		'    //   0.50 - lower limit (sharper, less sub-pixel aliasing removal)',
-		'    //   0.25 - almost off',
-		'    //   0.00 - completely off',
-		'    FxaaFloat fxaaQualitySubpix,',
-		'    //',
-		'    // Only used on FXAA Quality.',
-		'    // This used to be the FXAA_QUALITY_EDGE_THRESHOLD define.',
-		'    // It is here now to allow easier tuning.',
-		'    // The minimum amount of local contrast required to apply algorithm.',
-		'    //   0.333 - too little (faster)',
-		'    //   0.250 - low quality',
-		'    //   0.166 - default',
-		'    //   0.125 - high quality',
-		'    //   0.063 - overkill (slower)',
-		'    FxaaFloat fxaaQualityEdgeThreshold,',
-		'    //',
-		'    // Only used on FXAA Quality.',
-		'    // This used to be the FXAA_QUALITY_EDGE_THRESHOLD_MIN define.',
-		'    // It is here now to allow easier tuning.',
-		'    // Trims the algorithm from processing darks.',
-		'    //   0.0833 - upper limit (default, the start of visible unfiltered edges)',
-		'    //   0.0625 - high quality (faster)',
-		'    //   0.0312 - visible limit (slower)',
-		'    // Special notes when using FXAA_GREEN_AS_LUMA,',
-		'    //   Likely want to set this to zero.',
-		'    //   As colors that are mostly not-green',
-		'    //   will appear very dark in the green channel!',
-		'    //   Tune by looking at mostly non-green content,',
-		'    //   then start at zero and increase until aliasing is a problem.',
-		'    FxaaFloat fxaaQualityEdgeThresholdMin,',
-		'    //',
-		'    // Only used on FXAA Console.',
-		'    // This used to be the FXAA_CONSOLE_EDGE_SHARPNESS define.',
-		'    // It is here now to allow easier tuning.',
-		'    // This does not effect PS3, as this needs to be compiled in.',
-		'    //   Use FXAA_CONSOLE_PS3_EDGE_SHARPNESS for PS3.',
-		'    //   Due to the PS3 being ALU bound,',
-		'    //   there are only three safe values here: 2 and 4 and 8.',
-		'    //   These options use the shaders ability to a free *|/ by 2|4|8.',
-		'    // For all other platforms can be a non-power of two.',
-		'    //   8.0 is sharper (default!!!)',
-		'    //   4.0 is softer',
-		'    //   2.0 is really soft (good only for vector graphics inputs)',
-		'    FxaaFloat fxaaConsoleEdgeSharpness,',
-		'    //',
-		'    // Only used on FXAA Console.',
-		'    // This used to be the FXAA_CONSOLE_EDGE_THRESHOLD define.',
-		'    // It is here now to allow easier tuning.',
-		'    // This does not effect PS3, as this needs to be compiled in.',
-		'    //   Use FXAA_CONSOLE_PS3_EDGE_THRESHOLD for PS3.',
-		'    //   Due to the PS3 being ALU bound,',
-		'    //   there are only two safe values here: 1/4 and 1/8.',
-		'    //   These options use the shaders ability to a free *|/ by 2|4|8.',
-		'    // The console setting has a different mapping than the quality setting.',
-		'    // Other platforms can use other values.',
-		'    //   0.125 leaves less aliasing, but is softer (default!!!)',
-		'    //   0.25 leaves more aliasing, and is sharper',
-		'    FxaaFloat fxaaConsoleEdgeThreshold,',
-		'    //',
-		'    // Only used on FXAA Console.',
-		'    // This used to be the FXAA_CONSOLE_EDGE_THRESHOLD_MIN define.',
-		'    // It is here now to allow easier tuning.',
-		'    // Trims the algorithm from processing darks.',
-		'    // The console setting has a different mapping than the quality setting.',
-		'    // This only applies when FXAA_EARLY_EXIT is 1.',
-		'    // This does not apply to PS3,',
-		'    // PS3 was simplified to avoid more shader instructions.',
-		'    //   0.06 - faster but more aliasing in darks',
-		'    //   0.05 - default',
-		'    //   0.04 - slower and less aliasing in darks',
-		'    // Special notes when using FXAA_GREEN_AS_LUMA,',
-		'    //   Likely want to set this to zero.',
-		'    //   As colors that are mostly not-green',
-		'    //   will appear very dark in the green channel!',
-		'    //   Tune by looking at mostly non-green content,',
-		'    //   then start at zero and increase until aliasing is a problem.',
-		'    FxaaFloat fxaaConsoleEdgeThresholdMin,',
-		'    //',
-		'    // Extra constants for 360 FXAA Console only.',
-		'    // Use zeros or anything else for other platforms.',
-		'    // These must be in physical constant registers and NOT immediates.',
-		'    // Immediates will result in compiler un-optimizing.',
-		'    // {xyzw} = float4(1.0, -1.0, 0.25, -0.25)',
-		'    FxaaFloat4 fxaaConsole360ConstDir',
-		') {',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat2 posM;',
-		'    posM.x = pos.x;',
-		'    posM.y = pos.y;',
-		'    #if (FXAA_GATHER4_ALPHA == 1)',
-		'        #if (FXAA_DISCARD == 0)',
-		'            FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);',
-		'            #if (FXAA_GREEN_AS_LUMA == 0)',
-		'                #define lumaM rgbyM.w',
-		'            #else',
-		'                #define lumaM rgbyM.y',
-		'            #endif',
-		'        #endif',
-		'        #if (FXAA_GREEN_AS_LUMA == 0)',
-		'            FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);',
-		'            FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));',
-		'        #else',
-		'            FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);',
-		'            FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));',
-		'        #endif',
-		'        #if (FXAA_DISCARD == 1)',
-		'            #define lumaM luma4A.w',
-		'        #endif',
-		'        #define lumaE luma4A.z',
-		'        #define lumaS luma4A.x',
-		'        #define lumaSE luma4A.y',
-		'        #define lumaNW luma4B.w',
-		'        #define lumaN luma4B.z',
-		'        #define lumaW luma4B.x',
-		'    #else',
-		'        FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);',
-		'        #if (FXAA_GREEN_AS_LUMA == 0)',
-		'            #define lumaM rgbyM.w',
-		'        #else',
-		'            #define lumaM rgbyM.y',
-		'        #endif',
-		'        #if (FXAA_GLSL_100 == 1)',
-		'          FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 0.0, 1.0), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0, 0.0), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 0.0,-1.0), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0, 0.0), fxaaQualityRcpFrame.xy));',
-		'        #else',
-		'          FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));',
-		'        #endif',
-		'    #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat maxSM = max(lumaS, lumaM);',
-		'    FxaaFloat minSM = min(lumaS, lumaM);',
-		'    FxaaFloat maxESM = max(lumaE, maxSM);',
-		'    FxaaFloat minESM = min(lumaE, minSM);',
-		'    FxaaFloat maxWN = max(lumaN, lumaW);',
-		'    FxaaFloat minWN = min(lumaN, lumaW);',
-		'    FxaaFloat rangeMax = max(maxWN, maxESM);',
-		'    FxaaFloat rangeMin = min(minWN, minESM);',
-		'    FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;',
-		'    FxaaFloat range = rangeMax - rangeMin;',
-		'    FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);',
-		'    FxaaBool earlyExit = range < rangeMaxClamped;',
-		'/*--------------------------------------------------------------------------*/',
-		'    if(earlyExit)',
-		'        #if (FXAA_DISCARD == 1)',
-		'            FxaaDiscard;',
-		'        #else',
-		'            return rgbyM;',
-		'        #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'    #if (FXAA_GATHER4_ALPHA == 0)',
-		'        #if (FXAA_GLSL_100 == 1)',
-		'          FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0,-1.0), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0, 1.0), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0,-1.0), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0, 1.0), fxaaQualityRcpFrame.xy));',
-		'        #else',
-		'          FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));',
-		'          FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));',
-		'        #endif',
-		'    #else',
-		'        FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));',
-		'        FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));',
-		'    #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat lumaNS = lumaN + lumaS;',
-		'    FxaaFloat lumaWE = lumaW + lumaE;',
-		'    FxaaFloat subpixRcpRange = 1.0/range;',
-		'    FxaaFloat subpixNSWE = lumaNS + lumaWE;',
-		'    FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;',
-		'    FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat lumaNESE = lumaNE + lumaSE;',
-		'    FxaaFloat lumaNWNE = lumaNW + lumaNE;',
-		'    FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;',
-		'    FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat lumaNWSW = lumaNW + lumaSW;',
-		'    FxaaFloat lumaSWSE = lumaSW + lumaSE;',
-		'    FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);',
-		'    FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);',
-		'    FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;',
-		'    FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;',
-		'    FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;',
-		'    FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;',
-		'    FxaaFloat lengthSign = fxaaQualityRcpFrame.x;',
-		'    FxaaBool horzSpan = edgeHorz >= edgeVert;',
-		'    FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;',
-		'/*--------------------------------------------------------------------------*/',
-		'    if(!horzSpan) lumaN = lumaW;',
-		'    if(!horzSpan) lumaS = lumaE;',
-		'    if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;',
-		'    FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat gradientN = lumaN - lumaM;',
-		'    FxaaFloat gradientS = lumaS - lumaM;',
-		'    FxaaFloat lumaNN = lumaN + lumaM;',
-		'    FxaaFloat lumaSS = lumaS + lumaM;',
-		'    FxaaBool pairN = abs(gradientN) >= abs(gradientS);',
-		'    FxaaFloat gradient = max(abs(gradientN), abs(gradientS));',
-		'    if(pairN) lengthSign = -lengthSign;',
-		'    FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat2 posB;',
-		'    posB.x = posM.x;',
-		'    posB.y = posM.y;',
-		'    FxaaFloat2 offNP;',
-		'    offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;',
-		'    offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;',
-		'    if(!horzSpan) posB.x += lengthSign * 0.5;',
-		'    if( horzSpan) posB.y += lengthSign * 0.5;',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat2 posN;',
-		'    posN.x = posB.x - offNP.x * FXAA_QUALITY_P0;',
-		'    posN.y = posB.y - offNP.y * FXAA_QUALITY_P0;',
-		'    FxaaFloat2 posP;',
-		'    posP.x = posB.x + offNP.x * FXAA_QUALITY_P0;',
-		'    posP.y = posB.y + offNP.y * FXAA_QUALITY_P0;',
-		'    FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;',
-		'    FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));',
-		'    FxaaFloat subpixE = subpixC * subpixC;',
-		'    FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));',
-		'/*--------------------------------------------------------------------------*/',
-		'    if(!pairN) lumaNN = lumaSS;',
-		'    FxaaFloat gradientScaled = gradient * 1.0/4.0;',
-		'    FxaaFloat lumaMM = lumaM - lumaNN * 0.5;',
-		'    FxaaFloat subpixF = subpixD * subpixE;',
-		'    FxaaBool lumaMLTZero = lumaMM < 0.0;',
-		'/*--------------------------------------------------------------------------*/',
-		'    lumaEndN -= lumaNN * 0.5;',
-		'    lumaEndP -= lumaNN * 0.5;',
-		'    FxaaBool doneN = abs(lumaEndN) >= gradientScaled;',
-		'    FxaaBool doneP = abs(lumaEndP) >= gradientScaled;',
-		'    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;',
-		'    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;',
-		'    FxaaBool doneNP = (!doneN) || (!doneP);',
-		'    if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;',
-		'    if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;',
-		'/*--------------------------------------------------------------------------*/',
-		'    if(doneNP) {',
-		'        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'        doneN = abs(lumaEndN) >= gradientScaled;',
-		'        doneP = abs(lumaEndP) >= gradientScaled;',
-		'        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;',
-		'        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;',
-		'        doneNP = (!doneN) || (!doneP);',
-		'        if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;',
-		'        if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;',
-		'/*--------------------------------------------------------------------------*/',
-		'        #if (FXAA_QUALITY_PS > 3)',
-		'        if(doneNP) {',
-		'            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'            doneN = abs(lumaEndN) >= gradientScaled;',
-		'            doneP = abs(lumaEndP) >= gradientScaled;',
-		'            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;',
-		'            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;',
-		'            doneNP = (!doneN) || (!doneP);',
-		'            if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;',
-		'            if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;',
-		'/*--------------------------------------------------------------------------*/',
-		'            #if (FXAA_QUALITY_PS > 4)',
-		'            if(doneNP) {',
-		'                if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'                if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'                doneN = abs(lumaEndN) >= gradientScaled;',
-		'                doneP = abs(lumaEndP) >= gradientScaled;',
-		'                if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;',
-		'                if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;',
-		'                doneNP = (!doneN) || (!doneP);',
-		'                if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;',
-		'                if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;',
-		'/*--------------------------------------------------------------------------*/',
-		'                #if (FXAA_QUALITY_PS > 5)',
-		'                if(doneNP) {',
-		'                    if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'                    if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'                    doneN = abs(lumaEndN) >= gradientScaled;',
-		'                    doneP = abs(lumaEndP) >= gradientScaled;',
-		'                    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;',
-		'                    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;',
-		'                    doneNP = (!doneN) || (!doneP);',
-		'                    if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;',
-		'                    if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;',
-		'/*--------------------------------------------------------------------------*/',
-		'                    #if (FXAA_QUALITY_PS > 6)',
-		'                    if(doneNP) {',
-		'                        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'                        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'                        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'                        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'                        doneN = abs(lumaEndN) >= gradientScaled;',
-		'                        doneP = abs(lumaEndP) >= gradientScaled;',
-		'                        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;',
-		'                        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;',
-		'                        doneNP = (!doneN) || (!doneP);',
-		'                        if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;',
-		'                        if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;',
-		'/*--------------------------------------------------------------------------*/',
-		'                        #if (FXAA_QUALITY_PS > 7)',
-		'                        if(doneNP) {',
-		'                            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'                            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'                            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'                            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'                            doneN = abs(lumaEndN) >= gradientScaled;',
-		'                            doneP = abs(lumaEndP) >= gradientScaled;',
-		'                            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;',
-		'                            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;',
-		'                            doneNP = (!doneN) || (!doneP);',
-		'                            if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;',
-		'                            if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;',
-		'/*--------------------------------------------------------------------------*/',
-		'    #if (FXAA_QUALITY_PS > 8)',
-		'    if(doneNP) {',
-		'        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'        doneN = abs(lumaEndN) >= gradientScaled;',
-		'        doneP = abs(lumaEndP) >= gradientScaled;',
-		'        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;',
-		'        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;',
-		'        doneNP = (!doneN) || (!doneP);',
-		'        if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;',
-		'        if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;',
-		'/*--------------------------------------------------------------------------*/',
-		'        #if (FXAA_QUALITY_PS > 9)',
-		'        if(doneNP) {',
-		'            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'            doneN = abs(lumaEndN) >= gradientScaled;',
-		'            doneP = abs(lumaEndP) >= gradientScaled;',
-		'            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;',
-		'            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;',
-		'            doneNP = (!doneN) || (!doneP);',
-		'            if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;',
-		'            if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;',
-		'/*--------------------------------------------------------------------------*/',
-		'            #if (FXAA_QUALITY_PS > 10)',
-		'            if(doneNP) {',
-		'                if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'                if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'                doneN = abs(lumaEndN) >= gradientScaled;',
-		'                doneP = abs(lumaEndP) >= gradientScaled;',
-		'                if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;',
-		'                if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;',
-		'                doneNP = (!doneN) || (!doneP);',
-		'                if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;',
-		'                if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;',
-		'/*--------------------------------------------------------------------------*/',
-		'                #if (FXAA_QUALITY_PS > 11)',
-		'                if(doneNP) {',
-		'                    if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'                    if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'                    doneN = abs(lumaEndN) >= gradientScaled;',
-		'                    doneP = abs(lumaEndP) >= gradientScaled;',
-		'                    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;',
-		'                    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;',
-		'                    doneNP = (!doneN) || (!doneP);',
-		'                    if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;',
-		'                    if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;',
-		'/*--------------------------------------------------------------------------*/',
-		'                    #if (FXAA_QUALITY_PS > 12)',
-		'                    if(doneNP) {',
-		'                        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));',
-		'                        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));',
-		'                        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;',
-		'                        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;',
-		'                        doneN = abs(lumaEndN) >= gradientScaled;',
-		'                        doneP = abs(lumaEndP) >= gradientScaled;',
-		'                        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;',
-		'                        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;',
-		'                        doneNP = (!doneN) || (!doneP);',
-		'                        if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;',
-		'                        if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;',
-		'/*--------------------------------------------------------------------------*/',
-		'                    }',
-		'                    #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'                }',
-		'                #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'            }',
-		'            #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'        }',
-		'        #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'    }',
-		'    #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'                        }',
-		'                        #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'                    }',
-		'                    #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'                }',
-		'                #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'            }',
-		'            #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'        }',
-		'        #endif',
-		'/*--------------------------------------------------------------------------*/',
-		'    }',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat dstN = posM.x - posN.x;',
-		'    FxaaFloat dstP = posP.x - posM.x;',
-		'    if(!horzSpan) dstN = posM.y - posN.y;',
-		'    if(!horzSpan) dstP = posP.y - posM.y;',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;',
-		'    FxaaFloat spanLength = (dstP + dstN);',
-		'    FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;',
-		'    FxaaFloat spanLengthRcp = 1.0/spanLength;',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaBool directionN = dstN < dstP;',
-		'    FxaaFloat dst = min(dstN, dstP);',
-		'    FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;',
-		'    FxaaFloat subpixG = subpixF * subpixF;',
-		'    FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;',
-		'    FxaaFloat subpixH = subpixG * fxaaQualitySubpix;',
-		'/*--------------------------------------------------------------------------*/',
-		'    FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;',
-		'    FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);',
-		'    if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;',
-		'    if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;',
-		'    #if (FXAA_DISCARD == 1)',
-		'        return FxaaTexTop(tex, posM);',
-		'    #else',
-		'        return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);',
-		'    #endif',
-		'}',
-		'/*==========================================================================*/',
-		'#endif',
-		'',
-		'void main() {',
-		'  gl_FragColor = FxaaPixelShader(',
-		'    vUv,',
-		'    vec4(0.0),',
-		'    tDiffuse,',
-		'    tDiffuse,',
-		'    tDiffuse,',
-		'    resolution,',
-		'    vec4(0.0),',
-		'    vec4(0.0),',
-		'    vec4(0.0),',
-		'    0.75,',
-		'    0.166,',
-		'    0.0833,',
-		'    0.0,',
-		'    0.0,',
-		'    0.0,',
-		'    vec4(0.0)',
-		'  );',
-		'',
-		'  // TODO avoid querying texture twice for same texel',
-		'  gl_FragColor.a = texture2D(tDiffuse, vUv).a;',
-		'}'
-	].join( '\n' )
+	// FXAA 3.11 implementation by NVIDIA, ported to WebGL by Agost Biro ([email protected])
+
+	//----------------------------------------------------------------------------------
+	// File:				es3-kepler\FXAA\assets\shaders/FXAA_DefaultES.frag
+	// SDK Version: v3.00
+	// Email:			 [email protected]
+	// Site:				http://developer.nvidia.com/
+	//
+	// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
+	//
+	// Redistribution and use in source and binary forms, with or without
+	// modification, are permitted provided that the following conditions
+	// are met:
+	//	* Redistributions of source code must retain the above copyright
+	//		notice, this list of conditions and the following disclaimer.
+	//	* Redistributions in binary form must reproduce the above copyright
+	//		notice, this list of conditions and the following disclaimer in the
+	//		documentation and/or other materials provided with the distribution.
+	//	* Neither the name of NVIDIA CORPORATION nor the names of its
+	//		contributors may be used to endorse or promote products derived
+	//		from this software without specific prior written permission.
+	//
+	// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS\'\' AND ANY
+	// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+	// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+	// PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+	// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+	// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+	// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+	// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+	// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+	// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+	//
+	//----------------------------------------------------------------------------------
+
+		`precision highp float;
+
+		uniform sampler2D tDiffuse;
+
+		uniform vec2 resolution;
+
+		varying vec2 vUv;
+
+		#define FXAA_PC 1
+		#define FXAA_GLSL_100 1
+		#define FXAA_QUALITY_PRESET 12
+
+		#define FXAA_GREEN_AS_LUMA 1
+
+		/*--------------------------------------------------------------------------*/
+		#ifndef FXAA_PC_CONSOLE
+				//
+				// The console algorithm for PC is included
+				// for developers targeting really low spec machines.
+				// Likely better to just run FXAA_PC, and use a really low preset.
+				//
+				#define FXAA_PC_CONSOLE 0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#ifndef FXAA_GLSL_120
+				#define FXAA_GLSL_120 0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#ifndef FXAA_GLSL_130
+				#define FXAA_GLSL_130 0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#ifndef FXAA_HLSL_3
+				#define FXAA_HLSL_3 0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#ifndef FXAA_HLSL_4
+				#define FXAA_HLSL_4 0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#ifndef FXAA_HLSL_5
+				#define FXAA_HLSL_5 0
+		#endif
+		/*==========================================================================*/
+		#ifndef FXAA_GREEN_AS_LUMA
+				//
+				// For those using non-linear color,
+				// and either not able to get luma in alpha, or not wanting to,
+				// this enables FXAA to run using green as a proxy for luma.
+				// So with this enabled, no need to pack luma in alpha.
+				//
+				// This will turn off AA on anything which lacks some amount of green.
+				// Pure red and blue or combination of only R and B, will get no AA.
+				//
+				// Might want to lower the settings for both,
+				//		fxaaConsoleEdgeThresholdMin
+				//		fxaaQualityEdgeThresholdMin
+				// In order to insure AA does not get turned off on colors
+				// which contain a minor amount of green.
+				//
+				// 1 = On.
+				// 0 = Off.
+				//
+				#define FXAA_GREEN_AS_LUMA 0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#ifndef FXAA_EARLY_EXIT
+				//
+				// Controls algorithm\'s early exit path.
+				// On PS3 turning this ON adds 2 cycles to the shader.
+				// On 360 turning this OFF adds 10ths of a millisecond to the shader.
+				// Turning this off on console will result in a more blurry image.
+				// So this defaults to on.
+				//
+				// 1 = On.
+				// 0 = Off.
+				//
+				#define FXAA_EARLY_EXIT 1
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#ifndef FXAA_DISCARD
+				//
+				// Only valid for PC OpenGL currently.
+				// Probably will not work when FXAA_GREEN_AS_LUMA = 1.
+				//
+				// 1 = Use discard on pixels which don\'t need AA.
+				//		 For APIs which enable concurrent TEX+ROP from same surface.
+				// 0 = Return unchanged color on pixels which don\'t need AA.
+				//
+				#define FXAA_DISCARD 0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#ifndef FXAA_FAST_PIXEL_OFFSET
+				//
+				// Used for GLSL 120 only.
+				//
+				// 1 = GL API supports fast pixel offsets
+				// 0 = do not use fast pixel offsets
+				//
+				#ifdef GL_EXT_gpu_shader4
+						#define FXAA_FAST_PIXEL_OFFSET 1
+				#endif
+				#ifdef GL_NV_gpu_shader5
+						#define FXAA_FAST_PIXEL_OFFSET 1
+				#endif
+				#ifdef GL_ARB_gpu_shader5
+						#define FXAA_FAST_PIXEL_OFFSET 1
+				#endif
+				#ifndef FXAA_FAST_PIXEL_OFFSET
+						#define FXAA_FAST_PIXEL_OFFSET 0
+				#endif
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#ifndef FXAA_GATHER4_ALPHA
+				//
+				// 1 = API supports gather4 on alpha channel.
+				// 0 = API does not support gather4 on alpha channel.
+				//
+				#if (FXAA_HLSL_5 == 1)
+						#define FXAA_GATHER4_ALPHA 1
+				#endif
+				#ifdef GL_ARB_gpu_shader5
+						#define FXAA_GATHER4_ALPHA 1
+				#endif
+				#ifdef GL_NV_gpu_shader5
+						#define FXAA_GATHER4_ALPHA 1
+				#endif
+				#ifndef FXAA_GATHER4_ALPHA
+						#define FXAA_GATHER4_ALPHA 0
+				#endif
+		#endif
+
+
+		/*============================================================================
+														FXAA QUALITY - TUNING KNOBS
+		------------------------------------------------------------------------------
+		NOTE the other tuning knobs are now in the shader function inputs!
+		============================================================================*/
+		#ifndef FXAA_QUALITY_PRESET
+				//
+				// Choose the quality preset.
+				// This needs to be compiled into the shader as it effects code.
+				// Best option to include multiple presets is to
+				// in each shader define the preset, then include this file.
+				//
+				// OPTIONS
+				// -----------------------------------------------------------------------
+				// 10 to 15 - default medium dither (10=fastest, 15=highest quality)
+				// 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)
+				// 39			 - no dither, very expensive
+				//
+				// NOTES
+				// -----------------------------------------------------------------------
+				// 12 = slightly faster then FXAA 3.9 and higher edge quality (default)
+				// 13 = about same speed as FXAA 3.9 and better than 12
+				// 23 = closest to FXAA 3.9 visually and performance wise
+				//	_ = the lowest digit is directly related to performance
+				// _	= the highest digit is directly related to style
+				//
+				#define FXAA_QUALITY_PRESET 12
+		#endif
+
+
+		/*============================================================================
+
+															 FXAA QUALITY - PRESETS
+
+		============================================================================*/
+
+		/*============================================================================
+												 FXAA QUALITY - MEDIUM DITHER PRESETS
+		============================================================================*/
+		#if (FXAA_QUALITY_PRESET == 10)
+				#define FXAA_QUALITY_PS 3
+				#define FXAA_QUALITY_P0 1.5
+				#define FXAA_QUALITY_P1 3.0
+				#define FXAA_QUALITY_P2 12.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 11)
+				#define FXAA_QUALITY_PS 4
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 3.0
+				#define FXAA_QUALITY_P3 12.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 12)
+				#define FXAA_QUALITY_PS 5
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 4.0
+				#define FXAA_QUALITY_P4 12.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 13)
+				#define FXAA_QUALITY_PS 6
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 4.0
+				#define FXAA_QUALITY_P5 12.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 14)
+				#define FXAA_QUALITY_PS 7
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 2.0
+				#define FXAA_QUALITY_P5 4.0
+				#define FXAA_QUALITY_P6 12.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 15)
+				#define FXAA_QUALITY_PS 8
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 2.0
+				#define FXAA_QUALITY_P5 2.0
+				#define FXAA_QUALITY_P6 4.0
+				#define FXAA_QUALITY_P7 12.0
+		#endif
+
+		/*============================================================================
+												 FXAA QUALITY - LOW DITHER PRESETS
+		============================================================================*/
+		#if (FXAA_QUALITY_PRESET == 20)
+				#define FXAA_QUALITY_PS 3
+				#define FXAA_QUALITY_P0 1.5
+				#define FXAA_QUALITY_P1 2.0
+				#define FXAA_QUALITY_P2 8.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 21)
+				#define FXAA_QUALITY_PS 4
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 8.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 22)
+				#define FXAA_QUALITY_PS 5
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 8.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 23)
+				#define FXAA_QUALITY_PS 6
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 2.0
+				#define FXAA_QUALITY_P5 8.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 24)
+				#define FXAA_QUALITY_PS 7
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 2.0
+				#define FXAA_QUALITY_P5 3.0
+				#define FXAA_QUALITY_P6 8.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 25)
+				#define FXAA_QUALITY_PS 8
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 2.0
+				#define FXAA_QUALITY_P5 2.0
+				#define FXAA_QUALITY_P6 4.0
+				#define FXAA_QUALITY_P7 8.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 26)
+				#define FXAA_QUALITY_PS 9
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 2.0
+				#define FXAA_QUALITY_P5 2.0
+				#define FXAA_QUALITY_P6 2.0
+				#define FXAA_QUALITY_P7 4.0
+				#define FXAA_QUALITY_P8 8.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 27)
+				#define FXAA_QUALITY_PS 10
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 2.0
+				#define FXAA_QUALITY_P5 2.0
+				#define FXAA_QUALITY_P6 2.0
+				#define FXAA_QUALITY_P7 2.0
+				#define FXAA_QUALITY_P8 4.0
+				#define FXAA_QUALITY_P9 8.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 28)
+				#define FXAA_QUALITY_PS 11
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 2.0
+				#define FXAA_QUALITY_P5 2.0
+				#define FXAA_QUALITY_P6 2.0
+				#define FXAA_QUALITY_P7 2.0
+				#define FXAA_QUALITY_P8 2.0
+				#define FXAA_QUALITY_P9 4.0
+				#define FXAA_QUALITY_P10 8.0
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_QUALITY_PRESET == 29)
+				#define FXAA_QUALITY_PS 12
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.5
+				#define FXAA_QUALITY_P2 2.0
+				#define FXAA_QUALITY_P3 2.0
+				#define FXAA_QUALITY_P4 2.0
+				#define FXAA_QUALITY_P5 2.0
+				#define FXAA_QUALITY_P6 2.0
+				#define FXAA_QUALITY_P7 2.0
+				#define FXAA_QUALITY_P8 2.0
+				#define FXAA_QUALITY_P9 2.0
+				#define FXAA_QUALITY_P10 4.0
+				#define FXAA_QUALITY_P11 8.0
+		#endif
+
+		/*============================================================================
+												 FXAA QUALITY - EXTREME QUALITY
+		============================================================================*/
+		#if (FXAA_QUALITY_PRESET == 39)
+				#define FXAA_QUALITY_PS 12
+				#define FXAA_QUALITY_P0 1.0
+				#define FXAA_QUALITY_P1 1.0
+				#define FXAA_QUALITY_P2 1.0
+				#define FXAA_QUALITY_P3 1.0
+				#define FXAA_QUALITY_P4 1.0
+				#define FXAA_QUALITY_P5 1.5
+				#define FXAA_QUALITY_P6 2.0
+				#define FXAA_QUALITY_P7 2.0
+				#define FXAA_QUALITY_P8 2.0
+				#define FXAA_QUALITY_P9 2.0
+				#define FXAA_QUALITY_P10 4.0
+				#define FXAA_QUALITY_P11 8.0
+		#endif
+
+
+
+		/*============================================================================
+
+																		API PORTING
+
+		============================================================================*/
+		#if (FXAA_GLSL_100 == 1) || (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)
+				#define FxaaBool bool
+				#define FxaaDiscard discard
+				#define FxaaFloat float
+				#define FxaaFloat2 vec2
+				#define FxaaFloat3 vec3
+				#define FxaaFloat4 vec4
+				#define FxaaHalf float
+				#define FxaaHalf2 vec2
+				#define FxaaHalf3 vec3
+				#define FxaaHalf4 vec4
+				#define FxaaInt2 ivec2
+				#define FxaaSat(x) clamp(x, 0.0, 1.0)
+				#define FxaaTex sampler2D
+		#else
+				#define FxaaBool bool
+				#define FxaaDiscard clip(-1)
+				#define FxaaFloat float
+				#define FxaaFloat2 float2
+				#define FxaaFloat3 float3
+				#define FxaaFloat4 float4
+				#define FxaaHalf half
+				#define FxaaHalf2 half2
+				#define FxaaHalf3 half3
+				#define FxaaHalf4 half4
+				#define FxaaSat(x) saturate(x)
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_GLSL_100 == 1)
+			#define FxaaTexTop(t, p) texture2D(t, p, 0.0)
+			#define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r), 0.0)
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_GLSL_120 == 1)
+				// Requires,
+				//	#version 120
+				// And at least,
+				//	#extension GL_EXT_gpu_shader4 : enable
+				//	(or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)
+				#define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)
+				#if (FXAA_FAST_PIXEL_OFFSET == 1)
+						#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
+				#else
+						#define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)
+				#endif
+				#if (FXAA_GATHER4_ALPHA == 1)
+						// use #extension GL_ARB_gpu_shader5 : enable
+						#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
+						#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
+						#define FxaaTexGreen4(t, p) textureGather(t, p, 1)
+						#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
+				#endif
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_GLSL_130 == 1)
+				// Requires "#version 130" or better
+				#define FxaaTexTop(t, p) textureLod(t, p, 0.0)
+				#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
+				#if (FXAA_GATHER4_ALPHA == 1)
+						// use #extension GL_ARB_gpu_shader5 : enable
+						#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
+						#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
+						#define FxaaTexGreen4(t, p) textureGather(t, p, 1)
+						#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
+				#endif
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_HLSL_3 == 1)
+				#define FxaaInt2 float2
+				#define FxaaTex sampler2D
+				#define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
+				#define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_HLSL_4 == 1)
+				#define FxaaInt2 int2
+				struct FxaaTex { SamplerState smpl; Texture2D tex; };
+				#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
+				#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
+		#endif
+		/*--------------------------------------------------------------------------*/
+		#if (FXAA_HLSL_5 == 1)
+				#define FxaaInt2 int2
+				struct FxaaTex { SamplerState smpl; Texture2D tex; };
+				#define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
+				#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
+				#define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)
+				#define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)
+				#define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)
+				#define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)
+		#endif
+
+
+		/*============================================================================
+											 GREEN AS LUMA OPTION SUPPORT FUNCTION
+		============================================================================*/
+		#if (FXAA_GREEN_AS_LUMA == 0)
+				FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }
+		#else
+				FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }
+		#endif
+
+
+
+
+		/*============================================================================
+
+																 FXAA3 QUALITY - PC
+
+		============================================================================*/
+		#if (FXAA_PC == 1)
+		/*--------------------------------------------------------------------------*/
+		FxaaFloat4 FxaaPixelShader(
+				//
+				// Use noperspective interpolation here (turn off perspective interpolation).
+				// {xy} = center of pixel
+				FxaaFloat2 pos,
+				//
+				// Used only for FXAA Console, and not used on the 360 version.
+				// Use noperspective interpolation here (turn off perspective interpolation).
+				// {xy_} = upper left of pixel
+				// {_zw} = lower right of pixel
+				FxaaFloat4 fxaaConsolePosPos,
+				//
+				// Input color texture.
+				// {rgb_} = color in linear or perceptual color space
+				// if (FXAA_GREEN_AS_LUMA == 0)
+				//		 {__a} = luma in perceptual color space (not linear)
+				FxaaTex tex,
+				//
+				// Only used on the optimized 360 version of FXAA Console.
+				// For everything but 360, just use the same input here as for "tex".
+				// For 360, same texture, just alias with a 2nd sampler.
+				// This sampler needs to have an exponent bias of -1.
+				FxaaTex fxaaConsole360TexExpBiasNegOne,
+				//
+				// Only used on the optimized 360 version of FXAA Console.
+				// For everything but 360, just use the same input here as for "tex".
+				// For 360, same texture, just alias with a 3nd sampler.
+				// This sampler needs to have an exponent bias of -2.
+				FxaaTex fxaaConsole360TexExpBiasNegTwo,
+				//
+				// Only used on FXAA Quality.
+				// This must be from a constant/uniform.
+				// {x_} = 1.0/screenWidthInPixels
+				// {_y} = 1.0/screenHeightInPixels
+				FxaaFloat2 fxaaQualityRcpFrame,
+				//
+				// Only used on FXAA Console.
+				// This must be from a constant/uniform.
+				// This effects sub-pixel AA quality and inversely sharpness.
+				//	 Where N ranges between,
+				//		 N = 0.50 (default)
+				//		 N = 0.33 (sharper)
+				// {x__} = -N/screenWidthInPixels
+				// {_y_} = -N/screenHeightInPixels
+				// {_z_} =	N/screenWidthInPixels
+				// {__w} =	N/screenHeightInPixels
+				FxaaFloat4 fxaaConsoleRcpFrameOpt,
+				//
+				// Only used on FXAA Console.
+				// Not used on 360, but used on PS3 and PC.
+				// This must be from a constant/uniform.
+				// {x__} = -2.0/screenWidthInPixels
+				// {_y_} = -2.0/screenHeightInPixels
+				// {_z_} =	2.0/screenWidthInPixels
+				// {__w} =	2.0/screenHeightInPixels
+				FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+				//
+				// Only used on FXAA Console.
+				// Only used on 360 in place of fxaaConsoleRcpFrameOpt2.
+				// This must be from a constant/uniform.
+				// {x__} =	8.0/screenWidthInPixels
+				// {_y_} =	8.0/screenHeightInPixels
+				// {_z_} = -4.0/screenWidthInPixels
+				// {__w} = -4.0/screenHeightInPixels
+				FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+				//
+				// Only used on FXAA Quality.
+				// This used to be the FXAA_QUALITY_SUBPIX define.
+				// It is here now to allow easier tuning.
+				// Choose the amount of sub-pixel aliasing removal.
+				// This can effect sharpness.
+				//	 1.00 - upper limit (softer)
+				//	 0.75 - default amount of filtering
+				//	 0.50 - lower limit (sharper, less sub-pixel aliasing removal)
+				//	 0.25 - almost off
+				//	 0.00 - completely off
+				FxaaFloat fxaaQualitySubpix,
+				//
+				// Only used on FXAA Quality.
+				// This used to be the FXAA_QUALITY_EDGE_THRESHOLD define.
+				// It is here now to allow easier tuning.
+				// The minimum amount of local contrast required to apply algorithm.
+				//	 0.333 - too little (faster)
+				//	 0.250 - low quality
+				//	 0.166 - default
+				//	 0.125 - high quality
+				//	 0.063 - overkill (slower)
+				FxaaFloat fxaaQualityEdgeThreshold,
+				//
+				// Only used on FXAA Quality.
+				// This used to be the FXAA_QUALITY_EDGE_THRESHOLD_MIN define.
+				// It is here now to allow easier tuning.
+				// Trims the algorithm from processing darks.
+				//	 0.0833 - upper limit (default, the start of visible unfiltered edges)
+				//	 0.0625 - high quality (faster)
+				//	 0.0312 - visible limit (slower)
+				// Special notes when using FXAA_GREEN_AS_LUMA,
+				//	 Likely want to set this to zero.
+				//	 As colors that are mostly not-green
+				//	 will appear very dark in the green channel!
+				//	 Tune by looking at mostly non-green content,
+				//	 then start at zero and increase until aliasing is a problem.
+				FxaaFloat fxaaQualityEdgeThresholdMin,
+				//
+				// Only used on FXAA Console.
+				// This used to be the FXAA_CONSOLE_EDGE_SHARPNESS define.
+				// It is here now to allow easier tuning.
+				// This does not effect PS3, as this needs to be compiled in.
+				//	 Use FXAA_CONSOLE_PS3_EDGE_SHARPNESS for PS3.
+				//	 Due to the PS3 being ALU bound,
+				//	 there are only three safe values here: 2 and 4 and 8.
+				//	 These options use the shaders ability to a free *|/ by 2|4|8.
+				// For all other platforms can be a non-power of two.
+				//	 8.0 is sharper (default!!!)
+				//	 4.0 is softer
+				//	 2.0 is really soft (good only for vector graphics inputs)
+				FxaaFloat fxaaConsoleEdgeSharpness,
+				//
+				// Only used on FXAA Console.
+				// This used to be the FXAA_CONSOLE_EDGE_THRESHOLD define.
+				// It is here now to allow easier tuning.
+				// This does not effect PS3, as this needs to be compiled in.
+				//	 Use FXAA_CONSOLE_PS3_EDGE_THRESHOLD for PS3.
+				//	 Due to the PS3 being ALU bound,
+				//	 there are only two safe values here: 1/4 and 1/8.
+				//	 These options use the shaders ability to a free *|/ by 2|4|8.
+				// The console setting has a different mapping than the quality setting.
+				// Other platforms can use other values.
+				//	 0.125 leaves less aliasing, but is softer (default!!!)
+				//	 0.25 leaves more aliasing, and is sharper
+				FxaaFloat fxaaConsoleEdgeThreshold,
+				//
+				// Only used on FXAA Console.
+				// This used to be the FXAA_CONSOLE_EDGE_THRESHOLD_MIN define.
+				// It is here now to allow easier tuning.
+				// Trims the algorithm from processing darks.
+				// The console setting has a different mapping than the quality setting.
+				// This only applies when FXAA_EARLY_EXIT is 1.
+				// This does not apply to PS3,
+				// PS3 was simplified to avoid more shader instructions.
+				//	 0.06 - faster but more aliasing in darks
+				//	 0.05 - default
+				//	 0.04 - slower and less aliasing in darks
+				// Special notes when using FXAA_GREEN_AS_LUMA,
+				//	 Likely want to set this to zero.
+				//	 As colors that are mostly not-green
+				//	 will appear very dark in the green channel!
+				//	 Tune by looking at mostly non-green content,
+				//	 then start at zero and increase until aliasing is a problem.
+				FxaaFloat fxaaConsoleEdgeThresholdMin,
+				//
+				// Extra constants for 360 FXAA Console only.
+				// Use zeros or anything else for other platforms.
+				// These must be in physical constant registers and NOT immediates.
+				// Immediates will result in compiler un-optimizing.
+				// {xyzw} = float4(1.0, -1.0, 0.25, -0.25)
+				FxaaFloat4 fxaaConsole360ConstDir
+		) {
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat2 posM;
+				posM.x = pos.x;
+				posM.y = pos.y;
+				#if (FXAA_GATHER4_ALPHA == 1)
+						#if (FXAA_DISCARD == 0)
+								FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
+								#if (FXAA_GREEN_AS_LUMA == 0)
+										#define lumaM rgbyM.w
+								#else
+										#define lumaM rgbyM.y
+								#endif
+						#endif
+						#if (FXAA_GREEN_AS_LUMA == 0)
+								FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);
+								FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));
+						#else
+								FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);
+								FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));
+						#endif
+						#if (FXAA_DISCARD == 1)
+								#define lumaM luma4A.w
+						#endif
+						#define lumaE luma4A.z
+						#define lumaS luma4A.x
+						#define lumaSE luma4A.y
+						#define lumaNW luma4B.w
+						#define lumaN luma4B.z
+						#define lumaW luma4B.x
+				#else
+						FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
+						#if (FXAA_GREEN_AS_LUMA == 0)
+								#define lumaM rgbyM.w
+						#else
+								#define lumaM rgbyM.y
+						#endif
+						#if (FXAA_GLSL_100 == 1)
+							FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 0.0, 1.0), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0, 0.0), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 0.0,-1.0), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0, 0.0), fxaaQualityRcpFrame.xy));
+						#else
+							FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));
+						#endif
+				#endif
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat maxSM = max(lumaS, lumaM);
+				FxaaFloat minSM = min(lumaS, lumaM);
+				FxaaFloat maxESM = max(lumaE, maxSM);
+				FxaaFloat minESM = min(lumaE, minSM);
+				FxaaFloat maxWN = max(lumaN, lumaW);
+				FxaaFloat minWN = min(lumaN, lumaW);
+				FxaaFloat rangeMax = max(maxWN, maxESM);
+				FxaaFloat rangeMin = min(minWN, minESM);
+				FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
+				FxaaFloat range = rangeMax - rangeMin;
+				FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
+				FxaaBool earlyExit = range < rangeMaxClamped;
+		/*--------------------------------------------------------------------------*/
+				if(earlyExit)
+						#if (FXAA_DISCARD == 1)
+								FxaaDiscard;
+						#else
+								return rgbyM;
+						#endif
+		/*--------------------------------------------------------------------------*/
+				#if (FXAA_GATHER4_ALPHA == 0)
+						#if (FXAA_GLSL_100 == 1)
+							FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0,-1.0), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0, 1.0), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0,-1.0), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0, 1.0), fxaaQualityRcpFrame.xy));
+						#else
+							FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));
+							FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
+						#endif
+				#else
+						FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));
+						FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
+				#endif
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat lumaNS = lumaN + lumaS;
+				FxaaFloat lumaWE = lumaW + lumaE;
+				FxaaFloat subpixRcpRange = 1.0/range;
+				FxaaFloat subpixNSWE = lumaNS + lumaWE;
+				FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;
+				FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat lumaNESE = lumaNE + lumaSE;
+				FxaaFloat lumaNWNE = lumaNW + lumaNE;
+				FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
+				FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat lumaNWSW = lumaNW + lumaSW;
+				FxaaFloat lumaSWSE = lumaSW + lumaSE;
+				FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
+				FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
+				FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
+				FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
+				FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;
+				FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;
+				FxaaFloat lengthSign = fxaaQualityRcpFrame.x;
+				FxaaBool horzSpan = edgeHorz >= edgeVert;
+				FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
+		/*--------------------------------------------------------------------------*/
+				if(!horzSpan) lumaN = lumaW;
+				if(!horzSpan) lumaS = lumaE;
+				if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;
+				FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat gradientN = lumaN - lumaM;
+				FxaaFloat gradientS = lumaS - lumaM;
+				FxaaFloat lumaNN = lumaN + lumaM;
+				FxaaFloat lumaSS = lumaS + lumaM;
+				FxaaBool pairN = abs(gradientN) >= abs(gradientS);
+				FxaaFloat gradient = max(abs(gradientN), abs(gradientS));
+				if(pairN) lengthSign = -lengthSign;
+				FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat2 posB;
+				posB.x = posM.x;
+				posB.y = posM.y;
+				FxaaFloat2 offNP;
+				offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
+				offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
+				if(!horzSpan) posB.x += lengthSign * 0.5;
+				if( horzSpan) posB.y += lengthSign * 0.5;
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat2 posN;
+				posN.x = posB.x - offNP.x * FXAA_QUALITY_P0;
+				posN.y = posB.y - offNP.y * FXAA_QUALITY_P0;
+				FxaaFloat2 posP;
+				posP.x = posB.x + offNP.x * FXAA_QUALITY_P0;
+				posP.y = posB.y + offNP.y * FXAA_QUALITY_P0;
+				FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;
+				FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
+				FxaaFloat subpixE = subpixC * subpixC;
+				FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
+		/*--------------------------------------------------------------------------*/
+				if(!pairN) lumaNN = lumaSS;
+				FxaaFloat gradientScaled = gradient * 1.0/4.0;
+				FxaaFloat lumaMM = lumaM - lumaNN * 0.5;
+				FxaaFloat subpixF = subpixD * subpixE;
+				FxaaBool lumaMLTZero = lumaMM < 0.0;
+		/*--------------------------------------------------------------------------*/
+				lumaEndN -= lumaNN * 0.5;
+				lumaEndP -= lumaNN * 0.5;
+				FxaaBool doneN = abs(lumaEndN) >= gradientScaled;
+				FxaaBool doneP = abs(lumaEndP) >= gradientScaled;
+				if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;
+				if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;
+				FxaaBool doneNP = (!doneN) || (!doneP);
+				if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;
+				if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;
+		/*--------------------------------------------------------------------------*/
+				if(doneNP) {
+						if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+						if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+						if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+						if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+						doneN = abs(lumaEndN) >= gradientScaled;
+						doneP = abs(lumaEndP) >= gradientScaled;
+						if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;
+						if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;
+						doneNP = (!doneN) || (!doneP);
+						if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;
+						if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;
+		/*--------------------------------------------------------------------------*/
+						#if (FXAA_QUALITY_PS > 3)
+						if(doneNP) {
+								if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+								if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+								if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+								if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+								doneN = abs(lumaEndN) >= gradientScaled;
+								doneP = abs(lumaEndP) >= gradientScaled;
+								if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;
+								if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;
+								doneNP = (!doneN) || (!doneP);
+								if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;
+								if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;
+		/*--------------------------------------------------------------------------*/
+								#if (FXAA_QUALITY_PS > 4)
+								if(doneNP) {
+										if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+										if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+										if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+										if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+										doneN = abs(lumaEndN) >= gradientScaled;
+										doneP = abs(lumaEndP) >= gradientScaled;
+										if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;
+										if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;
+										doneNP = (!doneN) || (!doneP);
+										if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;
+										if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;
+		/*--------------------------------------------------------------------------*/
+										#if (FXAA_QUALITY_PS > 5)
+										if(doneNP) {
+												if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+												if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+												if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+												if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+												doneN = abs(lumaEndN) >= gradientScaled;
+												doneP = abs(lumaEndP) >= gradientScaled;
+												if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;
+												if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;
+												doneNP = (!doneN) || (!doneP);
+												if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;
+												if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;
+		/*--------------------------------------------------------------------------*/
+												#if (FXAA_QUALITY_PS > 6)
+												if(doneNP) {
+														if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+														if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+														if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+														if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+														doneN = abs(lumaEndN) >= gradientScaled;
+														doneP = abs(lumaEndP) >= gradientScaled;
+														if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;
+														if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;
+														doneNP = (!doneN) || (!doneP);
+														if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;
+														if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;
+		/*--------------------------------------------------------------------------*/
+														#if (FXAA_QUALITY_PS > 7)
+														if(doneNP) {
+																if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+																if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+																if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+																if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+																doneN = abs(lumaEndN) >= gradientScaled;
+																doneP = abs(lumaEndP) >= gradientScaled;
+																if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;
+																if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;
+																doneNP = (!doneN) || (!doneP);
+																if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;
+																if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;
+		/*--------------------------------------------------------------------------*/
+				#if (FXAA_QUALITY_PS > 8)
+				if(doneNP) {
+						if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+						if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+						if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+						if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+						doneN = abs(lumaEndN) >= gradientScaled;
+						doneP = abs(lumaEndP) >= gradientScaled;
+						if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;
+						if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;
+						doneNP = (!doneN) || (!doneP);
+						if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;
+						if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;
+		/*--------------------------------------------------------------------------*/
+						#if (FXAA_QUALITY_PS > 9)
+						if(doneNP) {
+								if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+								if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+								if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+								if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+								doneN = abs(lumaEndN) >= gradientScaled;
+								doneP = abs(lumaEndP) >= gradientScaled;
+								if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;
+								if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;
+								doneNP = (!doneN) || (!doneP);
+								if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;
+								if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;
+		/*--------------------------------------------------------------------------*/
+								#if (FXAA_QUALITY_PS > 10)
+								if(doneNP) {
+										if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+										if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+										if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+										if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+										doneN = abs(lumaEndN) >= gradientScaled;
+										doneP = abs(lumaEndP) >= gradientScaled;
+										if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;
+										if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;
+										doneNP = (!doneN) || (!doneP);
+										if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;
+										if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;
+		/*--------------------------------------------------------------------------*/
+										#if (FXAA_QUALITY_PS > 11)
+										if(doneNP) {
+												if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+												if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+												if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+												if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+												doneN = abs(lumaEndN) >= gradientScaled;
+												doneP = abs(lumaEndP) >= gradientScaled;
+												if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;
+												if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;
+												doneNP = (!doneN) || (!doneP);
+												if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;
+												if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;
+		/*--------------------------------------------------------------------------*/
+												#if (FXAA_QUALITY_PS > 12)
+												if(doneNP) {
+														if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+														if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+														if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+														if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+														doneN = abs(lumaEndN) >= gradientScaled;
+														doneP = abs(lumaEndP) >= gradientScaled;
+														if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;
+														if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;
+														doneNP = (!doneN) || (!doneP);
+														if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;
+														if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;
+		/*--------------------------------------------------------------------------*/
+												}
+												#endif
+		/*--------------------------------------------------------------------------*/
+										}
+										#endif
+		/*--------------------------------------------------------------------------*/
+								}
+								#endif
+		/*--------------------------------------------------------------------------*/
+						}
+						#endif
+		/*--------------------------------------------------------------------------*/
+				}
+				#endif
+		/*--------------------------------------------------------------------------*/
+														}
+														#endif
+		/*--------------------------------------------------------------------------*/
+												}
+												#endif
+		/*--------------------------------------------------------------------------*/
+										}
+										#endif
+		/*--------------------------------------------------------------------------*/
+								}
+								#endif
+		/*--------------------------------------------------------------------------*/
+						}
+						#endif
+		/*--------------------------------------------------------------------------*/
+				}
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat dstN = posM.x - posN.x;
+				FxaaFloat dstP = posP.x - posM.x;
+				if(!horzSpan) dstN = posM.y - posN.y;
+				if(!horzSpan) dstP = posP.y - posM.y;
+		/*--------------------------------------------------------------------------*/
+				FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
+				FxaaFloat spanLength = (dstP + dstN);
+				FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
+				FxaaFloat spanLengthRcp = 1.0/spanLength;
+		/*--------------------------------------------------------------------------*/
+				FxaaBool directionN = dstN < dstP;
+				FxaaFloat dst = min(dstN, dstP);
+				FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;
+				FxaaFloat subpixG = subpixF * subpixF;
+				FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
+				FxaaFloat subpixH = subpixG * fxaaQualitySubpix;
+		/*--------------------------------------------------------------------------*/
+				FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
+				FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
+				if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
+				if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
+				#if (FXAA_DISCARD == 1)
+						return FxaaTexTop(tex, posM);
+				#else
+						return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);
+				#endif
+		}
+		/*==========================================================================*/
+		#endif
+
+		void main() {
+			gl_FragColor = FxaaPixelShader(
+				vUv,
+				vec4(0.0),
+				tDiffuse,
+				tDiffuse,
+				tDiffuse,
+				resolution,
+				vec4(0.0),
+				vec4(0.0),
+				vec4(0.0),
+				0.75,
+				0.166,
+				0.0833,
+				0.0,
+				0.0,
+				0.0,
+				vec4(0.0)
+			);
+
+			// TODO avoid querying texture twice for same texel
+			gl_FragColor.a = texture2D(tDiffuse, vUv).a;
+		}`
 
 
 };
 };
 
 

+ 28 - 32
examples/jsm/shaders/FilmShader.js

@@ -18,7 +18,7 @@
  * http://creativecommons.org/licenses/by/3.0/
  * http://creativecommons.org/licenses/by/3.0/
  */
  */
 
 
-var FilmShader = {
+const FilmShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -31,73 +31,69 @@ var FilmShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
-
-		'#include <common>',
+		`#include <common>
 
 
 		// control parameter
 		// control parameter
-		'uniform float time;',
+		uniform float time;
 
 
-		'uniform bool grayscale;',
+		uniform bool grayscale;
 
 
 		// noise effect intensity value (0 = no effect, 1 = full effect)
 		// noise effect intensity value (0 = no effect, 1 = full effect)
-		'uniform float nIntensity;',
+		uniform float nIntensity;
 
 
 		// scanlines effect intensity value (0 = no effect, 1 = full effect)
 		// scanlines effect intensity value (0 = no effect, 1 = full effect)
-		'uniform float sIntensity;',
+		uniform float sIntensity;
 
 
 		// scanlines effect count value (0 = no effect, 4096 = full effect)
 		// scanlines effect count value (0 = no effect, 4096 = full effect)
-		'uniform float sCount;',
+		uniform float sCount;
 
 
-		'uniform sampler2D tDiffuse;',
+		uniform sampler2D tDiffuse;
 
 
-		'varying vec2 vUv;',
+		varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
 		// sample the source
 		// sample the source
-		'	vec4 cTextureScreen = texture2D( tDiffuse, vUv );',
+			vec4 cTextureScreen = texture2D( tDiffuse, vUv );
 
 
 		// make some noise
 		// make some noise
-		'	float dx = rand( vUv + time );',
+			float dx = rand( vUv + time );
 
 
 		// add noise
 		// add noise
-		'	vec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx, 0.0, 1.0 );',
+			vec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx, 0.0, 1.0 );
 
 
 		// get us a sine and cosine
 		// get us a sine and cosine
-		'	vec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );',
+			vec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );
 
 
 		// add scanlines
 		// add scanlines
-		'	cResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;',
+			cResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;
 
 
 		// interpolate between source and result by intensity
 		// interpolate between source and result by intensity
-		'	cResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );',
+			cResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );
 
 
 		// convert to grayscale if desired
 		// convert to grayscale if desired
-		'	if( grayscale ) {',
-
-		'		cResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );',
+			if( grayscale ) {
 
 
-		'	}',
+				cResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );
 
 
-		'	gl_FragColor =  vec4( cResult, cTextureScreen.a );',
+			}
 
 
-		'}'
+			gl_FragColor =  vec4( cResult, cTextureScreen.a );
 
 
-	].join( '\n' )
+		}`,
 
 
 };
 };
 
 

+ 42 - 46
examples/jsm/shaders/FocusShader.js

@@ -4,7 +4,7 @@
  * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js
  * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js
  */
  */
 
 
-var FocusShader = {
+const FocusShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -16,76 +16,72 @@ var FocusShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform float screenWidth;
+		uniform float screenHeight;
+		uniform float sampleDistance;
+		uniform float waveFactor;
 
 
-		'uniform float screenWidth;',
-		'uniform float screenHeight;',
-		'uniform float sampleDistance;',
-		'uniform float waveFactor;',
+		uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 color, org, tmp, add;
+			float sample_dist, f;
+			vec2 vin;
+			vec2 uv = vUv;
 
 
-		'	vec4 color, org, tmp, add;',
-		'	float sample_dist, f;',
-		'	vec2 vin;',
-		'	vec2 uv = vUv;',
+			add = color = org = texture2D( tDiffuse, uv );
 
 
-		'	add = color = org = texture2D( tDiffuse, uv );',
+			vin = ( uv - vec2( 0.5 ) ) * vec2( 1.4 );
+			sample_dist = dot( vin, vin ) * 2.0;
 
 
-		'	vin = ( uv - vec2( 0.5 ) ) * vec2( 1.4 );',
-		'	sample_dist = dot( vin, vin ) * 2.0;',
+			f = ( waveFactor * 100.0 + sample_dist ) * sampleDistance * 4.0;
 
 
-		'	f = ( waveFactor * 100.0 + sample_dist ) * sampleDistance * 4.0;',
+			vec2 sampleSize = vec2(  1.0 / screenWidth, 1.0 / screenHeight ) * vec2( f );
 
 
-		'	vec2 sampleSize = vec2(  1.0 / screenWidth, 1.0 / screenHeight ) * vec2( f );',
+			add += tmp = texture2D( tDiffuse, uv + vec2( 0.111964, 0.993712 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
 
 
-		'	add += tmp = texture2D( tDiffuse, uv + vec2( 0.111964, 0.993712 ) * sampleSize );',
-		'	if( tmp.b < color.b ) color = tmp;',
+			add += tmp = texture2D( tDiffuse, uv + vec2( 0.846724, 0.532032 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
 
 
-		'	add += tmp = texture2D( tDiffuse, uv + vec2( 0.846724, 0.532032 ) * sampleSize );',
-		'	if( tmp.b < color.b ) color = tmp;',
+			add += tmp = texture2D( tDiffuse, uv + vec2( 0.943883, -0.330279 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
 
 
-		'	add += tmp = texture2D( tDiffuse, uv + vec2( 0.943883, -0.330279 ) * sampleSize );',
-		'	if( tmp.b < color.b ) color = tmp;',
+			add += tmp = texture2D( tDiffuse, uv + vec2( 0.330279, -0.943883 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
 
 
-		'	add += tmp = texture2D( tDiffuse, uv + vec2( 0.330279, -0.943883 ) * sampleSize );',
-		'	if( tmp.b < color.b ) color = tmp;',
+			add += tmp = texture2D( tDiffuse, uv + vec2( -0.532032, -0.846724 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
 
 
-		'	add += tmp = texture2D( tDiffuse, uv + vec2( -0.532032, -0.846724 ) * sampleSize );',
-		'	if( tmp.b < color.b ) color = tmp;',
+			add += tmp = texture2D( tDiffuse, uv + vec2( -0.993712, -0.111964 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
 
 
-		'	add += tmp = texture2D( tDiffuse, uv + vec2( -0.993712, -0.111964 ) * sampleSize );',
-		'	if( tmp.b < color.b ) color = tmp;',
+			add += tmp = texture2D( tDiffuse, uv + vec2( -0.707107, 0.707107 ) * sampleSize );
+			if( tmp.b < color.b ) color = tmp;
 
 
-		'	add += tmp = texture2D( tDiffuse, uv + vec2( -0.707107, 0.707107 ) * sampleSize );',
-		'	if( tmp.b < color.b ) color = tmp;',
+			color = color * vec4( 2.0 ) - ( add / vec4( 8.0 ) );
+			color = color + ( add / vec4( 8.0 ) - color ) * ( vec4( 1.0 ) - vec4( sample_dist * 0.5 ) );
 
 
-		'	color = color * vec4( 2.0 ) - ( add / vec4( 8.0 ) );',
-		'	color = color + ( add / vec4( 8.0 ) - color ) * ( vec4( 1.0 ) - vec4( sample_dist * 0.5 ) );',
+			gl_FragColor = vec4( color.rgb * color.rgb * vec3( 0.95 ) + color.rgb, 1.0 );
 
 
-		'	gl_FragColor = vec4( color.rgb * color.rgb * vec3( 0.95 ) + color.rgb, 1.0 );',
+		}`
 
 
-		'}'
-
-
-	].join( '\n' )
 };
 };
 
 
 export { FocusShader };
 export { FocusShader };

+ 52 - 55
examples/jsm/shaders/FreiChenShader.js

@@ -17,81 +17,78 @@ var FreiChenShader = {
 		'aspect': { value: new Vector2( 512, 512 ) }
 		'aspect': { value: new Vector2( 512, 512 ) }
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		varying vec2 vUv;
 
 
-		'uniform sampler2D tDiffuse;',
-		'varying vec2 vUv;',
+		uniform vec2 aspect;
 
 
-		'uniform vec2 aspect;',
+		vec2 texel = vec2( 1.0 / aspect.x, 1.0 / aspect.y );
 
 
-		'vec2 texel = vec2(1.0 / aspect.x, 1.0 / aspect.y);',
 
 
-
-		'mat3 G[9];',
+		mat3 G[9];
 
 
 		// hard coded matrix values!!!! as suggested in https://github.com/neilmendoza/ofxPostProcessing/blob/master/src/EdgePass.cpp#L45
 		// hard coded matrix values!!!! as suggested in https://github.com/neilmendoza/ofxPostProcessing/blob/master/src/EdgePass.cpp#L45
 
 
-		'const mat3 g0 = mat3( 0.3535533845424652, 0, -0.3535533845424652, 0.5, 0, -0.5, 0.3535533845424652, 0, -0.3535533845424652 );',
-		'const mat3 g1 = mat3( 0.3535533845424652, 0.5, 0.3535533845424652, 0, 0, 0, -0.3535533845424652, -0.5, -0.3535533845424652 );',
-		'const mat3 g2 = mat3( 0, 0.3535533845424652, -0.5, -0.3535533845424652, 0, 0.3535533845424652, 0.5, -0.3535533845424652, 0 );',
-		'const mat3 g3 = mat3( 0.5, -0.3535533845424652, 0, -0.3535533845424652, 0, 0.3535533845424652, 0, 0.3535533845424652, -0.5 );',
-		'const mat3 g4 = mat3( 0, -0.5, 0, 0.5, 0, 0.5, 0, -0.5, 0 );',
-		'const mat3 g5 = mat3( -0.5, 0, 0.5, 0, 0, 0, 0.5, 0, -0.5 );',
-		'const mat3 g6 = mat3( 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.6666666865348816, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204 );',
-		'const mat3 g7 = mat3( -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, 0.6666666865348816, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408 );',
-		'const mat3 g8 = mat3( 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408 );',
-
-		'void main(void)',
-		'{',
-
-		'	G[0] = g0,',
-		'	G[1] = g1,',
-		'	G[2] = g2,',
-		'	G[3] = g3,',
-		'	G[4] = g4,',
-		'	G[5] = g5,',
-		'	G[6] = g6,',
-		'	G[7] = g7,',
-		'	G[8] = g8;',
-
-		'	mat3 I;',
-		'	float cnv[9];',
-		'	vec3 sample;',
+		const mat3 g0 = mat3( 0.3535533845424652, 0, -0.3535533845424652, 0.5, 0, -0.5, 0.3535533845424652, 0, -0.3535533845424652 );
+		const mat3 g1 = mat3( 0.3535533845424652, 0.5, 0.3535533845424652, 0, 0, 0, -0.3535533845424652, -0.5, -0.3535533845424652 );
+		const mat3 g2 = mat3( 0, 0.3535533845424652, -0.5, -0.3535533845424652, 0, 0.3535533845424652, 0.5, -0.3535533845424652, 0 );
+		const mat3 g3 = mat3( 0.5, -0.3535533845424652, 0, -0.3535533845424652, 0, 0.3535533845424652, 0, 0.3535533845424652, -0.5 );
+		const mat3 g4 = mat3( 0, -0.5, 0, 0.5, 0, 0.5, 0, -0.5, 0 );
+		const mat3 g5 = mat3( -0.5, 0, 0.5, 0, 0, 0, 0.5, 0, -0.5 );
+		const mat3 g6 = mat3( 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.6666666865348816, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204 );
+		const mat3 g7 = mat3( -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, 0.6666666865348816, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408 );
+		const mat3 g8 = mat3( 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408 );
+
+		void main(void)
+		{
+
+			G[0] = g0,
+			G[1] = g1,
+			G[2] = g2,
+			G[3] = g3,
+			G[4] = g4,
+			G[5] = g5,
+			G[6] = g6,
+			G[7] = g7,
+			G[8] = g8;
+
+			mat3 I;
+			float cnv[9];
+			vec3 sample;
 
 
 		/* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */
 		/* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */
-		'	for (float i=0.0; i<3.0; i++) {',
-		'		for (float j=0.0; j<3.0; j++) {',
-		'			sample = texture2D(tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;',
-		'			I[int(i)][int(j)] = length(sample);',
-		'		}',
-		'	}',
+			for (float i=0.0; i<3.0; i++) {
+				for (float j=0.0; j<3.0; j++) {
+					sample = texture2D(tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;
+					I[int(i)][int(j)] = length(sample);
+				}
+			}
 
 
 		/* calculate the convolution values for all the masks */
 		/* calculate the convolution values for all the masks */
-		'	for (int i=0; i<9; i++) {',
-		'		float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);',
-		'		cnv[i] = dp3 * dp3;',
-		'	}',
+			for (int i=0; i<9; i++) {
+				float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);
+				cnv[i] = dp3 * dp3;
+			}
 
 
-		'	float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]);',
-		'	float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M);',
+			float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]);
+			float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M);
 
 
-		'	gl_FragColor = vec4(vec3(sqrt(M/S)), 1.0);',
-		'}'
+			gl_FragColor = vec4(vec3(sqrt(M/S)), 1.0);
+		}`
 
 
-	].join( '\n' )
 };
 };
 
 
 export { FreiChenShader };
 export { FreiChenShader };

+ 34 - 38
examples/jsm/shaders/FresnelShader.js

@@ -2,7 +2,7 @@
  * Based on Nvidia Cg tutorial
  * Based on Nvidia Cg tutorial
  */
  */
 
 
-var FresnelShader = {
+const FresnelShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -14,60 +14,56 @@ var FresnelShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'uniform float mRefractionRatio;',
-		'uniform float mFresnelBias;',
-		'uniform float mFresnelScale;',
-		'uniform float mFresnelPower;',
+		`uniform float mRefractionRatio;
+		uniform float mFresnelBias;
+		uniform float mFresnelScale;
+		uniform float mFresnelPower;
 
 
-		'varying vec3 vReflect;',
-		'varying vec3 vRefract[3];',
-		'varying float vReflectionFactor;',
+		varying vec3 vReflect;
+		varying vec3 vRefract[3];
+		varying float vReflectionFactor;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
-		'	vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',
+			vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+			vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
 
 
-		'	vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );',
+			vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
 
 
-		'	vec3 I = worldPosition.xyz - cameraPosition;',
+			vec3 I = worldPosition.xyz - cameraPosition;
 
 
-		'	vReflect = reflect( I, worldNormal );',
-		'	vRefract[0] = refract( normalize( I ), worldNormal, mRefractionRatio );',
-		'	vRefract[1] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.99 );',
-		'	vRefract[2] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.98 );',
-		'	vReflectionFactor = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), mFresnelPower );',
+			vReflect = reflect( I, worldNormal );
+			vRefract[0] = refract( normalize( I ), worldNormal, mRefractionRatio );
+			vRefract[1] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.99 );
+			vRefract[2] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.98 );
+			vReflectionFactor = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), mFresnelPower );
 
 
-		'	gl_Position = projectionMatrix * mvPosition;',
+			gl_Position = projectionMatrix * mvPosition;
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform samplerCube tCube;
 
 
-		'uniform samplerCube tCube;',
+		varying vec3 vReflect;
+		varying vec3 vRefract[3];
+		varying float vReflectionFactor;
 
 
-		'varying vec3 vReflect;',
-		'varying vec3 vRefract[3];',
-		'varying float vReflectionFactor;',
+		void main() {
 
 
-		'void main() {',
+			vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );
+			vec4 refractedColor = vec4( 1.0 );
 
 
-		'	vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );',
-		'	vec4 refractedColor = vec4( 1.0 );',
+			refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;
+			refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;
+			refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;
 
 
-		'	refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;',
-		'	refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;',
-		'	refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;',
+			gl_FragColor = mix( refractedColor, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );
 
 
-		'	gl_FragColor = mix( refractedColor, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 14 - 18
examples/jsm/shaders/GammaCorrectionShader.js

@@ -3,7 +3,7 @@
  * http://en.wikipedia.org/wiki/gamma_correction
  * http://en.wikipedia.org/wiki/gamma_correction
  */
  */
 
 
-var GammaCorrectionShader = {
+const GammaCorrectionShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -11,34 +11,30 @@ var GammaCorrectionShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 tex = texture2D( tDiffuse, vUv );
 
 
-		'	vec4 tex = texture2D( tDiffuse, vUv );',
+			gl_FragColor = LinearTosRGB( tex ); // optional: LinearToGamma( tex, float( GAMMA_FACTOR ) );
 
 
-		'	gl_FragColor = LinearTosRGB( tex );', // optional: LinearToGamma( tex, float( GAMMA_FACTOR ) );
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 88 - 105
examples/jsm/shaders/GodRaysShader.js

@@ -21,7 +21,7 @@ import {
  * Sousa2008 - Crysis Next Gen Effects, GDC2008, http://www.crytek.com/sites/default/files/GDC08_SousaT_CrysisEffects.ppt
  * Sousa2008 - Crysis Next Gen Effects, GDC2008, http://www.crytek.com/sites/default/files/GDC08_SousaT_CrysisEffects.ppt
  */
  */
 
 
-var GodRaysDepthMaskShader = {
+const GodRaysDepthMaskShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -31,33 +31,28 @@ var GodRaysDepthMaskShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		' vUv = uv;',
-		' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+		 vUv = uv;
+		 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+	 }`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		uniform sampler2D tInput;
 
 
-		'uniform sampler2D tInput;',
+		void main() {
 
 
-		'void main() {',
+			gl_FragColor = vec4( 1.0 ) - texture2D( tInput, vUv );
 
 
-		'	gl_FragColor = vec4( 1.0 ) - texture2D( tInput, vUv );',
-
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 
@@ -77,7 +72,7 @@ var GodRaysDepthMaskShader = {
  * decreased distance between samples.
  * decreased distance between samples.
  */
  */
 
 
-var GodRaysGenerateShader = {
+const GodRaysGenerateShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -93,47 +88,45 @@ var GodRaysGenerateShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		' vUv = uv;',
-		' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+		 vUv = uv;
+		 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+	 }`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`#define TAPS_PER_PASS 6.0
 
 
-		'#define TAPS_PER_PASS 6.0',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		uniform sampler2D tInput;
 
 
-		'uniform sampler2D tInput;',
+		uniform vec3 vSunPositionScreenSpace;
+		uniform float fStepSize; // filter step size
 
 
-		'uniform vec3 vSunPositionScreenSpace;',
-		'uniform float fStepSize;', // filter step size
-
-		'void main() {',
+		void main() {
 
 
 		// delta from current pixel to "sun" position
 		// delta from current pixel to "sun" position
 
 
-		'	vec2 delta = vSunPositionScreenSpace.xy - vUv;',
-		'	float dist = length( delta );',
+			vec2 delta = vSunPositionScreenSpace.xy - vUv;
+			float dist = length( delta );
 
 
 		// Step vector (uv space)
 		// Step vector (uv space)
 
 
-		'	vec2 stepv = fStepSize * delta / dist;',
+			vec2 stepv = fStepSize * delta / dist;
 
 
 		// Number of iterations between pixel and sun
 		// Number of iterations between pixel and sun
 
 
-		'	float iters = dist/fStepSize;',
+			float iters = dist/fStepSize;
 
 
-		'	vec2 uv = vUv.xy;',
-		'	float col = 0.0;',
+			vec2 uv = vUv.xy;
+			float col = 0.0;
 
 
 		// This breaks ANGLE in Chrome 22
 		// This breaks ANGLE in Chrome 22
 		//	- see http://code.google.com/p/chromium/issues/detail?id=153105
 		//	- see http://code.google.com/p/chromium/issues/detail?id=153105
@@ -160,39 +153,37 @@ var GodRaysGenerateShader = {
 
 
 		// Unrolling loop manually makes it work in ANGLE
 		// Unrolling loop manually makes it work in ANGLE
 
 
-		'	float f = min( 1.0, max( vSunPositionScreenSpace.z / 1000.0, 0.0 ) );', // used to fade out godrays
+			float f = min( 1.0, max( vSunPositionScreenSpace.z / 1000.0, 0.0 ) ); // used to fade out godrays
 
 
-		'	if ( 0.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;',
-		'	uv += stepv;',
+			if ( 0.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
 
 
-		'	if ( 1.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;',
-		'	uv += stepv;',
+			if ( 1.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
 
 
-		'	if ( 2.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;',
-		'	uv += stepv;',
+			if ( 2.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
 
 
-		'	if ( 3.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;',
-		'	uv += stepv;',
+			if ( 3.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
 
 
-		'	if ( 4.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;',
-		'	uv += stepv;',
+			if ( 4.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
 
 
-		'	if ( 5.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;',
-		'	uv += stepv;',
+			if ( 5.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
+			uv += stepv;
 
 
-		// Should technically be dividing by 'iters', but 'TAPS_PER_PASS' smooths out
+		// Should technically be dividing by 'iters but 'TAPS_PER_PASS' smooths out
 		// objectionable artifacts, in particular near the sun position. The side
 		// objectionable artifacts, in particular near the sun position. The side
 		// effect is that the result is darker than it should be around the sun, as
 		// effect is that the result is darker than it should be around the sun, as
 		// TAPS_PER_PASS is greater than the number of samples actually accumulated.
 		// TAPS_PER_PASS is greater than the number of samples actually accumulated.
-		// When the result is inverted (in the shader 'godrays_combine', this produces
+		// When the result is inverted (in the shader 'godrays_combine this produces
 		// a slight bright spot at the position of the sun, even when it is occluded.
 		// a slight bright spot at the position of the sun, even when it is occluded.
 
 
-		'	gl_FragColor = vec4( col/TAPS_PER_PASS );',
-		'	gl_FragColor.a = 1.0;',
-
-		'}'
+			gl_FragColor = vec4( col/TAPS_PER_PASS );
+			gl_FragColor.a = 1.0;
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 
@@ -201,7 +192,7 @@ var GodRaysGenerateShader = {
  * fGodRayIntensity attenuates the god rays.
  * fGodRayIntensity attenuates the god rays.
  */
  */
 
 
-var GodRaysCombineShader = {
+const GodRaysCombineShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -219,40 +210,36 @@ var GodRaysCombineShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		uniform sampler2D tColors;
+		uniform sampler2D tGodRays;
 
 
-		'uniform sampler2D tColors;',
-		'uniform sampler2D tGodRays;',
+		uniform float fGodRayIntensity;
 
 
-		'uniform float fGodRayIntensity;',
-
-		'void main() {',
+		void main() {
 
 
 		// Since THREE.MeshDepthMaterial renders foreground objects white and background
 		// Since THREE.MeshDepthMaterial renders foreground objects white and background
 		// objects black, the god-rays will be white streaks. Therefore value is inverted
 		// objects black, the god-rays will be white streaks. Therefore value is inverted
 		// before being combined with tColors
 		// before being combined with tColors
 
 
-		'	gl_FragColor = texture2D( tColors, vUv ) + fGodRayIntensity * vec4( 1.0 - texture2D( tGodRays, vUv ).r );',
-		'	gl_FragColor.a = 1.0;',
-
-		'}'
+			gl_FragColor = texture2D( tColors, vUv ) + fGodRayIntensity * vec4( 1.0 - texture2D( tGodRays, vUv ).r );
+			gl_FragColor.a = 1.0;
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 
@@ -262,7 +249,7 @@ var GodRaysCombineShader = {
  * cheaper/faster/simpler to implement this as a simple sun sprite.
  * cheaper/faster/simpler to implement this as a simple sun sprite.
  */
  */
 
 
-var GodRaysFakeSunShader = {
+const GodRaysFakeSunShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -284,46 +271,42 @@ var GodRaysFakeSunShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		uniform vec3 vSunPositionScreenSpace;
+		uniform float fAspect;
 
 
-		'uniform vec3 vSunPositionScreenSpace;',
-		'uniform float fAspect;',
+		uniform vec3 sunColor;
+		uniform vec3 bgColor;
 
 
-		'uniform vec3 sunColor;',
-		'uniform vec3 bgColor;',
+		void main() {
 
 
-		'void main() {',
-
-		'	vec2 diff = vUv - vSunPositionScreenSpace.xy;',
+			vec2 diff = vUv - vSunPositionScreenSpace.xy;
 
 
 		// Correct for aspect ratio
 		// Correct for aspect ratio
 
 
-		'	diff.x *= fAspect;',
-
-		'	float prop = clamp( length( diff ) / 0.5, 0.0, 1.0 );',
-		'	prop = 0.35 * pow( 1.0 - prop, 3.0 );',
+			diff.x *= fAspect;
 
 
-		'	gl_FragColor.xyz = ( vSunPositionScreenSpace.z > 0.0 ) ? mix( sunColor, bgColor, 1.0 - prop ) : bgColor;',
-		'	gl_FragColor.w = 1.0;',
+			float prop = clamp( length( diff ) / 0.5, 0.0, 1.0 );
+			prop = 0.35 * pow( 1.0 - prop, 3.0 );
 
 
-		'}'
+			gl_FragColor.xyz = ( vSunPositionScreenSpace.z > 0.0 ) ? mix( sunColor, bgColor, 1.0 - prop ) : bgColor;
+			gl_FragColor.w = 1.0;
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 201 - 205
examples/jsm/shaders/HalftoneShader.js

@@ -5,7 +5,7 @@
  *		Blending Mode (1 = Linear, 2 = Multiply, 3 = Add, 4 = Lighter, 5 = Darker)
  *		Blending Mode (1 = Linear, 2 = Multiply, 3 = Add, 4 = Lighter, 5 = Darker)
  */
  */
 
 
-var HalftoneShader = {
+const HalftoneShader = {
 
 
 	uniforms: {
 	uniforms: {
 		'tDiffuse': { value: null },
 		'tDiffuse': { value: null },
@@ -23,291 +23,287 @@ var HalftoneShader = {
 		'disable': { value: false }
 		'disable': { value: false }
 	},
 	},
 
 
-	vertexShader: [
-
-		'varying vec2 vUV;',
-
-		'void main() {',
-
-		'	vUV = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
-
-		'}'
-
-	].join( '\n' ),
-
-	fragmentShader: [
-
-		'#define SQRT2_MINUS_ONE 0.41421356',
-		'#define SQRT2_HALF_MINUS_ONE 0.20710678',
-		'#define PI2 6.28318531',
-		'#define SHAPE_DOT 1',
-		'#define SHAPE_ELLIPSE 2',
-		'#define SHAPE_LINE 3',
-		'#define SHAPE_SQUARE 4',
-		'#define BLENDING_LINEAR 1',
-		'#define BLENDING_MULTIPLY 2',
-		'#define BLENDING_ADD 3',
-		'#define BLENDING_LIGHTER 4',
-		'#define BLENDING_DARKER 5',
-		'uniform sampler2D tDiffuse;',
-		'uniform float radius;',
-		'uniform float rotateR;',
-		'uniform float rotateG;',
-		'uniform float rotateB;',
-		'uniform float scatter;',
-		'uniform float width;',
-		'uniform float height;',
-		'uniform int shape;',
-		'uniform bool disable;',
-		'uniform float blending;',
-		'uniform int blendingMode;',
-		'varying vec2 vUV;',
-		'uniform bool greyscale;',
-		'const int samples = 8;',
-
-		'float blend( float a, float b, float t ) {',
+	vertexShader:
+
+		`varying vec2 vUV;
+
+		void main() {
+
+			vUV = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
+
+		}`,
+
+	fragmentShader:
+
+		`#define SQRT2_MINUS_ONE 0.41421356
+		#define SQRT2_HALF_MINUS_ONE 0.20710678
+		#define PI2 6.28318531
+		#define SHAPE_DOT 1
+		#define SHAPE_ELLIPSE 2
+		#define SHAPE_LINE 3
+		#define SHAPE_SQUARE 4
+		#define BLENDING_LINEAR 1
+		#define BLENDING_MULTIPLY 2
+		#define BLENDING_ADD 3
+		#define BLENDING_LIGHTER 4
+		#define BLENDING_DARKER 5
+		uniform sampler2D tDiffuse;
+		uniform float radius;
+		uniform float rotateR;
+		uniform float rotateG;
+		uniform float rotateB;
+		uniform float scatter;
+		uniform float width;
+		uniform float height;
+		uniform int shape;
+		uniform bool disable;
+		uniform float blending;
+		uniform int blendingMode;
+		varying vec2 vUV;
+		uniform bool greyscale;
+		const int samples = 8;
+
+		float blend( float a, float b, float t ) {
 
 
 		// linear blend
 		// linear blend
-		'	return a * ( 1.0 - t ) + b * t;',
+			return a * ( 1.0 - t ) + b * t;
 
 
-		'}',
+		}
 
 
-		'float hypot( float x, float y ) {',
+		float hypot( float x, float y ) {
 
 
 		// vector magnitude
 		// vector magnitude
-		'	return sqrt( x * x + y * y );',
+			return sqrt( x * x + y * y );
 
 
-		'}',
+		}
 
 
-		'float rand( vec2 seed ){',
+		float rand( vec2 seed ){
 
 
 		// get pseudo-random number
 		// get pseudo-random number
-	    'return fract( sin( dot( seed.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );',
+			return fract( sin( dot( seed.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );
 
 
-		'}',
+		}
 
 
-		'float distanceToDotRadius( float channel, vec2 coord, vec2 normal, vec2 p, float angle, float rad_max ) {',
+		float distanceToDotRadius( float channel, vec2 coord, vec2 normal, vec2 p, float angle, float rad_max ) {
 
 
 		// apply shape-specific transforms
 		// apply shape-specific transforms
-		'	float dist = hypot( coord.x - p.x, coord.y - p.y );',
-		'	float rad = channel;',
+			float dist = hypot( coord.x - p.x, coord.y - p.y );
+			float rad = channel;
 
 
-		'	if ( shape == SHAPE_DOT ) {',
+			if ( shape == SHAPE_DOT ) {
 
 
-		'		rad = pow( abs( rad ), 1.125 ) * rad_max;',
+				rad = pow( abs( rad ), 1.125 ) * rad_max;
 
 
-		'	} else if ( shape == SHAPE_ELLIPSE ) {',
+			} else if ( shape == SHAPE_ELLIPSE ) {
 
 
-		'		rad = pow( abs( rad ), 1.125 ) * rad_max;',
+				rad = pow( abs( rad ), 1.125 ) * rad_max;
 
 
-		'		if ( dist != 0.0 ) {',
-		'			float dot_p = abs( ( p.x - coord.x ) / dist * normal.x + ( p.y - coord.y ) / dist * normal.y );',
-		'			dist = ( dist * ( 1.0 - SQRT2_HALF_MINUS_ONE ) ) + dot_p * dist * SQRT2_MINUS_ONE;',
-		'		}',
+				if ( dist != 0.0 ) {
+					float dot_p = abs( ( p.x - coord.x ) / dist * normal.x + ( p.y - coord.y ) / dist * normal.y );
+					dist = ( dist * ( 1.0 - SQRT2_HALF_MINUS_ONE ) ) + dot_p * dist * SQRT2_MINUS_ONE;
+				}
 
 
-		'	} else if ( shape == SHAPE_LINE ) {',
+			} else if ( shape == SHAPE_LINE ) {
 
 
-		'		rad = pow( abs( rad ), 1.5) * rad_max;',
-		'		float dot_p = ( p.x - coord.x ) * normal.x + ( p.y - coord.y ) * normal.y;',
-		'		dist = hypot( normal.x * dot_p, normal.y * dot_p );',
+				rad = pow( abs( rad ), 1.5) * rad_max;
+				float dot_p = ( p.x - coord.x ) * normal.x + ( p.y - coord.y ) * normal.y;
+				dist = hypot( normal.x * dot_p, normal.y * dot_p );
 
 
-		'	} else if ( shape == SHAPE_SQUARE ) {',
+			} else if ( shape == SHAPE_SQUARE ) {
 
 
-		'		float theta = atan( p.y - coord.y, p.x - coord.x ) - angle;',
-		'		float sin_t = abs( sin( theta ) );',
-		'		float cos_t = abs( cos( theta ) );',
-		'		rad = pow( abs( rad ), 1.4 );',
-		'		rad = rad_max * ( rad + ( ( sin_t > cos_t ) ? rad - sin_t * rad : rad - cos_t * rad ) );',
+				float theta = atan( p.y - coord.y, p.x - coord.x ) - angle;
+				float sin_t = abs( sin( theta ) );
+				float cos_t = abs( cos( theta ) );
+				rad = pow( abs( rad ), 1.4 );
+				rad = rad_max * ( rad + ( ( sin_t > cos_t ) ? rad - sin_t * rad : rad - cos_t * rad ) );
 
 
-		'	}',
+			}
 
 
-		'	return rad - dist;',
+			return rad - dist;
 
 
-		'}',
+		}
 
 
-		'struct Cell {',
+		struct Cell {
 
 
 		// grid sample positions
 		// grid sample positions
-		'	vec2 normal;',
-		'	vec2 p1;',
-		'	vec2 p2;',
-		'	vec2 p3;',
-		'	vec2 p4;',
-		'	float samp2;',
-		'	float samp1;',
-		'	float samp3;',
-		'	float samp4;',
+			vec2 normal;
+			vec2 p1;
+			vec2 p2;
+			vec2 p3;
+			vec2 p4;
+			float samp2;
+			float samp1;
+			float samp3;
+			float samp4;
 
 
-		'};',
+		};
 
 
-		'vec4 getSample( vec2 point ) {',
+		vec4 getSample( vec2 point ) {
 
 
 		// multi-sampled point
 		// multi-sampled point
-		'	vec4 tex = texture2D( tDiffuse, vec2( point.x / width, point.y / height ) );',
-		'	float base = rand( vec2( floor( point.x ), floor( point.y ) ) ) * PI2;',
-		'	float step = PI2 / float( samples );',
-		'	float dist = radius * 0.66;',
+			vec4 tex = texture2D( tDiffuse, vec2( point.x / width, point.y / height ) );
+			float base = rand( vec2( floor( point.x ), floor( point.y ) ) ) * PI2;
+			float step = PI2 / float( samples );
+			float dist = radius * 0.66;
 
 
-		'	for ( int i = 0; i < samples; ++i ) {',
+			for ( int i = 0; i < samples; ++i ) {
 
 
-		'		float r = base + step * float( i );',
-		'		vec2 coord = point + vec2( cos( r ) * dist, sin( r ) * dist );',
-		'		tex += texture2D( tDiffuse, vec2( coord.x / width, coord.y / height ) );',
+				float r = base + step * float( i );
+				vec2 coord = point + vec2( cos( r ) * dist, sin( r ) * dist );
+				tex += texture2D( tDiffuse, vec2( coord.x / width, coord.y / height ) );
 
 
-		'	}',
+			}
 
 
-		'	tex /= float( samples ) + 1.0;',
-		'	return tex;',
+			tex /= float( samples ) + 1.0;
+			return tex;
 
 
-		'}',
+		}
 
 
-		'float getDotColour( Cell c, vec2 p, int channel, float angle, float aa ) {',
+		float getDotColour( Cell c, vec2 p, int channel, float angle, float aa ) {
 
 
 		// get colour for given point
 		// get colour for given point
-		'	float dist_c_1, dist_c_2, dist_c_3, dist_c_4, res;',
+			float dist_c_1, dist_c_2, dist_c_3, dist_c_4, res;
 
 
-		'	if ( channel == 0 ) {',
+			if ( channel == 0 ) {
 
 
-		'		c.samp1 = getSample( c.p1 ).r;',
-		'		c.samp2 = getSample( c.p2 ).r;',
-		'		c.samp3 = getSample( c.p3 ).r;',
-		'		c.samp4 = getSample( c.p4 ).r;',
+				c.samp1 = getSample( c.p1 ).r;
+				c.samp2 = getSample( c.p2 ).r;
+				c.samp3 = getSample( c.p3 ).r;
+				c.samp4 = getSample( c.p4 ).r;
 
 
-		'	} else if (channel == 1) {',
+			} else if (channel == 1) {
 
 
-		'		c.samp1 = getSample( c.p1 ).g;',
-		'		c.samp2 = getSample( c.p2 ).g;',
-		'		c.samp3 = getSample( c.p3 ).g;',
-		'		c.samp4 = getSample( c.p4 ).g;',
+				c.samp1 = getSample( c.p1 ).g;
+				c.samp2 = getSample( c.p2 ).g;
+				c.samp3 = getSample( c.p3 ).g;
+				c.samp4 = getSample( c.p4 ).g;
 
 
-		'	} else {',
+			} else {
 
 
-		'		c.samp1 = getSample( c.p1 ).b;',
-		'		c.samp3 = getSample( c.p3 ).b;',
-		'		c.samp2 = getSample( c.p2 ).b;',
-		'		c.samp4 = getSample( c.p4 ).b;',
+				c.samp1 = getSample( c.p1 ).b;
+				c.samp3 = getSample( c.p3 ).b;
+				c.samp2 = getSample( c.p2 ).b;
+				c.samp4 = getSample( c.p4 ).b;
 
 
-		'	}',
+			}
 
 
-		'	dist_c_1 = distanceToDotRadius( c.samp1, c.p1, c.normal, p, angle, radius );',
-		'	dist_c_2 = distanceToDotRadius( c.samp2, c.p2, c.normal, p, angle, radius );',
-		'	dist_c_3 = distanceToDotRadius( c.samp3, c.p3, c.normal, p, angle, radius );',
-		'	dist_c_4 = distanceToDotRadius( c.samp4, c.p4, c.normal, p, angle, radius );',
-		'	res = ( dist_c_1 > 0.0 ) ? clamp( dist_c_1 / aa, 0.0, 1.0 ) : 0.0;',
-		'	res += ( dist_c_2 > 0.0 ) ? clamp( dist_c_2 / aa, 0.0, 1.0 ) : 0.0;',
-		'	res += ( dist_c_3 > 0.0 ) ? clamp( dist_c_3 / aa, 0.0, 1.0 ) : 0.0;',
-		'	res += ( dist_c_4 > 0.0 ) ? clamp( dist_c_4 / aa, 0.0, 1.0 ) : 0.0;',
-		'	res = clamp( res, 0.0, 1.0 );',
+			dist_c_1 = distanceToDotRadius( c.samp1, c.p1, c.normal, p, angle, radius );
+			dist_c_2 = distanceToDotRadius( c.samp2, c.p2, c.normal, p, angle, radius );
+			dist_c_3 = distanceToDotRadius( c.samp3, c.p3, c.normal, p, angle, radius );
+			dist_c_4 = distanceToDotRadius( c.samp4, c.p4, c.normal, p, angle, radius );
+			res = ( dist_c_1 > 0.0 ) ? clamp( dist_c_1 / aa, 0.0, 1.0 ) : 0.0;
+			res += ( dist_c_2 > 0.0 ) ? clamp( dist_c_2 / aa, 0.0, 1.0 ) : 0.0;
+			res += ( dist_c_3 > 0.0 ) ? clamp( dist_c_3 / aa, 0.0, 1.0 ) : 0.0;
+			res += ( dist_c_4 > 0.0 ) ? clamp( dist_c_4 / aa, 0.0, 1.0 ) : 0.0;
+			res = clamp( res, 0.0, 1.0 );
 
 
-		'	return res;',
+			return res;
 
 
-		'}',
+		}
 
 
-		'Cell getReferenceCell( vec2 p, vec2 origin, float grid_angle, float step ) {',
+		Cell getReferenceCell( vec2 p, vec2 origin, float grid_angle, float step ) {
 
 
 		// get containing cell
 		// get containing cell
-		'	Cell c;',
+			Cell c;
 
 
 		// calc grid
 		// calc grid
-		'	vec2 n = vec2( cos( grid_angle ), sin( grid_angle ) );',
-		'	float threshold = step * 0.5;',
-		'	float dot_normal = n.x * ( p.x - origin.x ) + n.y * ( p.y - origin.y );',
-		'	float dot_line = -n.y * ( p.x - origin.x ) + n.x * ( p.y - origin.y );',
-		'	vec2 offset = vec2( n.x * dot_normal, n.y * dot_normal );',
-		'	float offset_normal = mod( hypot( offset.x, offset.y ), step );',
-		'	float normal_dir = ( dot_normal < 0.0 ) ? 1.0 : -1.0;',
-		'	float normal_scale = ( ( offset_normal < threshold ) ? -offset_normal : step - offset_normal ) * normal_dir;',
-		'	float offset_line = mod( hypot( ( p.x - offset.x ) - origin.x, ( p.y - offset.y ) - origin.y ), step );',
-		'	float line_dir = ( dot_line < 0.0 ) ? 1.0 : -1.0;',
-		'	float line_scale = ( ( offset_line < threshold ) ? -offset_line : step - offset_line ) * line_dir;',
+			vec2 n = vec2( cos( grid_angle ), sin( grid_angle ) );
+			float threshold = step * 0.5;
+			float dot_normal = n.x * ( p.x - origin.x ) + n.y * ( p.y - origin.y );
+			float dot_line = -n.y * ( p.x - origin.x ) + n.x * ( p.y - origin.y );
+			vec2 offset = vec2( n.x * dot_normal, n.y * dot_normal );
+			float offset_normal = mod( hypot( offset.x, offset.y ), step );
+			float normal_dir = ( dot_normal < 0.0 ) ? 1.0 : -1.0;
+			float normal_scale = ( ( offset_normal < threshold ) ? -offset_normal : step - offset_normal ) * normal_dir;
+			float offset_line = mod( hypot( ( p.x - offset.x ) - origin.x, ( p.y - offset.y ) - origin.y ), step );
+			float line_dir = ( dot_line < 0.0 ) ? 1.0 : -1.0;
+			float line_scale = ( ( offset_line < threshold ) ? -offset_line : step - offset_line ) * line_dir;
 
 
 		// get closest corner
 		// get closest corner
-		'	c.normal = n;',
-		'	c.p1.x = p.x - n.x * normal_scale + n.y * line_scale;',
-		'	c.p1.y = p.y - n.y * normal_scale - n.x * line_scale;',
+			c.normal = n;
+			c.p1.x = p.x - n.x * normal_scale + n.y * line_scale;
+			c.p1.y = p.y - n.y * normal_scale - n.x * line_scale;
 
 
 		// scatter
 		// scatter
-		'	if ( scatter != 0.0 ) {',
+			if ( scatter != 0.0 ) {
 
 
-		'		float off_mag = scatter * threshold * 0.5;',
-		'		float off_angle = rand( vec2( floor( c.p1.x ), floor( c.p1.y ) ) ) * PI2;',
-		'		c.p1.x += cos( off_angle ) * off_mag;',
-		'		c.p1.y += sin( off_angle ) * off_mag;',
+				float off_mag = scatter * threshold * 0.5;
+				float off_angle = rand( vec2( floor( c.p1.x ), floor( c.p1.y ) ) ) * PI2;
+				c.p1.x += cos( off_angle ) * off_mag;
+				c.p1.y += sin( off_angle ) * off_mag;
 
 
-		'	}',
+			}
 
 
 		// find corners
 		// find corners
-		'	float normal_step = normal_dir * ( ( offset_normal < threshold ) ? step : -step );',
-		'	float line_step = line_dir * ( ( offset_line < threshold ) ? step : -step );',
-		'	c.p2.x = c.p1.x - n.x * normal_step;',
-		'	c.p2.y = c.p1.y - n.y * normal_step;',
-		'	c.p3.x = c.p1.x + n.y * line_step;',
-		'	c.p3.y = c.p1.y - n.x * line_step;',
-		'	c.p4.x = c.p1.x - n.x * normal_step + n.y * line_step;',
-		'	c.p4.y = c.p1.y - n.y * normal_step - n.x * line_step;',
+			float normal_step = normal_dir * ( ( offset_normal < threshold ) ? step : -step );
+			float line_step = line_dir * ( ( offset_line < threshold ) ? step : -step );
+			c.p2.x = c.p1.x - n.x * normal_step;
+			c.p2.y = c.p1.y - n.y * normal_step;
+			c.p3.x = c.p1.x + n.y * line_step;
+			c.p3.y = c.p1.y - n.x * line_step;
+			c.p4.x = c.p1.x - n.x * normal_step + n.y * line_step;
+			c.p4.y = c.p1.y - n.y * normal_step - n.x * line_step;
 
 
-		'	return c;',
+			return c;
 
 
-		'}',
+		}
 
 
-		'float blendColour( float a, float b, float t ) {',
+		float blendColour( float a, float b, float t ) {
 
 
 		// blend colours
 		// blend colours
-		'	if ( blendingMode == BLENDING_LINEAR ) {',
-		'		return blend( a, b, 1.0 - t );',
-		'	} else if ( blendingMode == BLENDING_ADD ) {',
-		'		return blend( a, min( 1.0, a + b ), t );',
-		'	} else if ( blendingMode == BLENDING_MULTIPLY ) {',
-		'		return blend( a, max( 0.0, a * b ), t );',
-		'	} else if ( blendingMode == BLENDING_LIGHTER ) {',
-		'		return blend( a, max( a, b ), t );',
-		'	} else if ( blendingMode == BLENDING_DARKER ) {',
-		'		return blend( a, min( a, b ), t );',
-		'	} else {',
-		'		return blend( a, b, 1.0 - t );',
-		'	}',
-
-		'}',
-
-		'void main() {',
-
-		'	if ( ! disable ) {',
+			if ( blendingMode == BLENDING_LINEAR ) {
+				return blend( a, b, 1.0 - t );
+			} else if ( blendingMode == BLENDING_ADD ) {
+				return blend( a, min( 1.0, a + b ), t );
+			} else if ( blendingMode == BLENDING_MULTIPLY ) {
+				return blend( a, max( 0.0, a * b ), t );
+			} else if ( blendingMode == BLENDING_LIGHTER ) {
+				return blend( a, max( a, b ), t );
+			} else if ( blendingMode == BLENDING_DARKER ) {
+				return blend( a, min( a, b ), t );
+			} else {
+				return blend( a, b, 1.0 - t );
+			}
+
+		}
+
+		void main() {
+
+			if ( ! disable ) {
 
 
 		// setup
 		// setup
-		'		vec2 p = vec2( vUV.x * width, vUV.y * height );',
-		'		vec2 origin = vec2( 0, 0 );',
-		'		float aa = ( radius < 2.5 ) ? radius * 0.5 : 1.25;',
+				vec2 p = vec2( vUV.x * width, vUV.y * height );
+				vec2 origin = vec2( 0, 0 );
+				float aa = ( radius < 2.5 ) ? radius * 0.5 : 1.25;
 
 
 		// get channel samples
 		// get channel samples
-		'		Cell cell_r = getReferenceCell( p, origin, rotateR, radius );',
-		'		Cell cell_g = getReferenceCell( p, origin, rotateG, radius );',
-		'		Cell cell_b = getReferenceCell( p, origin, rotateB, radius );',
-		'		float r = getDotColour( cell_r, p, 0, rotateR, aa );',
-		'		float g = getDotColour( cell_g, p, 1, rotateG, aa );',
-		'		float b = getDotColour( cell_b, p, 2, rotateB, aa );',
+				Cell cell_r = getReferenceCell( p, origin, rotateR, radius );
+				Cell cell_g = getReferenceCell( p, origin, rotateG, radius );
+				Cell cell_b = getReferenceCell( p, origin, rotateB, radius );
+				float r = getDotColour( cell_r, p, 0, rotateR, aa );
+				float g = getDotColour( cell_g, p, 1, rotateG, aa );
+				float b = getDotColour( cell_b, p, 2, rotateB, aa );
 
 
 		// blend with original
 		// blend with original
-		'		vec4 colour = texture2D( tDiffuse, vUV );',
-		'		r = blendColour( r, colour.r, blending );',
-		'		g = blendColour( g, colour.g, blending );',
-		'		b = blendColour( b, colour.b, blending );',
+				vec4 colour = texture2D( tDiffuse, vUV );
+				r = blendColour( r, colour.r, blending );
+				g = blendColour( g, colour.g, blending );
+				b = blendColour( b, colour.b, blending );
 
 
-		'		if ( greyscale ) {',
-		'			r = g = b = (r + b + g) / 3.0;',
-		'		}',
+				if ( greyscale ) {
+					r = g = b = (r + b + g) / 3.0;
+				}
 
 
-		'		gl_FragColor = vec4( r, g, b, 1.0 );',
+				gl_FragColor = vec4( r, g, b, 1.0 );
 
 
-		'	} else {',
+			} else {
 
 
-		'		gl_FragColor = texture2D( tDiffuse, vUV );',
+				gl_FragColor = texture2D( tDiffuse, vUV );
 
 
-		'	}',
+			}
 
 
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 23 - 27
examples/jsm/shaders/HorizontalBlurShader.js

@@ -17,45 +17,41 @@ var HorizontalBlurShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform float h;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform float h;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 sum = vec4( 0.0 );
 
 
-		'	vec4 sum = vec4( 0.0 );',
+			sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;
 
 
-		'	sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;',
+			gl_FragColor = sum;
 
 
-		'	gl_FragColor = sum;',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 25 - 29
examples/jsm/shaders/HorizontalTiltShiftShader.js

@@ -17,48 +17,44 @@ var HorizontalTiltShiftShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform float h;
+		uniform float r;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform float h;',
-		'uniform float r;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 sum = vec4( 0.0 );
 
 
-		'	vec4 sum = vec4( 0.0 );',
+			float hh = h * abs( r - vUv.y );
 
 
-		'	float hh = h * abs( r - vUv.y );',
+			sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;
 
 
-		'	sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;',
+			gl_FragColor = sum;
 
 
-		'	gl_FragColor = sum;',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 32 - 36
examples/jsm/shaders/HueSaturationShader.js

@@ -5,7 +5,7 @@
  * saturation: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast)
  * saturation: -1 to 1 (-1 is solid gray, 0 is no change, and 1 is maximum contrast)
  */
  */
 
 
-var HueSaturationShader = {
+const HueSaturationShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -15,54 +15,50 @@ var HueSaturationShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
+			vUv = uv;
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform float hue;
+		uniform float saturation;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform float hue;',
-		'uniform float saturation;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			gl_FragColor = texture2D( tDiffuse, vUv );
 
 
-		'	gl_FragColor = texture2D( tDiffuse, vUv );',
+			// hue
+			float angle = hue * 3.14159265;
+			float s = sin(angle), c = cos(angle);
+			vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;
+			float len = length(gl_FragColor.rgb);
+			gl_FragColor.rgb = vec3(
+				dot(gl_FragColor.rgb, weights.xyz),
+				dot(gl_FragColor.rgb, weights.zxy),
+				dot(gl_FragColor.rgb, weights.yzx)
+			);
 
 
-		// hue
-		'	float angle = hue * 3.14159265;',
-		'	float s = sin(angle), c = cos(angle);',
-		'	vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;',
-		'	float len = length(gl_FragColor.rgb);',
-		'	gl_FragColor.rgb = vec3(',
-		'		dot(gl_FragColor.rgb, weights.xyz),',
-		'		dot(gl_FragColor.rgb, weights.zxy),',
-		'		dot(gl_FragColor.rgb, weights.yzx)',
-		'	);',
+			// saturation
+			float average = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / 3.0;
+			if (saturation > 0.0) {
+				gl_FragColor.rgb += (average - gl_FragColor.rgb) * (1.0 - 1.0 / (1.001 - saturation));
+			} else {
+				gl_FragColor.rgb += (average - gl_FragColor.rgb) * (-saturation);
+			}
 
 
-		// saturation
-		'	float average = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / 3.0;',
-		'	if (saturation > 0.0) {',
-		'		gl_FragColor.rgb += (average - gl_FragColor.rgb) * (1.0 - 1.0 / (1.001 - saturation));',
-		'	} else {',
-		'		gl_FragColor.rgb += (average - gl_FragColor.rgb) * (-saturation);',
-		'	}',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 23 - 27
examples/jsm/shaders/KaleidoShader.js

@@ -8,7 +8,7 @@
  * angle: initial angle in radians
  * angle: initial angle in radians
  */
  */
 
 
-var KaleidoShader = {
+const KaleidoShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -18,42 +18,38 @@ var KaleidoShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform float sides;
+		uniform float angle;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform float sides;',
-		'uniform float angle;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec2 p = vUv - 0.5;
+			float r = length(p);
+			float a = atan(p.y, p.x) + angle;
+			float tau = 2. * 3.1416 ;
+			a = mod(a, tau/sides);
+			a = abs(a - tau/sides/2.) ;
+			p = r * vec2(cos(a), sin(a));
+			vec4 color = texture2D(tDiffuse, p + 0.5);
+			gl_FragColor = color;
 
 
-		'	vec2 p = vUv - 0.5;',
-		'	float r = length(p);',
-		'	float a = atan(p.y, p.x) + angle;',
-		'	float tau = 2. * 3.1416 ;',
-		'	a = mod(a, tau/sides);',
-		'	a = abs(a - tau/sides/2.) ;',
-		'	p = r * vec2(cos(a), sin(a));',
-		'	vec4 color = texture2D(tDiffuse, p + 0.5);',
-		'	gl_FragColor = color;',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 22 - 26
examples/jsm/shaders/LuminosityHighPassShader.js

@@ -7,7 +7,7 @@ import {
  * http://en.wikipedia.org/wiki/Luminosity
  * http://en.wikipedia.org/wiki/Luminosity
  */
  */
 
 
-var LuminosityHighPassShader = {
+const LuminosityHighPassShader = {
 
 
 	shaderID: 'luminosityHighPass',
 	shaderID: 'luminosityHighPass',
 
 
@@ -21,47 +21,43 @@ var LuminosityHighPassShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
+			vUv = uv;
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform vec3 defaultColor;
+		uniform float defaultOpacity;
+		uniform float luminosityThreshold;
+		uniform float smoothWidth;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform vec3 defaultColor;',
-		'uniform float defaultOpacity;',
-		'uniform float luminosityThreshold;',
-		'uniform float smoothWidth;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 texel = texture2D( tDiffuse, vUv );
 
 
-		'	vec4 texel = texture2D( tDiffuse, vUv );',
+			vec3 luma = vec3( 0.299, 0.587, 0.114 );
 
 
-		'	vec3 luma = vec3( 0.299, 0.587, 0.114 );',
+			float v = dot( texel.xyz, luma );
 
 
-		'	float v = dot( texel.xyz, luma );',
+			vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );
 
 
-		'	vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );',
+			float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );
 
 
-		'	float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );',
+			gl_FragColor = mix( outputColor, texel, alpha );
 
 
-		'	gl_FragColor = mix( outputColor, texel, alpha );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 16 - 20
examples/jsm/shaders/LuminosityShader.js

@@ -3,7 +3,7 @@
  * http://en.wikipedia.org/wiki/Luminosity
  * http://en.wikipedia.org/wiki/Luminosity
  */
  */
 
 
-var LuminosityShader = {
+const LuminosityShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -11,39 +11,35 @@ var LuminosityShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
+			vUv = uv;
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`#include <common>
 
 
-		'#include <common>',
+		uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 texel = texture2D( tDiffuse, vUv );
 
 
-		'	vec4 texel = texture2D( tDiffuse, vUv );',
+			float l = linearToRelativeLuminance( texel.rgb );
 
 
-		'	float l = linearToRelativeLuminance( texel.rgb );',
+			gl_FragColor = vec4( l, l, l, texel.w );
 
 
-		'	gl_FragColor = vec4( l, l, l, texel.w );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 25 - 29
examples/jsm/shaders/MirrorShader.js

@@ -5,7 +5,7 @@
  * side: side of input to mirror (0 = left, 1 = right, 2 = top, 3 = bottom)
  * side: side of input to mirror (0 = left, 1 = right, 2 = top, 3 = bottom)
  */
  */
 
 
-var MirrorShader = {
+const MirrorShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -14,44 +14,40 @@ var MirrorShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform int side;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform int side;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec2 p = vUv;
+			if (side == 0){
+				if (p.x > 0.5) p.x = 1.0 - p.x;
+			}else if (side == 1){
+				if (p.x < 0.5) p.x = 1.0 - p.x;
+			}else if (side == 2){
+				if (p.y < 0.5) p.y = 1.0 - p.y;
+			}else if (side == 3){
+				if (p.y > 0.5) p.y = 1.0 - p.y;
+			}
+			vec4 color = texture2D(tDiffuse, p);
+			gl_FragColor = color;
 
 
-		'	vec2 p = vUv;',
-		'	if (side == 0){',
-		'		if (p.x > 0.5) p.x = 1.0 - p.x;',
-		'	}else if (side == 1){',
-		'		if (p.x < 0.5) p.x = 1.0 - p.x;',
-		'	}else if (side == 2){',
-		'		if (p.y < 0.5) p.y = 1.0 - p.y;',
-		'	}else if (side == 3){',
-		'		if (p.y > 0.5) p.y = 1.0 - p.y;',
-		'	} ',
-		'	vec4 color = texture2D(tDiffuse, p);',
-		'	gl_FragColor = color;',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 18 - 22
examples/jsm/shaders/NormalMapShader.js

@@ -7,7 +7,7 @@ import {
  * - compute normals from heightmap
  * - compute normals from heightmap
  */
  */
 
 
-var NormalMapShader = {
+const NormalMapShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -18,39 +18,35 @@ var NormalMapShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform float height;
+		uniform vec2 resolution;
+		uniform sampler2D heightMap;
 
 
-		'uniform float height;',
-		'uniform vec2 resolution;',
-		'uniform sampler2D heightMap;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			float val = texture2D( heightMap, vUv ).x;
 
 
-		'	float val = texture2D( heightMap, vUv ).x;',
+			float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;
+			float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;
 
 
-		'	float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;',
-		'	float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;',
+			gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height  ) ) + 0.5 ), 1.0 );
 
 
-		'	gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height  ) ) + 0.5 ), 1.0 );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 108 - 112
examples/jsm/shaders/ParallaxShader.js

@@ -3,7 +3,7 @@
 // No tangent-space transforms logic based on
 // No tangent-space transforms logic based on
 //   http://mmikkelsen3d.blogspot.sk/2012/02/parallaxpoc-mapping-and-no-tangent.html
 //   http://mmikkelsen3d.blogspot.sk/2012/02/parallaxpoc-mapping-and-no-tangent.html
 
 
-var ParallaxShader = {
+const ParallaxShader = {
 	// Ordered from fastest to best quality.
 	// Ordered from fastest to best quality.
 	modes: {
 	modes: {
 		none: 'NO_PARALLAX',
 		none: 'NO_PARALLAX',
@@ -21,165 +21,161 @@ var ParallaxShader = {
 		'parallaxMaxLayers': { value: null }
 		'parallaxMaxLayers': { value: null }
 	},
 	},
 
 
-	vertexShader: [
-		'varying vec2 vUv;',
-		'varying vec3 vViewPosition;',
-		'varying vec3 vNormal;',
+	vertexShader:
+		`varying vec2 vUv;
+		varying vec3 vViewPosition;
+		varying vec3 vNormal;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
-		'	vViewPosition = -mvPosition.xyz;',
-		'	vNormal = normalize( normalMatrix * normal );',
-		'	gl_Position = projectionMatrix * mvPosition;',
+			vUv = uv;
+			vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+			vViewPosition = -mvPosition.xyz;
+			vNormal = normalize( normalMatrix * normal );
+			gl_Position = projectionMatrix * mvPosition;
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
+		`uniform sampler2D bumpMap;
+		uniform sampler2D map;
 
 
-	fragmentShader: [
-		'uniform sampler2D bumpMap;',
-		'uniform sampler2D map;',
+		uniform float parallaxScale;
+		uniform float parallaxMinLayers;
+		uniform float parallaxMaxLayers;
 
 
-		'uniform float parallaxScale;',
-		'uniform float parallaxMinLayers;',
-		'uniform float parallaxMaxLayers;',
+		varying vec2 vUv;
+		varying vec3 vViewPosition;
+		varying vec3 vNormal;
 
 
-		'varying vec2 vUv;',
-		'varying vec3 vViewPosition;',
-		'varying vec3 vNormal;',
+		#ifdef USE_BASIC_PARALLAX
 
 
-		'#ifdef USE_BASIC_PARALLAX',
+			vec2 parallaxMap( in vec3 V ) {
 
 
-		'	vec2 parallaxMap( in vec3 V ) {',
+				float initialHeight = texture2D( bumpMap, vUv ).r;
 
 
-		'		float initialHeight = texture2D( bumpMap, vUv ).r;',
+				// No Offset Limitting: messy, floating output at grazing angles.
+			//"vec2 texCoordOffset = parallaxScale * V.xy / V.z * initialHeight;",
 
 
-		// No Offset Limitting: messy, floating output at grazing angles.
-		//"vec2 texCoordOffset = parallaxScale * V.xy / V.z * initialHeight;",
+			// Offset Limiting
+				vec2 texCoordOffset = parallaxScale * V.xy * initialHeight;
+				return vUv - texCoordOffset;
 
 
-		// Offset Limiting
-		'		vec2 texCoordOffset = parallaxScale * V.xy * initialHeight;',
-		'		return vUv - texCoordOffset;',
+			}
 
 
-		'	}',
+		#else
 
 
-		'#else',
+			vec2 parallaxMap( in vec3 V ) {
 
 
-		'	vec2 parallaxMap( in vec3 V ) {',
+				// Determine number of layers from angle between V and N
+				float numLayers = mix( parallaxMaxLayers, parallaxMinLayers, abs( dot( vec3( 0.0, 0.0, 1.0 ), V ) ) );
 
 
-		// Determine number of layers from angle between V and N
-		'		float numLayers = mix( parallaxMaxLayers, parallaxMinLayers, abs( dot( vec3( 0.0, 0.0, 1.0 ), V ) ) );',
+				float layerHeight = 1.0 / numLayers;
+				float currentLayerHeight = 0.0;
+				// Shift of texture coordinates for each iteration
+				vec2 dtex = parallaxScale * V.xy / V.z / numLayers;
 
 
-		'		float layerHeight = 1.0 / numLayers;',
-		'		float currentLayerHeight = 0.0;',
-		// Shift of texture coordinates for each iteration
-		'		vec2 dtex = parallaxScale * V.xy / V.z / numLayers;',
+				vec2 currentTextureCoords = vUv;
 
 
-		'		vec2 currentTextureCoords = vUv;',
+				float heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;
 
 
-		'		float heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;',
+				// while ( heightFromTexture > currentLayerHeight )
+				// Infinite loops are not well supported. Do a "large" finite
+				// loop, but not too large, as it slows down some compilers.
+				for ( int i = 0; i < 30; i += 1 ) {
+					if ( heightFromTexture <= currentLayerHeight ) {
+						break;
+					}
+					currentLayerHeight += layerHeight;
+					// Shift texture coordinates along vector V
+					currentTextureCoords -= dtex;
+					heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;
+				}
 
 
-		// while ( heightFromTexture > currentLayerHeight )
-		// Infinite loops are not well supported. Do a "large" finite
-		// loop, but not too large, as it slows down some compilers.
-		'		for ( int i = 0; i < 30; i += 1 ) {',
-		'			if ( heightFromTexture <= currentLayerHeight ) {',
-		'				break;',
-		'			}',
-		'			currentLayerHeight += layerHeight;',
-		// Shift texture coordinates along vector V
-		'			currentTextureCoords -= dtex;',
-		'			heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;',
-		'		}',
+				#ifdef USE_STEEP_PARALLAX
 
 
-		'		#ifdef USE_STEEP_PARALLAX',
+					return currentTextureCoords;
 
 
-		'			return currentTextureCoords;',
+				#elif defined( USE_RELIEF_PARALLAX )
 
 
-		'		#elif defined( USE_RELIEF_PARALLAX )',
+					vec2 deltaTexCoord = dtex / 2.0;
+					float deltaHeight = layerHeight / 2.0;
 
 
-		'			vec2 deltaTexCoord = dtex / 2.0;',
-		'			float deltaHeight = layerHeight / 2.0;',
+					// Return to the mid point of previous layer
+					currentTextureCoords += deltaTexCoord;
+					currentLayerHeight -= deltaHeight;
 
 
-		// Return to the mid point of previous layer
-		'			currentTextureCoords += deltaTexCoord;',
-		'			currentLayerHeight -= deltaHeight;',
+					// Binary search to increase precision of Steep Parallax Mapping
+					const int numSearches = 5;
+					for ( int i = 0; i < numSearches; i += 1 ) {
 
 
-		// Binary search to increase precision of Steep Parallax Mapping
-		'			const int numSearches = 5;',
-		'			for ( int i = 0; i < numSearches; i += 1 ) {',
+						deltaTexCoord /= 2.0;
+						deltaHeight /= 2.0;
+						heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;
+						// Shift along or against vector V
+						if( heightFromTexture > currentLayerHeight ) { // Below the surface
 
 
-		'				deltaTexCoord /= 2.0;',
-		'				deltaHeight /= 2.0;',
-		'				heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;',
-		// Shift along or against vector V
-		'				if( heightFromTexture > currentLayerHeight ) {', // Below the surface
+							currentTextureCoords -= deltaTexCoord;
+							currentLayerHeight += deltaHeight;
 
 
-		'					currentTextureCoords -= deltaTexCoord;',
-		'					currentLayerHeight += deltaHeight;',
+						} else { // above the surface
 
 
-		'				} else {', // above the surface
+							currentTextureCoords += deltaTexCoord;
+							currentLayerHeight -= deltaHeight;
 
 
-		'					currentTextureCoords += deltaTexCoord;',
-		'					currentLayerHeight -= deltaHeight;',
+						}
 
 
-		'				}',
+					}
+					return currentTextureCoords;
 
 
-		'			}',
-		'			return currentTextureCoords;',
+				#elif defined( USE_OCLUSION_PARALLAX )
 
 
-		'		#elif defined( USE_OCLUSION_PARALLAX )',
+					vec2 prevTCoords = currentTextureCoords + dtex;
 
 
-		'			vec2 prevTCoords = currentTextureCoords + dtex;',
+					// Heights for linear interpolation
+					float nextH = heightFromTexture - currentLayerHeight;
+					float prevH = texture2D( bumpMap, prevTCoords ).r - currentLayerHeight + layerHeight;
 
 
-		// Heights for linear interpolation
-		'			float nextH = heightFromTexture - currentLayerHeight;',
-		'			float prevH = texture2D( bumpMap, prevTCoords ).r - currentLayerHeight + layerHeight;',
+					// Proportions for linear interpolation
+					float weight = nextH / ( nextH - prevH );
 
 
-		// Proportions for linear interpolation
-		'			float weight = nextH / ( nextH - prevH );',
+					// Interpolation of texture coordinates
+					return prevTCoords * weight + currentTextureCoords * ( 1.0 - weight );
 
 
-		// Interpolation of texture coordinates
-		'			return prevTCoords * weight + currentTextureCoords * ( 1.0 - weight );',
+				#else // NO_PARALLAX
 
 
-		'		#else', // NO_PARALLAX
+					return vUv;
 
 
-		'			return vUv;',
+				#endif
 
 
-		'		#endif',
+			}
+		#endif
 
 
-		'	}',
-		'#endif',
+		vec2 perturbUv( vec3 surfPosition, vec3 surfNormal, vec3 viewPosition ) {
 
 
-		'vec2 perturbUv( vec3 surfPosition, vec3 surfNormal, vec3 viewPosition ) {',
+ 			vec2 texDx = dFdx( vUv );
+			vec2 texDy = dFdy( vUv );
 
 
- 		'	vec2 texDx = dFdx( vUv );',
-		'	vec2 texDy = dFdy( vUv );',
+			vec3 vSigmaX = dFdx( surfPosition );
+			vec3 vSigmaY = dFdy( surfPosition );
+			vec3 vR1 = cross( vSigmaY, surfNormal );
+			vec3 vR2 = cross( surfNormal, vSigmaX );
+			float fDet = dot( vSigmaX, vR1 );
 
 
-		'	vec3 vSigmaX = dFdx( surfPosition );',
-		'	vec3 vSigmaY = dFdy( surfPosition );',
-		'	vec3 vR1 = cross( vSigmaY, surfNormal );',
-		'	vec3 vR2 = cross( surfNormal, vSigmaX );',
-		'	float fDet = dot( vSigmaX, vR1 );',
+			vec2 vProjVscr = ( 1.0 / fDet ) * vec2( dot( vR1, viewPosition ), dot( vR2, viewPosition ) );
+			vec3 vProjVtex;
+			vProjVtex.xy = texDx * vProjVscr.x + texDy * vProjVscr.y;
+			vProjVtex.z = dot( surfNormal, viewPosition );
 
 
-		'	vec2 vProjVscr = ( 1.0 / fDet ) * vec2( dot( vR1, viewPosition ), dot( vR2, viewPosition ) );',
-		'	vec3 vProjVtex;',
-		'	vProjVtex.xy = texDx * vProjVscr.x + texDy * vProjVscr.y;',
-		'	vProjVtex.z = dot( surfNormal, viewPosition );',
+			return parallaxMap( vProjVtex );
+		}
 
 
-		'	return parallaxMap( vProjVtex );',
-		'}',
+		void main() {
 
 
-		'void main() {',
+			vec2 mapUv = perturbUv( -vViewPosition, normalize( vNormal ), normalize( vViewPosition ) );
+			gl_FragColor = texture2D( map, mapUv );
 
 
-		'	vec2 mapUv = perturbUv( -vViewPosition, normalize( vNormal ), normalize( vViewPosition ) );',
-		'	gl_FragColor = texture2D( map, mapUv );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 18 - 21
examples/jsm/shaders/PixelShader.js

@@ -2,46 +2,43 @@
  * Pixelation shader
  * Pixelation shader
  */
  */
 
 
-var PixelShader = {
+const PixelShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
 		'tDiffuse': { value: null },
 		'tDiffuse': { value: null },
 		'resolution': { value: null },
 		'resolution': { value: null },
-		'pixelSize': { value: 1. },
+		'pixelSize': { value: 1 },
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying highp vec2 vUv;',
+		`varying highp vec2 vUv;
 
 
-		'void main() {',
+			void main() {
 
 
-		'vUv = uv;',
-		'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+				vUv = uv;
+				gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform float pixelSize;
+		uniform vec2 resolution;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform float pixelSize;',
-		'uniform vec2 resolution;',
+		varying highp vec2 vUv;
 
 
-		'varying highp vec2 vUv;',
+		void main(){
 
 
-		'void main(){',
+			vec2 dxy = pixelSize / resolution;
+			vec2 coord = dxy * floor( vUv / dxy );
+			gl_FragColor = texture2D(tDiffuse, coord);
 
 
-		'vec2 dxy = pixelSize / resolution;',
-		'vec2 coord = dxy * floor( vUv / dxy );',
-		'gl_FragColor = texture2D(tDiffuse, coord);',
+		}`
 
 
-		'}'
-
-	].join( '\n' )
 };
 };
 
 
 export { PixelShader };
 export { PixelShader };

+ 19 - 23
examples/jsm/shaders/RGBShiftShader.js

@@ -8,7 +8,7 @@
  * angle: shift angle in radians
  * angle: shift angle in radians
  */
  */
 
 
-var RGBShiftShader = {
+const RGBShiftShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -18,38 +18,34 @@ var RGBShiftShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform float amount;
+		uniform float angle;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform float amount;',
-		'uniform float angle;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec2 offset = amount * vec2( cos(angle), sin(angle));
+			vec4 cr = texture2D(tDiffuse, vUv + offset);
+			vec4 cga = texture2D(tDiffuse, vUv);
+			vec4 cb = texture2D(tDiffuse, vUv - offset);
+			gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);
 
 
-		'	vec2 offset = amount * vec2( cos(angle), sin(angle));',
-		'	vec4 cr = texture2D(tDiffuse, vUv + offset);',
-		'	vec4 cga = texture2D(tDiffuse, vUv);',
-		'	vec4 cb = texture2D(tDiffuse, vUv - offset);',
-		'	gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 146 - 148
examples/jsm/shaders/SAOShader.js

@@ -7,7 +7,7 @@ import {
  * TODO
  * TODO
  */
  */
 
 
-var SAOShader = {
+const SAOShader = {
 	defines: {
 	defines: {
 		'NUM_SAMPLES': 7,
 		'NUM_SAMPLES': 7,
 		'NUM_RINGS': 4,
 		'NUM_RINGS': 4,
@@ -36,153 +36,151 @@ var SAOShader = {
 		'kernelRadius': { value: 100.0 },
 		'kernelRadius': { value: 100.0 },
 		'randomSeed': { value: 0.0 }
 		'randomSeed': { value: 0.0 }
 	},
 	},
-	vertexShader: [
-		'varying vec2 vUv;',
-
-		'void main() {',
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
-		'}'
-
-	].join( '\n' ),
-	fragmentShader: [
-		'#include <common>',
-
-		'varying vec2 vUv;',
-
-		'#if DIFFUSE_TEXTURE == 1',
-		'uniform sampler2D tDiffuse;',
-		'#endif',
-
-		'uniform sampler2D tDepth;',
-
-		'#if NORMAL_TEXTURE == 1',
-		'uniform sampler2D tNormal;',
-		'#endif',
-
-		'uniform float cameraNear;',
-		'uniform float cameraFar;',
-		'uniform mat4 cameraProjectionMatrix;',
-		'uniform mat4 cameraInverseProjectionMatrix;',
-
-		'uniform float scale;',
-		'uniform float intensity;',
-		'uniform float bias;',
-		'uniform float kernelRadius;',
-		'uniform float minResolution;',
-		'uniform vec2 size;',
-		'uniform float randomSeed;',
-
-		'// RGBA depth',
-
-		'#include <packing>',
-
-		'vec4 getDefaultColor( const in vec2 screenPosition ) {',
-		'	#if DIFFUSE_TEXTURE == 1',
-		'	return texture2D( tDiffuse, vUv );',
-		'	#else',
-		'	return vec4( 1.0 );',
-		'	#endif',
-		'}',
-
-		'float getDepth( const in vec2 screenPosition ) {',
-		'	#if DEPTH_PACKING == 1',
-		'	return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );',
-		'	#else',
-		'	return texture2D( tDepth, screenPosition ).x;',
-		'	#endif',
-		'}',
-
-		'float getViewZ( const in float depth ) {',
-		'	#if PERSPECTIVE_CAMERA == 1',
-		'	return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );',
-		'	#else',
-		'	return orthographicDepthToViewZ( depth, cameraNear, cameraFar );',
-		'	#endif',
-		'}',
-
-		'vec3 getViewPosition( const in vec2 screenPosition, const in float depth, const in float viewZ ) {',
-		'	float clipW = cameraProjectionMatrix[2][3] * viewZ + cameraProjectionMatrix[3][3];',
-		'	vec4 clipPosition = vec4( ( vec3( screenPosition, depth ) - 0.5 ) * 2.0, 1.0 );',
-		'	clipPosition *= clipW; // unprojection.',
-
-		'	return ( cameraInverseProjectionMatrix * clipPosition ).xyz;',
-		'}',
-
-		'vec3 getViewNormal( const in vec3 viewPosition, const in vec2 screenPosition ) {',
-		'	#if NORMAL_TEXTURE == 1',
-		'	return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );',
-		'	#else',
-		'	return normalize( cross( dFdx( viewPosition ), dFdy( viewPosition ) ) );',
-		'	#endif',
-		'}',
-
-		'float scaleDividedByCameraFar;',
-		'float minResolutionMultipliedByCameraFar;',
-
-		'float getOcclusion( const in vec3 centerViewPosition, const in vec3 centerViewNormal, const in vec3 sampleViewPosition ) {',
-		'	vec3 viewDelta = sampleViewPosition - centerViewPosition;',
-		'	float viewDistance = length( viewDelta );',
-		'	float scaledScreenDistance = scaleDividedByCameraFar * viewDistance;',
-
-		'	return max(0.0, (dot(centerViewNormal, viewDelta) - minResolutionMultipliedByCameraFar) / scaledScreenDistance - bias) / (1.0 + pow2( scaledScreenDistance ) );',
-		'}',
-
-		'// moving costly divides into consts',
-		'const float ANGLE_STEP = PI2 * float( NUM_RINGS ) / float( NUM_SAMPLES );',
-		'const float INV_NUM_SAMPLES = 1.0 / float( NUM_SAMPLES );',
-
-		'float getAmbientOcclusion( const in vec3 centerViewPosition ) {',
-		'	// precompute some variables require in getOcclusion.',
-		'	scaleDividedByCameraFar = scale / cameraFar;',
-		'	minResolutionMultipliedByCameraFar = minResolution * cameraFar;',
-		'	vec3 centerViewNormal = getViewNormal( centerViewPosition, vUv );',
-
-		'	// jsfiddle that shows sample pattern: https://jsfiddle.net/a16ff1p7/',
-		'	float angle = rand( vUv + randomSeed ) * PI2;',
-		'	vec2 radius = vec2( kernelRadius * INV_NUM_SAMPLES ) / size;',
-		'	vec2 radiusStep = radius;',
-
-		'	float occlusionSum = 0.0;',
-		'	float weightSum = 0.0;',
-
-		'	for( int i = 0; i < NUM_SAMPLES; i ++ ) {',
-		'		vec2 sampleUv = vUv + vec2( cos( angle ), sin( angle ) ) * radius;',
-		'		radius += radiusStep;',
-		'		angle += ANGLE_STEP;',
-
-		'		float sampleDepth = getDepth( sampleUv );',
-		'		if( sampleDepth >= ( 1.0 - EPSILON ) ) {',
-		'			continue;',
-		'		}',
-
-		'		float sampleViewZ = getViewZ( sampleDepth );',
-		'		vec3 sampleViewPosition = getViewPosition( sampleUv, sampleDepth, sampleViewZ );',
-		'		occlusionSum += getOcclusion( centerViewPosition, centerViewNormal, sampleViewPosition );',
-		'		weightSum += 1.0;',
-		'	}',
-
-		'	if( weightSum == 0.0 ) discard;',
-
-		'	return occlusionSum * ( intensity / weightSum );',
-		'}',
-
-
-		'void main() {',
-		'	float centerDepth = getDepth( vUv );',
-		'	if( centerDepth >= ( 1.0 - EPSILON ) ) {',
-		'		discard;',
-		'	}',
-
-		'	float centerViewZ = getViewZ( centerDepth );',
-		'	vec3 viewPosition = getViewPosition( vUv, centerDepth, centerViewZ );',
-
-		'	float ambientOcclusion = getAmbientOcclusion( viewPosition );',
-
-		'	gl_FragColor = getDefaultColor( vUv );',
-		'	gl_FragColor.xyz *=  1.0 - ambientOcclusion;',
-		'}'
-	].join( '\n' )
+	vertexShader:
+		`varying vec2 vUv;
+
+		void main() {
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+		}`,
+
+	fragmentShader:
+		`#include <common>
+
+		varying vec2 vUv;
+
+		#if DIFFUSE_TEXTURE == 1
+		uniform sampler2D tDiffuse;
+		#endif
+
+		uniform sampler2D tDepth;
+
+		#if NORMAL_TEXTURE == 1
+		uniform sampler2D tNormal;
+		#endif
+
+		uniform float cameraNear;
+		uniform float cameraFar;
+		uniform mat4 cameraProjectionMatrix;
+		uniform mat4 cameraInverseProjectionMatrix;
+
+		uniform float scale;
+		uniform float intensity;
+		uniform float bias;
+		uniform float kernelRadius;
+		uniform float minResolution;
+		uniform vec2 size;
+		uniform float randomSeed;
+
+		// RGBA depth
+
+		#include <packing>
+
+		vec4 getDefaultColor( const in vec2 screenPosition ) {
+			#if DIFFUSE_TEXTURE == 1
+			return texture2D( tDiffuse, vUv );
+			#else
+			return vec4( 1.0 );
+			#endif
+		}
+
+		float getDepth( const in vec2 screenPosition ) {
+			#if DEPTH_PACKING == 1
+			return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );
+			#else
+			return texture2D( tDepth, screenPosition ).x;
+			#endif
+		}
+
+		float getViewZ( const in float depth ) {
+			#if PERSPECTIVE_CAMERA == 1
+			return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );
+			#else
+			return orthographicDepthToViewZ( depth, cameraNear, cameraFar );
+			#endif
+		}
+
+		vec3 getViewPosition( const in vec2 screenPosition, const in float depth, const in float viewZ ) {
+			float clipW = cameraProjectionMatrix[2][3] * viewZ + cameraProjectionMatrix[3][3];
+			vec4 clipPosition = vec4( ( vec3( screenPosition, depth ) - 0.5 ) * 2.0, 1.0 );
+			clipPosition *= clipW; // unprojection.
+
+			return ( cameraInverseProjectionMatrix * clipPosition ).xyz;
+		}
+
+		vec3 getViewNormal( const in vec3 viewPosition, const in vec2 screenPosition ) {
+			#if NORMAL_TEXTURE == 1
+			return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );
+			#else
+			return normalize( cross( dFdx( viewPosition ), dFdy( viewPosition ) ) );
+			#endif
+		}
+
+		float scaleDividedByCameraFar;
+		float minResolutionMultipliedByCameraFar;
+
+		float getOcclusion( const in vec3 centerViewPosition, const in vec3 centerViewNormal, const in vec3 sampleViewPosition ) {
+			vec3 viewDelta = sampleViewPosition - centerViewPosition;
+			float viewDistance = length( viewDelta );
+			float scaledScreenDistance = scaleDividedByCameraFar * viewDistance;
+
+			return max(0.0, (dot(centerViewNormal, viewDelta) - minResolutionMultipliedByCameraFar) / scaledScreenDistance - bias) / (1.0 + pow2( scaledScreenDistance ) );
+		}
+
+		// moving costly divides into consts
+		const float ANGLE_STEP = PI2 * float( NUM_RINGS ) / float( NUM_SAMPLES );
+		const float INV_NUM_SAMPLES = 1.0 / float( NUM_SAMPLES );
+
+		float getAmbientOcclusion( const in vec3 centerViewPosition ) {
+			// precompute some variables require in getOcclusion.
+			scaleDividedByCameraFar = scale / cameraFar;
+			minResolutionMultipliedByCameraFar = minResolution * cameraFar;
+			vec3 centerViewNormal = getViewNormal( centerViewPosition, vUv );
+
+			// jsfiddle that shows sample pattern: https://jsfiddle.net/a16ff1p7/
+			float angle = rand( vUv + randomSeed ) * PI2;
+			vec2 radius = vec2( kernelRadius * INV_NUM_SAMPLES ) / size;
+			vec2 radiusStep = radius;
+
+			float occlusionSum = 0.0;
+			float weightSum = 0.0;
+
+			for( int i = 0; i < NUM_SAMPLES; i ++ ) {
+				vec2 sampleUv = vUv + vec2( cos( angle ), sin( angle ) ) * radius;
+				radius += radiusStep;
+				angle += ANGLE_STEP;
+
+				float sampleDepth = getDepth( sampleUv );
+				if( sampleDepth >= ( 1.0 - EPSILON ) ) {
+					continue;
+				}
+
+				float sampleViewZ = getViewZ( sampleDepth );
+				vec3 sampleViewPosition = getViewPosition( sampleUv, sampleDepth, sampleViewZ );
+				occlusionSum += getOcclusion( centerViewPosition, centerViewNormal, sampleViewPosition );
+				weightSum += 1.0;
+			}
+
+			if( weightSum == 0.0 ) discard;
+
+			return occlusionSum * ( intensity / weightSum );
+		}
+
+		void main() {
+			float centerDepth = getDepth( vUv );
+			if( centerDepth >= ( 1.0 - EPSILON ) ) {
+				discard;
+			}
+
+			float centerViewZ = getViewZ( centerDepth );
+			vec3 viewPosition = getViewPosition( vUv, centerDepth, centerViewZ );
+
+			float ambientOcclusion = getAmbientOcclusion( viewPosition );
+
+			gl_FragColor = getDefaultColor( vUv );
+			gl_FragColor.xyz *=  1.0 - ambientOcclusion;
+		}`
+
 };
 };
 
 
 export { SAOShader };
 export { SAOShader };

+ 288 - 300
examples/jsm/shaders/SMAAShader.js

@@ -8,7 +8,7 @@ import {
  * https://github.com/iryoku/smaa/releases/tag/v2.8
  * https://github.com/iryoku/smaa/releases/tag/v2.8
  */
  */
 
 
-var SMAAEdgesShader = {
+const SMAAEdgesShader = {
 
 
 	defines: {
 	defines: {
 
 
@@ -23,101 +23,97 @@ var SMAAEdgesShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'uniform vec2 resolution;',
+		`uniform vec2 resolution;
 
 
-		'varying vec2 vUv;',
-		'varying vec4 vOffset[ 3 ];',
+		varying vec2 vUv;
+		varying vec4 vOffset[ 3 ];
 
 
-		'void SMAAEdgeDetectionVS( vec2 texcoord ) {',
-		'	vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0,  1.0 );', // WebGL port note: Changed sign in W component
-		'	vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4(  1.0, 0.0, 0.0, -1.0 );', // WebGL port note: Changed sign in W component
-		'	vOffset[ 2 ] = texcoord.xyxy + resolution.xyxy * vec4( -2.0, 0.0, 0.0,  2.0 );', // WebGL port note: Changed sign in W component
-		'}',
+		void SMAAEdgeDetectionVS( vec2 texcoord ) {
+			vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0,  1.0 ); // WebGL port note: Changed sign in W component
+			vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4(  1.0, 0.0, 0.0, -1.0 ); // WebGL port note: Changed sign in W component
+			vOffset[ 2 ] = texcoord.xyxy + resolution.xyxy * vec4( -2.0, 0.0, 0.0,  2.0 ); // WebGL port note: Changed sign in W component
+		}
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
+			vUv = uv;
 
 
-		'	SMAAEdgeDetectionVS( vUv );',
+			SMAAEdgeDetectionVS( vUv );
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
+		varying vec4 vOffset[ 3 ];
 
 
-		'varying vec2 vUv;',
-		'varying vec4 vOffset[ 3 ];',
+		vec4 SMAAColorEdgeDetectionPS( vec2 texcoord, vec4 offset[3], sampler2D colorTex ) {
+			vec2 threshold = vec2( SMAA_THRESHOLD, SMAA_THRESHOLD );
 
 
-		'vec4 SMAAColorEdgeDetectionPS( vec2 texcoord, vec4 offset[3], sampler2D colorTex ) {',
-		'	vec2 threshold = vec2( SMAA_THRESHOLD, SMAA_THRESHOLD );',
+			// Calculate color deltas:
+			vec4 delta;
+			vec3 C = texture2D( colorTex, texcoord ).rgb;
 
 
-		// Calculate color deltas:
-		'	vec4 delta;',
-		'	vec3 C = texture2D( colorTex, texcoord ).rgb;',
+			vec3 Cleft = texture2D( colorTex, offset[0].xy ).rgb;
+			vec3 t = abs( C - Cleft );
+			delta.x = max( max( t.r, t.g ), t.b );
 
 
-		'	vec3 Cleft = texture2D( colorTex, offset[0].xy ).rgb;',
-		'	vec3 t = abs( C - Cleft );',
-		'	delta.x = max( max( t.r, t.g ), t.b );',
+			vec3 Ctop = texture2D( colorTex, offset[0].zw ).rgb;
+			t = abs( C - Ctop );
+			delta.y = max( max( t.r, t.g ), t.b );
 
 
-		'	vec3 Ctop = texture2D( colorTex, offset[0].zw ).rgb;',
-		'	t = abs( C - Ctop );',
-		'	delta.y = max( max( t.r, t.g ), t.b );',
+			// We do the usual threshold:
+			vec2 edges = step( threshold, delta.xy );
 
 
-		// We do the usual threshold:
-		'	vec2 edges = step( threshold, delta.xy );',
+			// Then discard if there is no edge:
+			if ( dot( edges, vec2( 1.0, 1.0 ) ) == 0.0 )
+				discard;
 
 
-		// Then discard if there is no edge:
-		'	if ( dot( edges, vec2( 1.0, 1.0 ) ) == 0.0 )',
-		'		discard;',
+			// Calculate right and bottom deltas:
+			vec3 Cright = texture2D( colorTex, offset[1].xy ).rgb;
+			t = abs( C - Cright );
+			delta.z = max( max( t.r, t.g ), t.b );
 
 
-		// Calculate right and bottom deltas:
-		'	vec3 Cright = texture2D( colorTex, offset[1].xy ).rgb;',
-		'	t = abs( C - Cright );',
-		'	delta.z = max( max( t.r, t.g ), t.b );',
+			vec3 Cbottom  = texture2D( colorTex, offset[1].zw ).rgb;
+			t = abs( C - Cbottom );
+			delta.w = max( max( t.r, t.g ), t.b );
 
 
-		'	vec3 Cbottom  = texture2D( colorTex, offset[1].zw ).rgb;',
-		'	t = abs( C - Cbottom );',
-		'	delta.w = max( max( t.r, t.g ), t.b );',
+			// Calculate the maximum delta in the direct neighborhood:
+			float maxDelta = max( max( max( delta.x, delta.y ), delta.z ), delta.w );
 
 
-		// Calculate the maximum delta in the direct neighborhood:
-		'	float maxDelta = max( max( max( delta.x, delta.y ), delta.z ), delta.w );',
+			// Calculate left-left and top-top deltas:
+			vec3 Cleftleft  = texture2D( colorTex, offset[2].xy ).rgb;
+			t = abs( C - Cleftleft );
+			delta.z = max( max( t.r, t.g ), t.b );
 
 
-		// Calculate left-left and top-top deltas:
-		'	vec3 Cleftleft  = texture2D( colorTex, offset[2].xy ).rgb;',
-		'	t = abs( C - Cleftleft );',
-		'	delta.z = max( max( t.r, t.g ), t.b );',
+			vec3 Ctoptop = texture2D( colorTex, offset[2].zw ).rgb;
+			t = abs( C - Ctoptop );
+			delta.w = max( max( t.r, t.g ), t.b );
 
 
-		'	vec3 Ctoptop = texture2D( colorTex, offset[2].zw ).rgb;',
-		'	t = abs( C - Ctoptop );',
-		'	delta.w = max( max( t.r, t.g ), t.b );',
+			// Calculate the final maximum delta:
+			maxDelta = max( max( maxDelta, delta.z ), delta.w );
 
 
-		// Calculate the final maximum delta:
-		'	maxDelta = max( max( maxDelta, delta.z ), delta.w );',
+			// Local contrast adaptation in action:
+			edges.xy *= step( 0.5 * maxDelta, delta.xy );
 
 
-		// Local contrast adaptation in action:
-		'	edges.xy *= step( 0.5 * maxDelta, delta.xy );',
+			return vec4( edges, 0.0, 0.0 );
+		}
 
 
-		'	return vec4( edges, 0.0, 0.0 );',
-		'}',
+		void main() {
 
 
-		'void main() {',
+			gl_FragColor = SMAAColorEdgeDetectionPS( vUv, vOffset, tDiffuse );
 
 
-		'	gl_FragColor = SMAAColorEdgeDetectionPS( vUv, vOffset, tDiffuse );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 
-var SMAAWeightsShader = {
+const SMAAWeightsShader = {
 
 
 	defines: {
 	defines: {
 
 
@@ -137,245 +133,241 @@ var SMAAWeightsShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
-
-		'uniform vec2 resolution;',
+	vertexShader:
 
 
-		'varying vec2 vUv;',
-		'varying vec4 vOffset[ 3 ];',
-		'varying vec2 vPixcoord;',
+		`uniform vec2 resolution;
 
 
-		'void SMAABlendingWeightCalculationVS( vec2 texcoord ) {',
-		'	vPixcoord = texcoord / resolution;',
+		varying vec2 vUv;
+		varying vec4 vOffset[ 3 ];
+		varying vec2 vPixcoord;
 
 
-		// We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
-		'	vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.25, 0.125, 1.25, 0.125 );', // WebGL port note: Changed sign in Y and W components
-		'	vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.125, 0.25, -0.125, -1.25 );', // WebGL port note: Changed sign in Y and W components
+		void SMAABlendingWeightCalculationVS( vec2 texcoord ) {
+			vPixcoord = texcoord / resolution;
 
 
-		// And these for the searches, they indicate the ends of the loops:
-		'	vOffset[ 2 ] = vec4( vOffset[ 0 ].xz, vOffset[ 1 ].yw ) + vec4( -2.0, 2.0, -2.0, 2.0 ) * resolution.xxyy * float( SMAA_MAX_SEARCH_STEPS );',
+			// We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
+			vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.25, 0.125, 1.25, 0.125 ); // WebGL port note: Changed sign in Y and W components
+			vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.125, 0.25, -0.125, -1.25 ); // WebGL port note: Changed sign in Y and W components
 
 
-		'}',
+			// And these for the searches, they indicate the ends of the loops:
+			vOffset[ 2 ] = vec4( vOffset[ 0 ].xz, vOffset[ 1 ].yw ) + vec4( -2.0, 2.0, -2.0, 2.0 ) * resolution.xxyy * float( SMAA_MAX_SEARCH_STEPS );
 
 
-		'void main() {',
+		}
 
 
-		'	vUv = uv;',
+		void main() {
 
 
-		'	SMAABlendingWeightCalculationVS( vUv );',
+			vUv = uv;
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			SMAABlendingWeightCalculationVS( vUv );
 
 
-		'}'
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-	].join( '\n' ),
+		}`,
 
 
-	fragmentShader: [
+	fragmentShader:
 
 
-		'#define SMAASampleLevelZeroOffset( tex, coord, offset ) texture2D( tex, coord + float( offset ) * resolution, 0.0 )',
+		`#define SMAASampleLevelZeroOffset( tex, coord, offset ) texture2D( tex, coord + float( offset ) * resolution, 0.0 )
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform sampler2D tArea;',
-		'uniform sampler2D tSearch;',
-		'uniform vec2 resolution;',
+		uniform sampler2D tDiffuse;
+		uniform sampler2D tArea;
+		uniform sampler2D tSearch;
+		uniform vec2 resolution;
 
 
-		'varying vec2 vUv;',
-		'varying vec4 vOffset[3];',
-		'varying vec2 vPixcoord;',
+		varying vec2 vUv;
+		varying vec4 vOffset[3];
+		varying vec2 vPixcoord;
 
 
-		'#if __VERSION__ == 100',
-		'vec2 round( vec2 x ) {',
-		'	return sign( x ) * floor( abs( x ) + 0.5 );',
-		'}',
-		'#endif',
+		#if __VERSION__ == 100
+		vec2 round( vec2 x ) {
+			return sign( x ) * floor( abs( x ) + 0.5 );
+		}
+		#endif
 
 
-		'float SMAASearchLength( sampler2D searchTex, vec2 e, float bias, float scale ) {',
-		// Not required if searchTex accesses are set to point:
-		// float2 SEARCH_TEX_PIXEL_SIZE = 1.0 / float2(66.0, 33.0);
-		// e = float2(bias, 0.0) + 0.5 * SEARCH_TEX_PIXEL_SIZE +
-		//     e * float2(scale, 1.0) * float2(64.0, 32.0) * SEARCH_TEX_PIXEL_SIZE;
-		'	e.r = bias + e.r * scale;',
-		'	return 255.0 * texture2D( searchTex, e, 0.0 ).r;',
-		'}',
+		float SMAASearchLength( sampler2D searchTex, vec2 e, float bias, float scale ) {
+			// Not required if searchTex accesses are set to point:
+			// float2 SEARCH_TEX_PIXEL_SIZE = 1.0 / float2(66.0, 33.0);
+			// e = float2(bias, 0.0) + 0.5 * SEARCH_TEX_PIXEL_SIZE +
+			//     e * float2(scale, 1.0) * float2(64.0, 32.0) * SEARCH_TEX_PIXEL_SIZE;
+			e.r = bias + e.r * scale;
+			return 255.0 * texture2D( searchTex, e, 0.0 ).r;
+		}
 
 
-		'float SMAASearchXLeft( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {',
-		/**
-			* @PSEUDO_GATHER4
-			* This texcoord has been offset by (-0.25, -0.125) in the vertex shader to
-			* sample between edge, thus fetching four edges in a row.
-			* Sampling with different offsets in each direction allows to disambiguate
-			* which edges are active from the four fetched ones.
-			*/
-		'	vec2 e = vec2( 0.0, 1.0 );',
+		float SMAASearchXLeft( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {
+			/**
+				* @PSEUDO_GATHER4
+				* This texcoord has been offset by (-0.25, -0.125) in the vertex shader to
+				* sample between edge, thus fetching four edges in a row.
+				* Sampling with different offsets in each direction allows to disambiguate
+				* which edges are active from the four fetched ones.
+				*/
+			vec2 e = vec2( 0.0, 1.0 );
 
 
-		'	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {', // WebGL port note: Changed while to for
-		'		e = texture2D( edgesTex, texcoord, 0.0 ).rg;',
-		'		texcoord -= vec2( 2.0, 0.0 ) * resolution;',
-		'		if ( ! ( texcoord.x > end && e.g > 0.8281 && e.r == 0.0 ) ) break;',
-		'	}',
+			for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) { // WebGL port note: Changed while to for
+				e = texture2D( edgesTex, texcoord, 0.0 ).rg;
+				texcoord -= vec2( 2.0, 0.0 ) * resolution;
+				if ( ! ( texcoord.x > end && e.g > 0.8281 && e.r == 0.0 ) ) break;
+			}
 
 
-		// We correct the previous (-0.25, -0.125) offset we applied:
-		'	texcoord.x += 0.25 * resolution.x;',
+			// We correct the previous (-0.25, -0.125) offset we applied:
+			texcoord.x += 0.25 * resolution.x;
 
 
-		// The searches are bias by 1, so adjust the coords accordingly:
-		'	texcoord.x += resolution.x;',
+			// The searches are bias by 1, so adjust the coords accordingly:
+			texcoord.x += resolution.x;
 
 
-		// Disambiguate the length added by the last step:
-		'	texcoord.x += 2.0 * resolution.x;', // Undo last step
-		'	texcoord.x -= resolution.x * SMAASearchLength(searchTex, e, 0.0, 0.5);',
+			// Disambiguate the length added by the last step:
+			texcoord.x += 2.0 * resolution.x; // Undo last step
+			texcoord.x -= resolution.x * SMAASearchLength(searchTex, e, 0.0, 0.5);
 
 
-		'	return texcoord.x;',
-		'}',
+			return texcoord.x;
+		}
 
 
-		'float SMAASearchXRight( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {',
-		'	vec2 e = vec2( 0.0, 1.0 );',
+		float SMAASearchXRight( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {
+			vec2 e = vec2( 0.0, 1.0 );
 
 
-		'	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {', // WebGL port note: Changed while to for
-		'		e = texture2D( edgesTex, texcoord, 0.0 ).rg;',
-		'		texcoord += vec2( 2.0, 0.0 ) * resolution;',
-		'		if ( ! ( texcoord.x < end && e.g > 0.8281 && e.r == 0.0 ) ) break;',
-		'	}',
+			for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) { // WebGL port note: Changed while to for
+				e = texture2D( edgesTex, texcoord, 0.0 ).rg;
+				texcoord += vec2( 2.0, 0.0 ) * resolution;
+				if ( ! ( texcoord.x < end && e.g > 0.8281 && e.r == 0.0 ) ) break;
+			}
 
 
-		'	texcoord.x -= 0.25 * resolution.x;',
-		'	texcoord.x -= resolution.x;',
-		'	texcoord.x -= 2.0 * resolution.x;',
-		'	texcoord.x += resolution.x * SMAASearchLength( searchTex, e, 0.5, 0.5 );',
+			texcoord.x -= 0.25 * resolution.x;
+			texcoord.x -= resolution.x;
+			texcoord.x -= 2.0 * resolution.x;
+			texcoord.x += resolution.x * SMAASearchLength( searchTex, e, 0.5, 0.5 );
 
 
-		'	return texcoord.x;',
-		'}',
+			return texcoord.x;
+		}
 
 
-		'float SMAASearchYUp( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {',
-		'	vec2 e = vec2( 1.0, 0.0 );',
+		float SMAASearchYUp( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {
+			vec2 e = vec2( 1.0, 0.0 );
 
 
-		'	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {', // WebGL port note: Changed while to for
-		'		e = texture2D( edgesTex, texcoord, 0.0 ).rg;',
-		'		texcoord += vec2( 0.0, 2.0 ) * resolution;', // WebGL port note: Changed sign
-		'		if ( ! ( texcoord.y > end && e.r > 0.8281 && e.g == 0.0 ) ) break;',
-		'	}',
+			for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) { // WebGL port note: Changed while to for
+				e = texture2D( edgesTex, texcoord, 0.0 ).rg;
+				texcoord += vec2( 0.0, 2.0 ) * resolution; // WebGL port note: Changed sign
+				if ( ! ( texcoord.y > end && e.r > 0.8281 && e.g == 0.0 ) ) break;
+			}
 
 
-		'	texcoord.y -= 0.25 * resolution.y;', // WebGL port note: Changed sign
-		'	texcoord.y -= resolution.y;', // WebGL port note: Changed sign
-		'	texcoord.y -= 2.0 * resolution.y;', // WebGL port note: Changed sign
-		'	texcoord.y += resolution.y * SMAASearchLength( searchTex, e.gr, 0.0, 0.5 );', // WebGL port note: Changed sign
+			texcoord.y -= 0.25 * resolution.y; // WebGL port note: Changed sign
+			texcoord.y -= resolution.y; // WebGL port note: Changed sign
+			texcoord.y -= 2.0 * resolution.y; // WebGL port note: Changed sign
+			texcoord.y += resolution.y * SMAASearchLength( searchTex, e.gr, 0.0, 0.5 ); // WebGL port note: Changed sign
 
 
-		'	return texcoord.y;',
-		'}',
+			return texcoord.y;
+		}
 
 
-		'float SMAASearchYDown( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {',
-		'	vec2 e = vec2( 1.0, 0.0 );',
+		float SMAASearchYDown( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {
+			vec2 e = vec2( 1.0, 0.0 );
 
 
-		'	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {', // WebGL port note: Changed while to for
-		'		e = texture2D( edgesTex, texcoord, 0.0 ).rg;',
-		'		texcoord -= vec2( 0.0, 2.0 ) * resolution;', // WebGL port note: Changed sign
-		'		if ( ! ( texcoord.y < end && e.r > 0.8281 && e.g == 0.0 ) ) break;',
-		'	}',
+			for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) { // WebGL port note: Changed while to for
+				e = texture2D( edgesTex, texcoord, 0.0 ).rg;
+				texcoord -= vec2( 0.0, 2.0 ) * resolution; // WebGL port note: Changed sign
+				if ( ! ( texcoord.y < end && e.r > 0.8281 && e.g == 0.0 ) ) break;
+			}
 
 
-		'	texcoord.y += 0.25 * resolution.y;', // WebGL port note: Changed sign
-		'	texcoord.y += resolution.y;', // WebGL port note: Changed sign
-		'	texcoord.y += 2.0 * resolution.y;', // WebGL port note: Changed sign
-		'	texcoord.y -= resolution.y * SMAASearchLength( searchTex, e.gr, 0.5, 0.5 );', // WebGL port note: Changed sign
+			texcoord.y += 0.25 * resolution.y; // WebGL port note: Changed sign
+			texcoord.y += resolution.y; // WebGL port note: Changed sign
+			texcoord.y += 2.0 * resolution.y; // WebGL port note: Changed sign
+			texcoord.y -= resolution.y * SMAASearchLength( searchTex, e.gr, 0.5, 0.5 ); // WebGL port note: Changed sign
 
 
-		'	return texcoord.y;',
-		'}',
+			return texcoord.y;
+		}
 
 
-		'vec2 SMAAArea( sampler2D areaTex, vec2 dist, float e1, float e2, float offset ) {',
-		// Rounding prevents precision errors of bilinear filtering:
-		'	vec2 texcoord = float( SMAA_AREATEX_MAX_DISTANCE ) * round( 4.0 * vec2( e1, e2 ) ) + dist;',
+		vec2 SMAAArea( sampler2D areaTex, vec2 dist, float e1, float e2, float offset ) {
+			// Rounding prevents precision errors of bilinear filtering:
+			vec2 texcoord = float( SMAA_AREATEX_MAX_DISTANCE ) * round( 4.0 * vec2( e1, e2 ) ) + dist;
 
 
-		// We do a scale and bias for mapping to texel space:
-		'	texcoord = SMAA_AREATEX_PIXEL_SIZE * texcoord + ( 0.5 * SMAA_AREATEX_PIXEL_SIZE );',
+			// We do a scale and bias for mapping to texel space:
+			texcoord = SMAA_AREATEX_PIXEL_SIZE * texcoord + ( 0.5 * SMAA_AREATEX_PIXEL_SIZE );
 
 
-		// Move to proper place, according to the subpixel offset:
-		'	texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset;',
+			// Move to proper place, according to the subpixel offset:
+			texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset;
 
 
-		'	return texture2D( areaTex, texcoord, 0.0 ).rg;',
-		'}',
+			return texture2D( areaTex, texcoord, 0.0 ).rg;
+		}
 
 
-		'vec4 SMAABlendingWeightCalculationPS( vec2 texcoord, vec2 pixcoord, vec4 offset[ 3 ], sampler2D edgesTex, sampler2D areaTex, sampler2D searchTex, ivec4 subsampleIndices ) {',
-		'	vec4 weights = vec4( 0.0, 0.0, 0.0, 0.0 );',
+		vec4 SMAABlendingWeightCalculationPS( vec2 texcoord, vec2 pixcoord, vec4 offset[ 3 ], sampler2D edgesTex, sampler2D areaTex, sampler2D searchTex, ivec4 subsampleIndices ) {
+			vec4 weights = vec4( 0.0, 0.0, 0.0, 0.0 );
 
 
-		'	vec2 e = texture2D( edgesTex, texcoord ).rg;',
+			vec2 e = texture2D( edgesTex, texcoord ).rg;
 
 
-		'	if ( e.g > 0.0 ) {', // Edge at north
-		'		vec2 d;',
+			if ( e.g > 0.0 ) { // Edge at north
+				vec2 d;
 
 
-		// Find the distance to the left:
-		'		vec2 coords;',
-		'		coords.x = SMAASearchXLeft( edgesTex, searchTex, offset[ 0 ].xy, offset[ 2 ].x );',
-		'		coords.y = offset[ 1 ].y;', // offset[1].y = texcoord.y - 0.25 * resolution.y (@CROSSING_OFFSET)
-		'		d.x = coords.x;',
+				// Find the distance to the left:
+				vec2 coords;
+				coords.x = SMAASearchXLeft( edgesTex, searchTex, offset[ 0 ].xy, offset[ 2 ].x );
+				coords.y = offset[ 1 ].y; // offset[1].y = texcoord.y - 0.25 * resolution.y (@CROSSING_OFFSET)
+				d.x = coords.x;
 
 
-		// Now fetch the left crossing edges, two at a time using bilinear
-		// filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to
-		// discern what value each edge has:
-		'		float e1 = texture2D( edgesTex, coords, 0.0 ).r;',
+				// Now fetch the left crossing edges, two at a time using bilinear
+				// filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to
+				// discern what value each edge has:
+				float e1 = texture2D( edgesTex, coords, 0.0 ).r;
 
 
-		// Find the distance to the right:
-		'		coords.x = SMAASearchXRight( edgesTex, searchTex, offset[ 0 ].zw, offset[ 2 ].y );',
-		'		d.y = coords.x;',
+				// Find the distance to the right:
+				coords.x = SMAASearchXRight( edgesTex, searchTex, offset[ 0 ].zw, offset[ 2 ].y );
+				d.y = coords.x;
 
 
-		// We want the distances to be in pixel units (doing this here allow to
-		// better interleave arithmetic and memory accesses):
-		'		d = d / resolution.x - pixcoord.x;',
+				// We want the distances to be in pixel units (doing this here allow to
+				// better interleave arithmetic and memory accesses):
+				d = d / resolution.x - pixcoord.x;
 
 
-		// SMAAArea below needs a sqrt, as the areas texture is compressed
-		// quadratically:
-		'		vec2 sqrt_d = sqrt( abs( d ) );',
+				// SMAAArea below needs a sqrt, as the areas texture is compressed
+				// quadratically:
+				vec2 sqrt_d = sqrt( abs( d ) );
 
 
-		// Fetch the right crossing edges:
-		'		coords.y -= 1.0 * resolution.y;', // WebGL port note: Added
-		'		float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 1, 0 ) ).r;',
+				// Fetch the right crossing edges:
+				coords.y -= 1.0 * resolution.y; // WebGL port note: Added
+				float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 1, 0 ) ).r;
 
 
-		// Ok, we know how this pattern looks like, now it is time for getting
-		// the actual area:
-		'		weights.rg = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.y ) );',
-		'	}',
+				// Ok, we know how this pattern looks like, now it is time for getting
+				// the actual area:
+				weights.rg = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.y ) );
+			}
 
 
-		'	if ( e.r > 0.0 ) {', // Edge at west
-		'		vec2 d;',
+			if ( e.r > 0.0 ) { // Edge at west
+				vec2 d;
 
 
-		// Find the distance to the top:
-		'		vec2 coords;',
+				// Find the distance to the top:
+				vec2 coords;
 
 
-		'		coords.y = SMAASearchYUp( edgesTex, searchTex, offset[ 1 ].xy, offset[ 2 ].z );',
-		'		coords.x = offset[ 0 ].x;', // offset[1].x = texcoord.x - 0.25 * resolution.x;
-		'		d.x = coords.y;',
+				coords.y = SMAASearchYUp( edgesTex, searchTex, offset[ 1 ].xy, offset[ 2 ].z );
+				coords.x = offset[ 0 ].x; // offset[1].x = texcoord.x - 0.25 * resolution.x;
+				d.x = coords.y;
 
 
-		// Fetch the top crossing edges:
-		'		float e1 = texture2D( edgesTex, coords, 0.0 ).g;',
+				// Fetch the top crossing edges:
+				float e1 = texture2D( edgesTex, coords, 0.0 ).g;
 
 
-		// Find the distance to the bottom:
-		'		coords.y = SMAASearchYDown( edgesTex, searchTex, offset[ 1 ].zw, offset[ 2 ].w );',
-		'		d.y = coords.y;',
+				// Find the distance to the bottom:
+				coords.y = SMAASearchYDown( edgesTex, searchTex, offset[ 1 ].zw, offset[ 2 ].w );
+				d.y = coords.y;
 
 
-		// We want the distances to be in pixel units:
-		'		d = d / resolution.y - pixcoord.y;',
+				// We want the distances to be in pixel units:
+				d = d / resolution.y - pixcoord.y;
 
 
-		// SMAAArea below needs a sqrt, as the areas texture is compressed
-		// quadratically:
-		'		vec2 sqrt_d = sqrt( abs( d ) );',
+				// SMAAArea below needs a sqrt, as the areas texture is compressed
+				// quadratically:
+				vec2 sqrt_d = sqrt( abs( d ) );
 
 
-		// Fetch the bottom crossing edges:
-		'		coords.y -= 1.0 * resolution.y;', // WebGL port note: Added
-		'		float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 0, 1 ) ).g;',
+				// Fetch the bottom crossing edges:
+				coords.y -= 1.0 * resolution.y; // WebGL port note: Added
+				float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 0, 1 ) ).g;
 
 
-		// Get the area for this direction:
-		'		weights.ba = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.x ) );',
-		'	}',
+				// Get the area for this direction:
+				weights.ba = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.x ) );
+			}
 
 
-		'	return weights;',
-		'}',
+			return weights;
+		}
 
 
-		'void main() {',
+		void main() {
 
 
-		'	gl_FragColor = SMAABlendingWeightCalculationPS( vUv, vPixcoord, vOffset, tDiffuse, tArea, tSearch, ivec4( 0.0 ) );',
+			gl_FragColor = SMAABlendingWeightCalculationPS( vUv, vPixcoord, vOffset, tDiffuse, tArea, tSearch, ivec4( 0.0 ) );
 
 
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 
-var SMAABlendShader = {
+const SMAABlendShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -385,87 +377,83 @@ var SMAABlendShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
-
-		'uniform vec2 resolution;',
-
-		'varying vec2 vUv;',
-		'varying vec4 vOffset[ 2 ];',
+	vertexShader:
 
 
-		'void SMAANeighborhoodBlendingVS( vec2 texcoord ) {',
-		'	vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0, 1.0 );', // WebGL port note: Changed sign in W component
-		'	vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( 1.0, 0.0, 0.0, -1.0 );', // WebGL port note: Changed sign in W component
-		'}',
+		`uniform vec2 resolution;
 
 
-		'void main() {',
+		varying vec2 vUv;
+		varying vec4 vOffset[ 2 ];
 
 
-		'	vUv = uv;',
+		void SMAANeighborhoodBlendingVS( vec2 texcoord ) {
+			vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0, 1.0 ); // WebGL port note: Changed sign in W component
+			vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( 1.0, 0.0, 0.0, -1.0 ); // WebGL port note: Changed sign in W component
+		}
 
 
-		'	SMAANeighborhoodBlendingVS( vUv );',
+		void main() {
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
 
 
-		'}'
+			SMAANeighborhoodBlendingVS( vUv );
 
 
-	].join( '\n' ),
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-	fragmentShader: [
+		}`,
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform sampler2D tColor;',
-		'uniform vec2 resolution;',
+	fragmentShader:
 
 
-		'varying vec2 vUv;',
-		'varying vec4 vOffset[ 2 ];',
+		`uniform sampler2D tDiffuse;
+		uniform sampler2D tColor;
+		uniform vec2 resolution;
 
 
-		'vec4 SMAANeighborhoodBlendingPS( vec2 texcoord, vec4 offset[ 2 ], sampler2D colorTex, sampler2D blendTex ) {',
-		// Fetch the blending weights for current pixel:
-		'	vec4 a;',
-		'	a.xz = texture2D( blendTex, texcoord ).xz;',
-		'	a.y = texture2D( blendTex, offset[ 1 ].zw ).g;',
-		'	a.w = texture2D( blendTex, offset[ 1 ].xy ).a;',
+		varying vec2 vUv;
+		varying vec4 vOffset[ 2 ];
 
 
-		// Is there any blending weight with a value greater than 0.0?
-		'	if ( dot(a, vec4( 1.0, 1.0, 1.0, 1.0 )) < 1e-5 ) {',
-		'		return texture2D( colorTex, texcoord, 0.0 );',
-		'	} else {',
-		// Up to 4 lines can be crossing a pixel (one through each edge). We
-		// favor blending by choosing the line with the maximum weight for each
-		// direction:
-		'		vec2 offset;',
-		'		offset.x = a.a > a.b ? a.a : -a.b;', // left vs. right
-		'		offset.y = a.g > a.r ? -a.g : a.r;', // top vs. bottom // WebGL port note: Changed signs
+		vec4 SMAANeighborhoodBlendingPS( vec2 texcoord, vec4 offset[ 2 ], sampler2D colorTex, sampler2D blendTex ) {
+			// Fetch the blending weights for current pixel:
+			vec4 a;
+			a.xz = texture2D( blendTex, texcoord ).xz;
+			a.y = texture2D( blendTex, offset[ 1 ].zw ).g;
+			a.w = texture2D( blendTex, offset[ 1 ].xy ).a;
 
 
-		// Then we go in the direction that has the maximum weight:
-		'		if ( abs( offset.x ) > abs( offset.y )) {', // horizontal vs. vertical
-		'			offset.y = 0.0;',
-		'		} else {',
-		'			offset.x = 0.0;',
-		'		}',
+			// Is there any blending weight with a value greater than 0.0?
+			if ( dot(a, vec4( 1.0, 1.0, 1.0, 1.0 )) < 1e-5 ) {
+				return texture2D( colorTex, texcoord, 0.0 );
+			} else {
+				// Up to 4 lines can be crossing a pixel (one through each edge). We
+				// favor blending by choosing the line with the maximum weight for each
+				// direction:
+				vec2 offset;
+				offset.x = a.a > a.b ? a.a : -a.b; // left vs. right
+				offset.y = a.g > a.r ? -a.g : a.r; // top vs. bottom // WebGL port note: Changed signs
 
 
-		// Fetch the opposite color and lerp by hand:
-		'		vec4 C = texture2D( colorTex, texcoord, 0.0 );',
-		'		texcoord += sign( offset ) * resolution;',
-		'		vec4 Cop = texture2D( colorTex, texcoord, 0.0 );',
-		'		float s = abs( offset.x ) > abs( offset.y ) ? abs( offset.x ) : abs( offset.y );',
+				// Then we go in the direction that has the maximum weight:
+				if ( abs( offset.x ) > abs( offset.y )) { // horizontal vs. vertical
+					offset.y = 0.0;
+				} else {
+					offset.x = 0.0;
+				}
 
 
-		// WebGL port note: Added gamma correction
-		'		C.xyz = pow(C.xyz, vec3(2.2));',
-		'		Cop.xyz = pow(Cop.xyz, vec3(2.2));',
-		'		vec4 mixed = mix(C, Cop, s);',
-		'		mixed.xyz = pow(mixed.xyz, vec3(1.0 / 2.2));',
+				// Fetch the opposite color and lerp by hand:
+				vec4 C = texture2D( colorTex, texcoord, 0.0 );
+				texcoord += sign( offset ) * resolution;
+				vec4 Cop = texture2D( colorTex, texcoord, 0.0 );
+				float s = abs( offset.x ) > abs( offset.y ) ? abs( offset.x ) : abs( offset.y );
 
 
-		'		return mixed;',
-		'	}',
-		'}',
+				// WebGL port note: Added gamma correction
+				C.xyz = pow(C.xyz, vec3(2.2));
+				Cop.xyz = pow(Cop.xyz, vec3(2.2));
+				vec4 mixed = mix(C, Cop, s);
+				mixed.xyz = pow(mixed.xyz, vec3(1.0 / 2.2));
 
 
-		'void main() {',
+				return mixed;
+			}
+		}
 
 
-		'	gl_FragColor = SMAANeighborhoodBlendingPS( vUv, vOffset, tColor, tDiffuse );',
+		void main() {
 
 
-		'}'
+			gl_FragColor = SMAANeighborhoodBlendingPS( vUv, vOffset, tColor, tDiffuse );
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 127 - 139
examples/jsm/shaders/SSAOShader.js

@@ -10,7 +10,7 @@ import {
  * https://github.com/McNopper/OpenGL/blob/master/Example28/shader/ssao.frag.glsl
  * https://github.com/McNopper/OpenGL/blob/master/Example28/shader/ssao.frag.glsl
  */
  */
 
 
-var SSAOShader = {
+const SSAOShader = {
 
 
 	defines: {
 	defines: {
 		'PERSPECTIVE_CAMERA': 1,
 		'PERSPECTIVE_CAMERA': 1,
@@ -35,150 +35,146 @@ var SSAOShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
+			vUv = uv;
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform sampler2D tNormal;
+		uniform sampler2D tDepth;
+		uniform sampler2D tNoise;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform sampler2D tNormal;',
-		'uniform sampler2D tDepth;',
-		'uniform sampler2D tNoise;',
+		uniform vec3 kernel[ KERNEL_SIZE ];
 
 
-		'uniform vec3 kernel[ KERNEL_SIZE ];',
+		uniform vec2 resolution;
 
 
-		'uniform vec2 resolution;',
+		uniform float cameraNear;
+		uniform float cameraFar;
+		uniform mat4 cameraProjectionMatrix;
+		uniform mat4 cameraInverseProjectionMatrix;
 
 
-		'uniform float cameraNear;',
-		'uniform float cameraFar;',
-		'uniform mat4 cameraProjectionMatrix;',
-		'uniform mat4 cameraInverseProjectionMatrix;',
+		uniform float kernelRadius;
+		uniform float minDistance; // avoid artifacts caused by neighbour fragments with minimal depth difference
+		uniform float maxDistance; // avoid the influence of fragments which are too far away
 
 
-		'uniform float kernelRadius;',
-		'uniform float minDistance;', // avoid artifacts caused by neighbour fragments with minimal depth difference
-		'uniform float maxDistance;', // avoid the influence of fragments which are too far away
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		#include <packing>
 
 
-		'#include <packing>',
+		float getDepth( const in vec2 screenPosition ) {
 
 
-		'float getDepth( const in vec2 screenPosition ) {',
+			return texture2D( tDepth, screenPosition ).x;
 
 
-		'	return texture2D( tDepth, screenPosition ).x;',
+		}
 
 
-		'}',
+		float getLinearDepth( const in vec2 screenPosition ) {
 
 
-		'float getLinearDepth( const in vec2 screenPosition ) {',
+			#if PERSPECTIVE_CAMERA == 1
 
 
-		'	#if PERSPECTIVE_CAMERA == 1',
+				float fragCoordZ = texture2D( tDepth, screenPosition ).x;
+				float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
+				return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
 
 
-		'		float fragCoordZ = texture2D( tDepth, screenPosition ).x;',
-		'		float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );',
-		'		return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );',
+			#else
 
 
-		'	#else',
+				return texture2D( tDepth, screenPosition ).x;
 
 
-		'		return texture2D( tDepth, screenPosition ).x;',
+			#endif
 
 
-		'	#endif',
+		}
 
 
-		'}',
+		float getViewZ( const in float depth ) {
 
 
-		'float getViewZ( const in float depth ) {',
+			#if PERSPECTIVE_CAMERA == 1
 
 
-		'	#if PERSPECTIVE_CAMERA == 1',
+				return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );
 
 
-		'		return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );',
+			#else
 
 
-		'	#else',
+				return orthographicDepthToViewZ( depth, cameraNear, cameraFar );
 
 
-		'		return orthographicDepthToViewZ( depth, cameraNear, cameraFar );',
+			#endif
 
 
-		'	#endif',
+		}
 
 
-		'}',
+		vec3 getViewPosition( const in vec2 screenPosition, const in float depth, const in float viewZ ) {
 
 
-		'vec3 getViewPosition( const in vec2 screenPosition, const in float depth, const in float viewZ ) {',
+			float clipW = cameraProjectionMatrix[2][3] * viewZ + cameraProjectionMatrix[3][3];
 
 
-		'	float clipW = cameraProjectionMatrix[2][3] * viewZ + cameraProjectionMatrix[3][3];',
+			vec4 clipPosition = vec4( ( vec3( screenPosition, depth ) - 0.5 ) * 2.0, 1.0 );
 
 
-		'	vec4 clipPosition = vec4( ( vec3( screenPosition, depth ) - 0.5 ) * 2.0, 1.0 );',
+			clipPosition *= clipW; // unprojection.
 
 
-		'	clipPosition *= clipW; // unprojection.',
+			return ( cameraInverseProjectionMatrix * clipPosition ).xyz;
 
 
-		'	return ( cameraInverseProjectionMatrix * clipPosition ).xyz;',
+		}
 
 
-		'}',
+		vec3 getViewNormal( const in vec2 screenPosition ) {
 
 
-		'vec3 getViewNormal( const in vec2 screenPosition ) {',
+			return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );
 
 
-		'	return unpackRGBToNormal( texture2D( tNormal, screenPosition ).xyz );',
+		}
 
 
-		'}',
+		void main() {
 
 
-		'void main() {',
+			float depth = getDepth( vUv );
+			float viewZ = getViewZ( depth );
 
 
-		'	float depth = getDepth( vUv );',
-		'	float viewZ = getViewZ( depth );',
+			vec3 viewPosition = getViewPosition( vUv, depth, viewZ );
+			vec3 viewNormal = getViewNormal( vUv );
 
 
-		'	vec3 viewPosition = getViewPosition( vUv, depth, viewZ );',
-		'	vec3 viewNormal = getViewNormal( vUv );',
+			vec2 noiseScale = vec2( resolution.x / 4.0, resolution.y / 4.0 );
+			vec3 random = texture2D( tNoise, vUv * noiseScale ).xyz;
 
 
-		' vec2 noiseScale = vec2( resolution.x / 4.0, resolution.y / 4.0 );',
-		'	vec3 random = texture2D( tNoise, vUv * noiseScale ).xyz;',
+			// compute matrix used to reorient a kernel vector
 
 
-		// compute matrix used to reorient a kernel vector
+			vec3 tangent = normalize( random - viewNormal * dot( random, viewNormal ) );
+			vec3 bitangent = cross( viewNormal, tangent );
+			mat3 kernelMatrix = mat3( tangent, bitangent, viewNormal );
 
 
-		'	vec3 tangent = normalize( random - viewNormal * dot( random, viewNormal ) );',
-		'	vec3 bitangent = cross( viewNormal, tangent );',
-		'	mat3 kernelMatrix = mat3( tangent, bitangent, viewNormal );',
+		 float occlusion = 0.0;
 
 
-		' float occlusion = 0.0;',
+		 for ( int i = 0; i < KERNEL_SIZE; i ++ ) {
 
 
-		' for ( int i = 0; i < KERNEL_SIZE; i ++ ) {',
+				vec3 sampleVector = kernelMatrix * kernel[ i ]; // reorient sample vector in view space
+				vec3 samplePoint = viewPosition + ( sampleVector * kernelRadius ); // calculate sample point
 
 
-		'		vec3 sampleVector = kernelMatrix * kernel[ i ];', // reorient sample vector in view space
-		'		vec3 samplePoint = viewPosition + ( sampleVector * kernelRadius );', // calculate sample point
+				vec4 samplePointNDC = cameraProjectionMatrix * vec4( samplePoint, 1.0 ); // project point and calculate NDC
+				samplePointNDC /= samplePointNDC.w;
 
 
-		'		vec4 samplePointNDC = cameraProjectionMatrix * vec4( samplePoint, 1.0 );', // project point and calculate NDC
-		'		samplePointNDC /= samplePointNDC.w;',
+				vec2 samplePointUv = samplePointNDC.xy * 0.5 + 0.5; // compute uv coordinates
 
 
-		'		vec2 samplePointUv = samplePointNDC.xy * 0.5 + 0.5;', // compute uv coordinates
+				float realDepth = getLinearDepth( samplePointUv ); // get linear depth from depth texture
+				float sampleDepth = viewZToOrthographicDepth( samplePoint.z, cameraNear, cameraFar ); // compute linear depth of the sample view Z value
+				float delta = sampleDepth - realDepth;
 
 
-		'		float realDepth = getLinearDepth( samplePointUv );', // get linear depth from depth texture
-		'		float sampleDepth = viewZToOrthographicDepth( samplePoint.z, cameraNear, cameraFar );', // compute linear depth of the sample view Z value
-		'		float delta = sampleDepth - realDepth;',
+				if ( delta > minDistance && delta < maxDistance ) { // if fragment is before sample point, increase occlusion
 
 
-		'		if ( delta > minDistance && delta < maxDistance ) {', // if fragment is before sample point, increase occlusion
+					occlusion += 1.0;
 
 
-		'			occlusion += 1.0;',
+				}
 
 
-		'		}',
+			}
 
 
-		'	}',
+			occlusion = clamp( occlusion / float( KERNEL_SIZE ), 0.0, 1.0 );
 
 
-		'	occlusion = clamp( occlusion / float( KERNEL_SIZE ), 0.0, 1.0 );',
+			gl_FragColor = vec4( vec3( 1.0 - occlusion ), 1.0 );
 
 
-		'	gl_FragColor = vec4( vec3( 1.0 - occlusion ), 1.0 );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 
-var SSAODepthShader = {
+const SSAODepthShader = {
 
 
 	defines: {
 	defines: {
 		'PERSPECTIVE_CAMERA': 1
 		'PERSPECTIVE_CAMERA': 1
@@ -192,58 +188,54 @@ var SSAODepthShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
-
-		'varying vec2 vUv;',
+	vertexShader:
 
 
-		'void main() {',
+		`varying vec2 vUv;
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+		void main() {
 
 
-		'}'
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-	].join( '\n' ),
+		}`,
 
 
-	fragmentShader: [
+	fragmentShader:
 
 
-		'uniform sampler2D tDepth;',
+		`uniform sampler2D tDepth;
 
 
-		'uniform float cameraNear;',
-		'uniform float cameraFar;',
+		uniform float cameraNear;
+		uniform float cameraFar;
 
 
-		'varying vec2 vUv;',
+		varying vec2 vUv;
 
 
-		'#include <packing>',
+		#include <packing>
 
 
-		'float getLinearDepth( const in vec2 screenPosition ) {',
+		float getLinearDepth( const in vec2 screenPosition ) {
 
 
-		'	#if PERSPECTIVE_CAMERA == 1',
+			#if PERSPECTIVE_CAMERA == 1
 
 
-		'		float fragCoordZ = texture2D( tDepth, screenPosition ).x;',
-		'		float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );',
-		'		return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );',
+				float fragCoordZ = texture2D( tDepth, screenPosition ).x;
+				float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
+				return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
 
 
-		'	#else',
+			#else
 
 
-		'		return texture2D( tDepth, screenPosition ).x;',
+				return texture2D( tDepth, screenPosition ).x;
 
 
-		'	#endif',
+			#endif
 
 
-		'}',
+		}
 
 
-		'void main() {',
+		void main() {
 
 
-		'	float depth = getLinearDepth( vUv );',
-		'	gl_FragColor = vec4( vec3( 1.0 - depth ), 1.0 );',
+			float depth = getLinearDepth( vUv );
+			gl_FragColor = vec4( vec3( 1.0 - depth ), 1.0 );
 
 
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 
-var SSAOBlurShader = {
+const SSAOBlurShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -252,48 +244,44 @@ var SSAOBlurShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
-
-		'varying vec2 vUv;',
-
-		'void main() {',
+	vertexShader:
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+		`varying vec2 vUv;
 
 
-		'}'
+		void main() {
 
 
-	].join( '\n' ),
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-	fragmentShader: [
+		}`,
 
 
-		'uniform sampler2D tDiffuse;',
+	fragmentShader:
 
 
-		'uniform vec2 resolution;',
+		`uniform sampler2D tDiffuse;
 
 
-		'varying vec2 vUv;',
+		uniform vec2 resolution;
 
 
-		'void main() {',
+		varying vec2 vUv;
 
 
-		'	vec2 texelSize = ( 1.0 / resolution );',
-		'	float result = 0.0;',
+		void main() {
 
 
-		'	for ( int i = - 2; i <= 2; i ++ ) {',
+			vec2 texelSize = ( 1.0 / resolution );
+			float result = 0.0;
 
 
-		'		for ( int j = - 2; j <= 2; j ++ ) {',
+			for ( int i = - 2; i <= 2; i ++ ) {
 
 
-		'			vec2 offset = ( vec2( float( i ), float( j ) ) ) * texelSize;',
-		'			result += texture2D( tDiffuse, vUv + offset ).r;',
+				for ( int j = - 2; j <= 2; j ++ ) {
 
 
-		'		}',
+					vec2 offset = ( vec2( float( i ), float( j ) ) ) * texelSize;
+					result += texture2D( tDiffuse, vUv + offset ).r;
 
 
-		'	}',
+				}
 
 
-		'	gl_FragColor = vec4( vec3( result / ( 5.0 * 5.0 ) ), 1.0 );',
+			}
 
 
-		'}'
+			gl_FragColor = vec4( vec3( result / ( 5.0 * 5.0 ) ), 1.0 );
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 1 - 1
examples/jsm/shaders/SSRrShader.js

@@ -3,7 +3,7 @@ import {
 	Vector2
 	Vector2
 } from '../../../build/three.module.js';
 } from '../../../build/three.module.js';
 
 
-var SSRrShader = {
+const SSRrShader = {
 
 
 	defines: {
 	defines: {
 		MAX_STEP: 0,
 		MAX_STEP: 0,

+ 19 - 23
examples/jsm/shaders/SepiaShader.js

@@ -4,7 +4,7 @@
  * https://github.com/evanw/glfx.js
  * https://github.com/evanw/glfx.js
  */
  */
 
 
-var SepiaShader = {
+const SepiaShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -13,41 +13,37 @@ var SepiaShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform float amount;
 
 
-		'uniform float amount;',
+		uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 color = texture2D( tDiffuse, vUv );
+			vec3 c = color.rgb;
 
 
-		'	vec4 color = texture2D( tDiffuse, vUv );',
-		'	vec3 c = color.rgb;',
+			color.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );
+			color.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );
+			color.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );
 
 
-		'	color.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );',
-		'	color.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );',
-		'	color.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );',
+			gl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );
 
 
-		'	gl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 33 - 37
examples/jsm/shaders/SobelOperatorShader.js

@@ -9,7 +9,7 @@ import {
  *
  *
  */
  */
 
 
-var SobelOperatorShader = {
+const SobelOperatorShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -18,76 +18,72 @@ var SobelOperatorShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
+			vUv = uv;
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform vec2 resolution;
+		varying vec2 vUv;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform vec2 resolution;',
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
-
-		'	vec2 texel = vec2( 1.0 / resolution.x, 1.0 / resolution.y );',
+			vec2 texel = vec2( 1.0 / resolution.x, 1.0 / resolution.y );
 
 
 		// kernel definition (in glsl matrices are filled in column-major order)
 		// kernel definition (in glsl matrices are filled in column-major order)
 
 
-		'	const mat3 Gx = mat3( -1, -2, -1, 0, 0, 0, 1, 2, 1 );', // x direction kernel
-		'	const mat3 Gy = mat3( -1, 0, 1, -2, 0, 2, -1, 0, 1 );', // y direction kernel
+			const mat3 Gx = mat3( -1, -2, -1, 0, 0, 0, 1, 2, 1 ); // x direction kernel
+			const mat3 Gy = mat3( -1, 0, 1, -2, 0, 2, -1, 0, 1 ); // y direction kernel
 
 
 		// fetch the 3x3 neighbourhood of a fragment
 		// fetch the 3x3 neighbourhood of a fragment
 
 
 		// first column
 		// first column
 
 
-		'	float tx0y0 = texture2D( tDiffuse, vUv + texel * vec2( -1, -1 ) ).r;',
-		'	float tx0y1 = texture2D( tDiffuse, vUv + texel * vec2( -1,  0 ) ).r;',
-		'	float tx0y2 = texture2D( tDiffuse, vUv + texel * vec2( -1,  1 ) ).r;',
+			float tx0y0 = texture2D( tDiffuse, vUv + texel * vec2( -1, -1 ) ).r;
+			float tx0y1 = texture2D( tDiffuse, vUv + texel * vec2( -1,  0 ) ).r;
+			float tx0y2 = texture2D( tDiffuse, vUv + texel * vec2( -1,  1 ) ).r;
 
 
 		// second column
 		// second column
 
 
-		'	float tx1y0 = texture2D( tDiffuse, vUv + texel * vec2(  0, -1 ) ).r;',
-		'	float tx1y1 = texture2D( tDiffuse, vUv + texel * vec2(  0,  0 ) ).r;',
-		'	float tx1y2 = texture2D( tDiffuse, vUv + texel * vec2(  0,  1 ) ).r;',
+			float tx1y0 = texture2D( tDiffuse, vUv + texel * vec2(  0, -1 ) ).r;
+			float tx1y1 = texture2D( tDiffuse, vUv + texel * vec2(  0,  0 ) ).r;
+			float tx1y2 = texture2D( tDiffuse, vUv + texel * vec2(  0,  1 ) ).r;
 
 
 		// third column
 		// third column
 
 
-		'	float tx2y0 = texture2D( tDiffuse, vUv + texel * vec2(  1, -1 ) ).r;',
-		'	float tx2y1 = texture2D( tDiffuse, vUv + texel * vec2(  1,  0 ) ).r;',
-		'	float tx2y2 = texture2D( tDiffuse, vUv + texel * vec2(  1,  1 ) ).r;',
+			float tx2y0 = texture2D( tDiffuse, vUv + texel * vec2(  1, -1 ) ).r;
+			float tx2y1 = texture2D( tDiffuse, vUv + texel * vec2(  1,  0 ) ).r;
+			float tx2y2 = texture2D( tDiffuse, vUv + texel * vec2(  1,  1 ) ).r;
 
 
 		// gradient value in x direction
 		// gradient value in x direction
 
 
-		'	float valueGx = Gx[0][0] * tx0y0 + Gx[1][0] * tx1y0 + Gx[2][0] * tx2y0 + ',
-		'		Gx[0][1] * tx0y1 + Gx[1][1] * tx1y1 + Gx[2][1] * tx2y1 + ',
-		'		Gx[0][2] * tx0y2 + Gx[1][2] * tx1y2 + Gx[2][2] * tx2y2; ',
+			float valueGx = Gx[0][0] * tx0y0 + Gx[1][0] * tx1y0 + Gx[2][0] * tx2y0 +
+				Gx[0][1] * tx0y1 + Gx[1][1] * tx1y1 + Gx[2][1] * tx2y1 +
+				Gx[0][2] * tx0y2 + Gx[1][2] * tx1y2 + Gx[2][2] * tx2y2;
 
 
 		// gradient value in y direction
 		// gradient value in y direction
 
 
-		'	float valueGy = Gy[0][0] * tx0y0 + Gy[1][0] * tx1y0 + Gy[2][0] * tx2y0 + ',
-		'		Gy[0][1] * tx0y1 + Gy[1][1] * tx1y1 + Gy[2][1] * tx2y1 + ',
-		'		Gy[0][2] * tx0y2 + Gy[1][2] * tx1y2 + Gy[2][2] * tx2y2; ',
+			float valueGy = Gy[0][0] * tx0y0 + Gy[1][0] * tx1y0 + Gy[2][0] * tx2y0 +
+				Gy[0][1] * tx0y1 + Gy[1][1] * tx1y1 + Gy[2][1] * tx2y1 +
+				Gy[0][2] * tx0y2 + Gy[1][2] * tx1y2 + Gy[2][2] * tx2y2;
 
 
 		// magnitute of the total gradient
 		// magnitute of the total gradient
 
 
-		'	float G = sqrt( ( valueGx * valueGx ) + ( valueGy * valueGy ) );',
-
-		'	gl_FragColor = vec4( vec3( G ), 1 );',
+			float G = sqrt( ( valueGx * valueGx ) + ( valueGy * valueGy ) );
 
 
-		'}'
+			gl_FragColor = vec4( vec3( G ), 1 );
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 3 - 3
examples/jsm/shaders/SubsurfaceScatteringShader.js

@@ -19,10 +19,10 @@ function replaceAll( string, find, replace ) {
 
 
 }
 }
 
 
-var meshphong_frag_head = ShaderChunk[ 'meshphong_frag' ].slice( 0, ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) );
-var meshphong_frag_body = ShaderChunk[ 'meshphong_frag' ].slice( ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) );
+const meshphong_frag_head = ShaderChunk[ 'meshphong_frag' ].slice( 0, ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) );
+const meshphong_frag_body = ShaderChunk[ 'meshphong_frag' ].slice( ShaderChunk[ 'meshphong_frag' ].indexOf( 'void main() {' ) );
 
 
-var SubsurfaceScatteringShader = {
+const SubsurfaceScatteringShader = {
 
 
 	uniforms: UniformsUtils.merge( [
 	uniforms: UniformsUtils.merge( [
 		ShaderLib[ 'phong' ].uniforms,
 		ShaderLib[ 'phong' ].uniforms,

+ 15 - 19
examples/jsm/shaders/TechnicolorShader.js

@@ -5,7 +5,7 @@
  * Demo here: http://charliehoey.com/technicolor_shader/shader_test.html
  * Demo here: http://charliehoey.com/technicolor_shader/shader_test.html
  */
  */
 
 
-var TechnicolorShader = {
+const TechnicolorShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -13,34 +13,30 @@ var TechnicolorShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		varying vec2 vUv;
 
 
-		'uniform sampler2D tDiffuse;',
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 tex = texture2D( tDiffuse, vec2( vUv.x, vUv.y ) );
+			vec4 newTex = vec4(tex.r, (tex.g + tex.b) * .5, (tex.g + tex.b) * .5, 1.0);
 
 
-		'	vec4 tex = texture2D( tDiffuse, vec2( vUv.x, vUv.y ) );',
-		'	vec4 newTex = vec4(tex.r, (tex.g + tex.b) * .5, (tex.g + tex.b) * .5, 1.0);',
+			gl_FragColor = newTex;
 
 
-		'	gl_FragColor = newTex;',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 36 - 40
examples/jsm/shaders/ToneMapShader.js

@@ -14,63 +14,59 @@ var ToneMapShader = {
 		'middleGrey': { value: 0.6 }
 		'middleGrey': { value: 0.6 }
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`#include <common>
 
 
-		'#include <common>',
+		uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		uniform float middleGrey;
+		uniform float minLuminance;
+		uniform float maxLuminance;
+		#ifdef ADAPTED_LUMINANCE
+			uniform sampler2D luminanceMap;
+		#else
+			uniform float averageLuminance;
+		#endif
 
 
-		'uniform float middleGrey;',
-		'uniform float minLuminance;',
-		'uniform float maxLuminance;',
-		'#ifdef ADAPTED_LUMINANCE',
-		'	uniform sampler2D luminanceMap;',
-		'#else',
-		'	uniform float averageLuminance;',
-		'#endif',
+		vec3 ToneMap( vec3 vColor ) {
+			#ifdef ADAPTED_LUMINANCE
+				// Get the calculated average luminance
+				float fLumAvg = texture2D(luminanceMap, vec2(0.5, 0.5)).r;
+			#else
+				float fLumAvg = averageLuminance;
+			#endif
 
 
-		'vec3 ToneMap( vec3 vColor ) {',
-		'	#ifdef ADAPTED_LUMINANCE',
-		// Get the calculated average luminance
-		'		float fLumAvg = texture2D(luminanceMap, vec2(0.5, 0.5)).r;',
-		'	#else',
-		'		float fLumAvg = averageLuminance;',
-		'	#endif',
+			// Calculate the luminance of the current pixel
+			float fLumPixel = linearToRelativeLuminance( vColor );
 
 
-		// Calculate the luminance of the current pixel
-		'	float fLumPixel = linearToRelativeLuminance( vColor );',
+			// Apply the modified operator (Eq. 4)
+			float fLumScaled = (fLumPixel * middleGrey) / max( minLuminance, fLumAvg );
 
 
-		// Apply the modified operator (Eq. 4)
-		'	float fLumScaled = (fLumPixel * middleGrey) / max( minLuminance, fLumAvg );',
+			float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (maxLuminance * maxLuminance)))) / (1.0 + fLumScaled);
+			return fLumCompressed * vColor;
+		}
 
 
-		'	float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (maxLuminance * maxLuminance)))) / (1.0 + fLumScaled);',
-		'	return fLumCompressed * vColor;',
-		'}',
+		void main() {
 
 
-		'void main() {',
+			vec4 texel = texture2D( tDiffuse, vUv );
 
 
-		'	vec4 texel = texture2D( tDiffuse, vUv );',
+			gl_FragColor = vec4( ToneMap( texel.xyz ), texel.w );
 
 
-		'	gl_FragColor = vec4( ToneMap( texel.xyz ), texel.w );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 136 - 152
examples/jsm/shaders/ToonShader.js

@@ -12,7 +12,7 @@ import {
  *	dotted
  *	dotted
  */
  */
 
 
-var ToonShader1 = {
+const ToonShader1 = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -25,70 +25,66 @@ var ToonShader1 = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec3 vNormal;',
-		'varying vec3 vRefract;',
+		`varying vec3 vNormal;
+		varying vec3 vRefract;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',
-		'	vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
-		'	vec3 worldNormal = normalize ( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );',
+			vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
+			vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+			vec3 worldNormal = normalize ( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
 
 
-		'	vNormal = normalize( normalMatrix * normal );',
+			vNormal = normalize( normalMatrix * normal );
 
 
-		'	vec3 I = worldPosition.xyz - cameraPosition;',
-		'	vRefract = refract( normalize( I ), worldNormal, 1.02 );',
+			vec3 I = worldPosition.xyz - cameraPosition;
+			vRefract = refract( normalize( I ), worldNormal, 1.02 );
 
 
-		'	gl_Position = projectionMatrix * mvPosition;',
+			gl_Position = projectionMatrix * mvPosition;
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform vec3 uBaseColor;
 
 
-		'uniform vec3 uBaseColor;',
+		uniform vec3 uDirLightPos;
+		uniform vec3 uDirLightColor;
 
 
-		'uniform vec3 uDirLightPos;',
-		'uniform vec3 uDirLightColor;',
+		uniform vec3 uAmbientLightColor;
 
 
-		'uniform vec3 uAmbientLightColor;',
+		varying vec3 vNormal;
 
 
-		'varying vec3 vNormal;',
+		varying vec3 vRefract;
 
 
-		'varying vec3 vRefract;',
+		void main() {
 
 
-		'void main() {',
+			float directionalLightWeighting = max( dot( normalize( vNormal ), uDirLightPos ), 0.0);
+			vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;
 
 
-		'	float directionalLightWeighting = max( dot( normalize( vNormal ), uDirLightPos ), 0.0);',
-		'	vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;',
+			float intensity = smoothstep( - 0.5, 1.0, pow( length(lightWeighting), 20.0 ) );
+			intensity += length(lightWeighting) * 0.2;
 
 
-		'	float intensity = smoothstep( - 0.5, 1.0, pow( length(lightWeighting), 20.0 ) );',
-		'	intensity += length(lightWeighting) * 0.2;',
+			float cameraWeighting = dot( normalize( vNormal ), vRefract );
+			intensity += pow( 1.0 - length( cameraWeighting ), 6.0 );
+			intensity = intensity * 0.2 + 0.3;
 
 
-		'	float cameraWeighting = dot( normalize( vNormal ), vRefract );',
-		'	intensity += pow( 1.0 - length( cameraWeighting ), 6.0 );',
-		'	intensity = intensity * 0.2 + 0.3;',
+			if ( intensity < 0.50 ) {
 
 
-		'	if ( intensity < 0.50 ) {',
+				gl_FragColor = vec4( 2.0 * intensity * uBaseColor, 1.0 );
 
 
-		'		gl_FragColor = vec4( 2.0 * intensity * uBaseColor, 1.0 );',
+			} else {
 
 
-		'	} else {',
+				gl_FragColor = vec4( 1.0 - 2.0 * ( 1.0 - intensity ) * ( 1.0 - uBaseColor ), 1.0 );
 
 
-		'		gl_FragColor = vec4( 1.0 - 2.0 * ( 1.0 - intensity ) * ( 1.0 - uBaseColor ), 1.0 );',
+		}
 
 
-		'}',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 
-var ToonShader2 = {
+const ToonShader2 = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -105,60 +101,56 @@ var ToonShader2 = {
 
 
 	},
 	},
 
 
-	vertexShader: [
-
-		'varying vec3 vNormal;',
-
-		'void main() {',
+	vertexShader:
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
-		'	vNormal = normalize( normalMatrix * normal );',
+		`varying vec3 vNormal;
 
 
-		'}'
+		void main() {
 
 
-	].join( '\n' ),
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+			vNormal = normalize( normalMatrix * normal );
 
 
-	fragmentShader: [
+		}`,
 
 
-		'uniform vec3 uBaseColor;',
-		'uniform vec3 uLineColor1;',
-		'uniform vec3 uLineColor2;',
-		'uniform vec3 uLineColor3;',
-		'uniform vec3 uLineColor4;',
+	fragmentShader:
 
 
-		'uniform vec3 uDirLightPos;',
-		'uniform vec3 uDirLightColor;',
+		`uniform vec3 uBaseColor;
+		uniform vec3 uLineColor1;
+		uniform vec3 uLineColor2;
+		uniform vec3 uLineColor3;
+		uniform vec3 uLineColor4;
 
 
-		'uniform vec3 uAmbientLightColor;',
+		uniform vec3 uDirLightPos;
+		uniform vec3 uDirLightColor;
 
 
-		'varying vec3 vNormal;',
+		uniform vec3 uAmbientLightColor;
 
 
-		'void main() {',
+		varying vec3 vNormal;
 
 
-		'	float camera = max( dot( normalize( vNormal ), vec3( 0.0, 0.0, 1.0 ) ), 0.4);',
-		'	float light = max( dot( normalize( vNormal ), uDirLightPos ), 0.0);',
+		void main() {
 
 
-		'	gl_FragColor = vec4( uBaseColor, 1.0 );',
+			float camera = max( dot( normalize( vNormal ), vec3( 0.0, 0.0, 1.0 ) ), 0.4);
+			float light = max( dot( normalize( vNormal ), uDirLightPos ), 0.0);
 
 
-		'	if ( length(uAmbientLightColor + uDirLightColor * light) < 1.00 ) {',
+			gl_FragColor = vec4( uBaseColor, 1.0 );
 
 
-		'		gl_FragColor *= vec4( uLineColor1, 1.0 );',
+			if ( length(uAmbientLightColor + uDirLightColor * light) < 1.00 ) {
 
 
-		'	}',
+				gl_FragColor *= vec4( uLineColor1, 1.0 );
 
 
-		'	if ( length(uAmbientLightColor + uDirLightColor * camera) < 0.50 ) {',
+			}
 
 
-		'		gl_FragColor *= vec4( uLineColor2, 1.0 );',
+			if ( length(uAmbientLightColor + uDirLightColor * camera) < 0.50 ) {
 
 
-		'	}',
+				gl_FragColor *= vec4( uLineColor2, 1.0 );
 
 
-		'}'
+			}
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 
-var ToonShaderHatching = {
+const ToonShaderHatching = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -175,88 +167,84 @@ var ToonShaderHatching = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec3 vNormal;',
+		`varying vec3 vNormal;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
-		'	vNormal = normalize( normalMatrix * normal );',
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+			vNormal = normalize( normalMatrix * normal );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform vec3 uBaseColor;
+		uniform vec3 uLineColor1;
+		uniform vec3 uLineColor2;
+		uniform vec3 uLineColor3;
+		uniform vec3 uLineColor4;
 
 
-		'uniform vec3 uBaseColor;',
-		'uniform vec3 uLineColor1;',
-		'uniform vec3 uLineColor2;',
-		'uniform vec3 uLineColor3;',
-		'uniform vec3 uLineColor4;',
+		uniform vec3 uDirLightPos;
+		uniform vec3 uDirLightColor;
 
 
-		'uniform vec3 uDirLightPos;',
-		'uniform vec3 uDirLightColor;',
+		uniform vec3 uAmbientLightColor;
 
 
-		'uniform vec3 uAmbientLightColor;',
+		varying vec3 vNormal;
 
 
-		'varying vec3 vNormal;',
+		void main() {
 
 
-		'void main() {',
+			float directionalLightWeighting = max( dot( normalize(vNormal), uDirLightPos ), 0.0);
+			vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;
 
 
-		'	float directionalLightWeighting = max( dot( normalize(vNormal), uDirLightPos ), 0.0);',
-		'	vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;',
+			gl_FragColor = vec4( uBaseColor, 1.0 );
 
 
-		'	gl_FragColor = vec4( uBaseColor, 1.0 );',
+			if ( length(lightWeighting) < 1.00 ) {
 
 
-		'	if ( length(lightWeighting) < 1.00 ) {',
+				if ( mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {
 
 
-		'		if ( mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {',
+					gl_FragColor = vec4( uLineColor1, 1.0 );
 
 
-		'			gl_FragColor = vec4( uLineColor1, 1.0 );',
+				}
 
 
-		'		}',
+			}
 
 
-		'	}',
+			if ( length(lightWeighting) < 0.75 ) {
 
 
-		'	if ( length(lightWeighting) < 0.75 ) {',
+				if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {
 
 
-		'		if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {',
+					gl_FragColor = vec4( uLineColor2, 1.0 );
 
 
-		'			gl_FragColor = vec4( uLineColor2, 1.0 );',
+				}
 
 
-		'		}',
+			}
 
 
-		'	}',
+			if ( length(lightWeighting) < 0.50 ) {
 
 
-		'	if ( length(lightWeighting) < 0.50 ) {',
+				if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {
 
 
-		'		if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {',
+					gl_FragColor = vec4( uLineColor3, 1.0 );
 
 
-		'			gl_FragColor = vec4( uLineColor3, 1.0 );',
+				}
 
 
-		'		}',
+			}
 
 
-		'	}',
+			if ( length(lightWeighting) < 0.3465 ) {
 
 
-		'	if ( length(lightWeighting) < 0.3465 ) {',
+				if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {
 
 
-		'		if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {',
+					gl_FragColor = vec4( uLineColor4, 1.0 );
 
 
-		'			gl_FragColor = vec4( uLineColor4, 1.0 );',
+			}
 
 
-		'	}',
+			}
 
 
-		'	}',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 
-var ToonShaderDotted = {
+const ToonShaderDotted = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -270,64 +258,60 @@ var ToonShaderDotted = {
 
 
 	},
 	},
 
 
-	vertexShader: [
-
-		'varying vec3 vNormal;',
-
-		'void main() {',
+	vertexShader:
 
 
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
-		'	vNormal = normalize( normalMatrix * normal );',
+		`varying vec3 vNormal;
 
 
-		'}'
+		void main() {
 
 
-	].join( '\n' ),
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+			vNormal = normalize( normalMatrix * normal );
 
 
-	fragmentShader: [
+		}`,
 
 
-		'uniform vec3 uBaseColor;',
-		'uniform vec3 uLineColor1;',
-		'uniform vec3 uLineColor2;',
-		'uniform vec3 uLineColor3;',
-		'uniform vec3 uLineColor4;',
+	fragmentShader:
 
 
-		'uniform vec3 uDirLightPos;',
-		'uniform vec3 uDirLightColor;',
+		`uniform vec3 uBaseColor;
+		uniform vec3 uLineColor1;
+		uniform vec3 uLineColor2;
+		uniform vec3 uLineColor3;
+		uniform vec3 uLineColor4;
 
 
-		'uniform vec3 uAmbientLightColor;',
+		uniform vec3 uDirLightPos;
+		uniform vec3 uDirLightColor;
 
 
-		'varying vec3 vNormal;',
+		uniform vec3 uAmbientLightColor;
 
 
-		'void main() {',
+		varying vec3 vNormal;
 
 
-		'float directionalLightWeighting = max( dot( normalize(vNormal), uDirLightPos ), 0.0);',
-		'vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;',
+		void main() {
 
 
-		'gl_FragColor = vec4( uBaseColor, 1.0 );',
+		float directionalLightWeighting = max( dot( normalize(vNormal), uDirLightPos ), 0.0);
+		vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;
 
 
-		'if ( length(lightWeighting) < 1.00 ) {',
+		gl_FragColor = vec4( uBaseColor, 1.0 );
 
 
-		'		if ( ( mod(gl_FragCoord.x, 4.001) + mod(gl_FragCoord.y, 4.0) ) > 6.00 ) {',
+		if ( length(lightWeighting) < 1.00 ) {
 
 
-		'			gl_FragColor = vec4( uLineColor1, 1.0 );',
+				if ( ( mod(gl_FragCoord.x, 4.001) + mod(gl_FragCoord.y, 4.0) ) > 6.00 ) {
 
 
-		'		}',
+					gl_FragColor = vec4( uLineColor1, 1.0 );
 
 
-		'	}',
+				}
 
 
-		'	if ( length(lightWeighting) < 0.50 ) {',
+			}
 
 
-		'		if ( ( mod(gl_FragCoord.x + 2.0, 4.001) + mod(gl_FragCoord.y + 2.0, 4.0) ) > 6.00 ) {',
+			if ( length(lightWeighting) < 0.50 ) {
 
 
-		'			gl_FragColor = vec4( uLineColor1, 1.0 );',
+				if ( ( mod(gl_FragCoord.x + 2.0, 4.001) + mod(gl_FragCoord.y + 2.0, 4.0) ) > 6.00 ) {
 
 
-		'		}',
+					gl_FragColor = vec4( uLineColor1, 1.0 );
 
 
-		'	}',
+				}
 
 
-		'}'
+			}
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 25 - 29
examples/jsm/shaders/TriangleBlurShader.js

@@ -12,7 +12,7 @@ import {
  * perpendicular triangle filters.
  * perpendicular triangle filters.
  */
  */
 
 
-var TriangleBlurShader = {
+const TriangleBlurShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -21,55 +21,51 @@ var TriangleBlurShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`#include <common>
 
 
-		'#include <common>',
+		#define ITERATIONS 10.0
 
 
-		'#define ITERATIONS 10.0',
+		uniform sampler2D texture;
+		uniform vec2 delta;
 
 
-		'uniform sampler2D texture;',
-		'uniform vec2 delta;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 color = vec4( 0.0 );
 
 
-		'	vec4 color = vec4( 0.0 );',
-
-		'	float total = 0.0;',
+			float total = 0.0;
 
 
 		// randomize the lookup values to hide the fixed number of samples
 		// randomize the lookup values to hide the fixed number of samples
 
 
-		'	float offset = rand( vUv );',
-
-		'	for ( float t = -ITERATIONS; t <= ITERATIONS; t ++ ) {',
+			float offset = rand( vUv );
 
 
-		'		float percent = ( t + offset - 0.5 ) / ITERATIONS;',
-		'		float weight = 1.0 - abs( percent );',
+			for ( float t = -ITERATIONS; t <= ITERATIONS; t ++ ) {
 
 
-		'		color += texture2D( texture, vUv + delta * percent ) * weight;',
-		'		total += weight;',
+				float percent = ( t + offset - 0.5 ) / ITERATIONS;
+				float weight = 1.0 - abs( percent );
 
 
-		'	}',
+				color += texture2D( texture, vUv + delta * percent ) * weight;
+				total += weight;
 
 
-		'	gl_FragColor = color / total;',
+			}
 
 
-		'}'
+			gl_FragColor = color / total;
 
 
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 16 - 20
examples/jsm/shaders/UnpackDepthRGBAShader.js

@@ -3,7 +3,7 @@
  * - show RGBA encoded depth as monochrome color
  * - show RGBA encoded depth as monochrome color
  */
  */
 
 
-var UnpackDepthRGBAShader = {
+const UnpackDepthRGBAShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -12,37 +12,33 @@ var UnpackDepthRGBAShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform float opacity;
 
 
-		'uniform float opacity;',
+		uniform sampler2D tDiffuse;
 
 
-		'uniform sampler2D tDiffuse;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		#include <packing>
 
 
-		'#include <packing>',
+		void main() {
 
 
-		'void main() {',
+			float depth = 1.0 - unpackRGBAToDepth( texture2D( tDiffuse, vUv ) );
+			gl_FragColor = vec4( vec3( depth ), opacity );
 
 
-		'	float depth = 1.0 - unpackRGBAToDepth( texture2D( tDiffuse, vUv ) );',
-		'	gl_FragColor = vec4( vec3( depth ), opacity );',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

+ 24 - 28
examples/jsm/shaders/VerticalBlurShader.js

@@ -8,7 +8,7 @@
  * - "h" and "v" parameters should be set to "1 / width" and "1 / height"
  * - "h" and "v" parameters should be set to "1 / width" and "1 / height"
  */
  */
 
 
-var VerticalBlurShader = {
+const VerticalBlurShader = {
 
 
 	uniforms: {
 	uniforms: {
 
 
@@ -17,45 +17,41 @@ var VerticalBlurShader = {
 
 
 	},
 	},
 
 
-	vertexShader: [
+	vertexShader:
 
 
-		'varying vec2 vUv;',
+		`varying vec2 vUv;
 
 
-		'void main() {',
+		void main() {
 
 
-		'	vUv = uv;',
-		'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
+			vUv = uv;
+			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 
 
-		'}'
+		}`,
 
 
-	].join( '\n' ),
+	fragmentShader:
 
 
-	fragmentShader: [
+		`uniform sampler2D tDiffuse;
+		uniform float v;
 
 
-		'uniform sampler2D tDiffuse;',
-		'uniform float v;',
+		varying vec2 vUv;
 
 
-		'varying vec2 vUv;',
+		void main() {
 
 
-		'void main() {',
+			vec4 sum = vec4( 0.0 );
 
 
-		'	vec4 sum = vec4( 0.0 );',
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;
+			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;
 
 
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;',
-		'	sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;',
+			gl_FragColor = sum;
 
 
-		'	gl_FragColor = sum;',
-
-		'}'
-
-	].join( '\n' )
+		}`
 
 
 };
 };
 
 

Some files were not shown because too many files changed in this diff