diff --git a/examples/jsm/postprocessing/LUTPass.js b/examples/jsm/postprocessing/LUTPass.js index f4f3f34b0ca6ce..c01431f4438958 100644 --- a/examples/jsm/postprocessing/LUTPass.js +++ b/examples/jsm/postprocessing/LUTPass.js @@ -1,108 +1,111 @@ import { ShaderPass } from './ShaderPass.js'; -const LUTShader = { +const LUTShader = function(isWebGL2) { - defines: { - USE_3DTEXTURE: 1, - }, + return { - uniforms: { - lut3d: { value: null }, + defines: { + USE_3DTEXTURE: isWebGL2 + }, - lut: { value: null }, - lutSize: { value: 0 }, + uniforms: { + lut3d: { value: null }, - tDiffuse: { value: null }, - intensity: { value: 1.0 }, - }, + lut: { value: null }, + lutSize: { value: 0 }, - vertexShader: /* glsl */` + tDiffuse: { value: null }, + intensity: { value: 1.0 }, + }, - varying vec2 vUv; + vertexShader: /* glsl */` - void main() { + varying vec2 vUv; - vUv = uv; - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + void main() { - } - - `, - - - fragmentShader: /* glsl */` - precision highp sampler3D; - - uniform float lutSize; - #if USE_3DTEXTURE - uniform sampler3D lut3d; - #else - uniform sampler2D lut; - - vec3 lutLookup( sampler2D tex, float size, vec3 rgb ) { - - float sliceHeight = 1.0 / size; - float yPixelHeight = 1.0 / ( size * size ); - - // Get the slices on either side of the sample - float slice = rgb.b * size; - float interp = fract( slice ); - float slice0 = slice - interp; - float centeredInterp = interp - 0.5; - - float slice1 = slice0 + sign( centeredInterp ); - - // Pull y sample in by half a pixel in each direction to avoid color - // bleeding from adjacent slices. - float greenOffset = clamp( rgb.g * sliceHeight, yPixelHeight * 0.5, sliceHeight - yPixelHeight * 0.5 ); + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); - vec2 uv0 = vec2( - rgb.r, - slice0 * sliceHeight + greenOffset - ); - vec2 uv1 = vec2( - rgb.r, - slice1 * sliceHeight + greenOffset - ); - - vec3 sample0 = texture2D( tex, uv0 ).rgb; - vec3 sample1 = texture2D( tex, uv1 ).rgb; + } - return mix( sample0, sample1, abs( centeredInterp ) ); + `, - } - #endif - varying vec2 vUv; - uniform float intensity; - uniform sampler2D tDiffuse; - void main() { + get fragmentShader() { + let shader = ''; + shader += this.defines.USE_3DTEXTURE ? ` + precision highp sampler3D; + ` : ` + `; + shader += ` + uniform float lutSize; + `; + shader += this.defines.USE_3DTEXTURE ? ` + uniform sampler3D lut3d; + ` : ` + uniform sampler2D lut; - vec4 val = texture2D( tDiffuse, vUv ); - vec4 lutVal; + vec3 lutLookup( sampler2D tex, float size, vec3 rgb ) { - // 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 ); + float sliceHeight = 1.0 / size; + float yPixelHeight = 1.0 / ( size * size ); - #if USE_3DTEXTURE + // Get the slices on either side of the sample + float slice = rgb.b * size; + float interp = fract( slice ); + float slice0 = slice - interp; + float centeredInterp = interp - 0.5; - lutVal = vec4( texture( lut3d, uvw ).rgb, val.a ); + float slice1 = slice0 + sign( centeredInterp ); - #else + // Pull y sample in by half a pixel in each direction to avoid color + // bleeding from adjacent slices. + float greenOffset = clamp( rgb.g * sliceHeight, yPixelHeight * 0.5, sliceHeight - yPixelHeight * 0.5 ); - lutVal = vec4( lutLookup( lut, lutSize, uvw ), val.a ); + vec2 uv0 = vec2( + rgb.r, + slice0 * sliceHeight + greenOffset + ); + vec2 uv1 = vec2( + rgb.r, + slice1 * sliceHeight + greenOffset + ); - #endif + vec3 sample0 = texture2D( tex, uv0 ).rgb; + vec3 sample1 = texture2D( tex, uv1 ).rgb; - gl_FragColor = vec4( mix( val, lutVal, intensity ) ); - - } - - `, + return mix( sample0, sample1, abs( centeredInterp ) ); + } + `; + shader += ` + 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 ); + `; + shader += this.defines.USE_3DTEXTURE ? ` + lutVal = vec4( texture( lut3d, uvw ).rgb, val.a ); + ` : ` + lutVal = vec4( lutLookup( lut, lutSize, uvw ), val.a ); + `; + shader += ` + gl_FragColor = vec4( mix( val, lutVal, intensity ) ); + + }` + return shader; + }, + } }; class LUTPass extends ShaderPass { @@ -117,10 +120,11 @@ class LUTPass extends ShaderPass { if ( v ) { - const is3dTextureDefine = v.isDataTexture3D ? 1 : 0; + const is3dTextureDefine = v.isDataTexture3D ? true : false; if ( is3dTextureDefine !== material.defines.USE_3DTEXTURE ) { material.defines.USE_3DTEXTURE = is3dTextureDefine; + material.fragmentShader = LUTShader(is3dTextureDefine).fragmentShader; material.needsUpdate = true; } @@ -161,8 +165,7 @@ class LUTPass extends ShaderPass { } constructor( options = {} ) { - - super( LUTShader ); + super(LUTShader(true)); this.lut = options.lut || null; this.intensity = 'intensity' in options ? options.intensity : 1; diff --git a/examples/webgl_postprocessing_3dlut.html b/examples/webgl_postprocessing_3dlut.html index 9fac22dd0c02ae..deb42bcffe9354 100644 --- a/examples/webgl_postprocessing_3dlut.html +++ b/examples/webgl_postprocessing_3dlut.html @@ -34,7 +34,7 @@ enabled: true, lut: 'Bourbon 64.CUBE', intensity: 1, - use2dLut: false, + use2DLut: false, }; const lutMap = { @@ -137,7 +137,8 @@ if ( renderer.capabilities.isWebGL2 ) { - gui.add( params, 'use2dLut' ); + gui.add( params, 'use2DLut' ); + params.use2DLut = false; } else { @@ -161,7 +162,6 @@ } - // function render() {