109 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { ShaderPass } from './ShaderPass.js';
 | |
| 
 | |
| const LUTShader = {
 | |
| 
 | |
| 	name: 'LUTShader',
 | |
| 
 | |
| 	uniforms: {
 | |
| 
 | |
| 		lut: { value: null },
 | |
| 		lutSize: { value: 0 },
 | |
| 
 | |
| 		tDiffuse: { value: null },
 | |
| 		intensity: { value: 1.0 },
 | |
| 	},
 | |
| 
 | |
| 	vertexShader: /* glsl */`
 | |
| 
 | |
| 		varying vec2 vUv;
 | |
| 
 | |
| 		void main() {
 | |
| 
 | |
| 			vUv = uv;
 | |
| 			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 	`,
 | |
| 
 | |
| 	fragmentShader: /* glsl */`
 | |
| 
 | |
| 		uniform float lutSize;
 | |
| 		uniform sampler3D lut;
 | |
| 
 | |
| 		varying vec2 vUv;
 | |
| 		uniform float intensity;
 | |
| 		uniform sampler2D tDiffuse;
 | |
| 		void main() {
 | |
| 
 | |
| 			vec4 val = texture2D( tDiffuse, vUv );
 | |
| 			vec4 lutVal;
 | |
| 
 | |
| 			// pull the sample in by half a pixel so the sample begins
 | |
| 			// at the center of the edge pixels.
 | |
| 			float pixelWidth = 1.0 / lutSize;
 | |
| 			float halfPixelWidth = 0.5 / lutSize;
 | |
| 			vec3 uvw = vec3( halfPixelWidth ) + val.rgb * ( 1.0 - pixelWidth );
 | |
| 
 | |
| 
 | |
| 			lutVal = vec4( texture( lut, uvw ).rgb, val.a );
 | |
| 
 | |
| 			gl_FragColor = vec4( mix( val, lutVal, intensity ) );
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 	`,
 | |
| 
 | |
| };
 | |
| 
 | |
| class LUTPass extends ShaderPass {
 | |
| 
 | |
| 	set lut( v ) {
 | |
| 
 | |
| 		const material = this.material;
 | |
| 
 | |
| 		if ( v !== this.lut ) {
 | |
| 
 | |
| 			material.uniforms.lut.value = null;
 | |
| 
 | |
| 			if ( v ) {
 | |
| 
 | |
| 				material.uniforms.lutSize.value = v.image.width;
 | |
| 				material.uniforms.lut.value = v;
 | |
| 
 | |
| 			}
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	get lut() {
 | |
| 
 | |
| 		return this.material.uniforms.lut.value;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	set intensity( v ) {
 | |
| 
 | |
| 		this.material.uniforms.intensity.value = v;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	get intensity() {
 | |
| 
 | |
| 		return this.material.uniforms.intensity.value;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	constructor( options = {} ) {
 | |
| 
 | |
| 		super( LUTShader );
 | |
| 		this.lut = options.lut || null;
 | |
| 		this.intensity = 'intensity' in options ? options.intensity : 1;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| }
 | |
| 
 | |
| export { LUTPass };
 |