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 }; |