Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              <head>
    <meta charset="utf-8">
    <title>show room</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        #container {
            position:fixed;
            width:100%;
            height:100%;
            margin: 0;
            padding:0;
        }

    </style>
</head>
<body>
    <div id="container"></div>

    <script>
        
    </script>
</body>
            
          
!
            
              


(function(undefined) {
    "use strict";
    let _global;
    let textureMix = function( renderer, settings ){

        let defualtSettings = {
            width: 512,
            height: 512,
            textures: [],
            textureGroup: [],
            cameraPositions: [],// 可传入的一组相机位置值 可以通过其对传入内容进行切割 并分配为纹理放入一个纹理数组中 有多少个位置就有多少个纹理图片 需要根据其生成多个rendererTarget
            cameraPosition: new THREE.Vector2( 0, 0 ),
            size: 1,
            loadingManager: null,
            type: THREE.UnsignedByteType
        };

        settings = Object.assign(defualtSettings, settings);
        if (!renderer) {
            console.alert('renderer is needed');
        } else {
            this.renderer = renderer;
        }

        this.loadingManager = settings.loadingManager ? settings.loadingManager : THREE.DefaultLoadingManager;

        this.renderTarget = new THREE.WebGLRenderTarget( settings.width, settings.height,{
            type: settings.type
        } );
        this.texture = this.renderTarget.texture;
        this.textures = [];
        this.renderGroup = [];
        this.scene = new THREE.Scene();
        this.initClips( settings.cameraPositions, settings );

        let shaderText = {
            vertexShader:`
            varying vec2 vUv;
            void main()
                {
                    vUv = uv;
                    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
                    gl_Position = projectionMatrix * mvPosition;
                }
            `,
            fragmentShader : `
            #ifdef GL_ES
            precision mediump float;
            precision highp float;
            #endif
    
            #define PI 3.14159265359
            #define TWO_PI 6.28318530718
            //#define LUMINANCE_PRESERVATION 0.75
            
            //#define EPSILON 1e-10
            
            float x(float v) { return clamp(v, 0.0,       1.0);       }
            vec2  x(vec2  v) { return clamp(v, vec2(0.0), vec2(1.0)); }
            vec3  x(vec3  v) { return clamp(v, vec3(0.0), vec3(1.0)); }
            vec4  x(vec4  v) { return clamp(v, vec4(0.0), vec4(1.0)); }
    
            uniform vec2 u_resolution;
            uniform vec2 u_mouse;
            uniform float u_time;
            
            uniform float temperature;
    
            uniform float u_one;
            uniform float u_two;
            uniform float u_three;
            uniform float u_four;
            uniform float u_five;
            uniform float u_six;
            uniform float u_seven;
            uniform float u_eight;
            uniform float u_nine;
            uniform float u_ten;
            uniform float u_eleven;
            uniform float u_twelve;
            uniform float u_thirteen;
            uniform float u_fourteen;
            uniform float u_fifteen;
            uniform float u_sixteen;
    
            uniform sampler2D tOne;
            uniform sampler2D tTwo;
            uniform sampler2D tThree;
            uniform sampler2D tFour;
            uniform sampler2D tFive;
            uniform sampler2D tSix;
            uniform sampler2D tSeven;
            uniform sampler2D tEight;
            uniform sampler2D tNine;
            uniform sampler2D tTen;
            uniform sampler2D tEleven;
            uniform sampler2D tTwelve;
            uniform sampler2D tThirteen;
            uniform sampler2D tFourteen;
            uniform sampler2D tFifteen;
            uniform sampler2D tSixteen;
            uniform sampler2D tSeventeen;
    
            varying vec2 vUv;
            
            // Color temperature (sRGB) stuff
            // Copyright (C) 2014 by Benjamin 'BeRo' Rosseaux
            // Because the german law knows no public domain in the usual sense,
            // this code is licensed under the CC0 license 
            // http://creativecommons.org/publicdomain/zero/1.0/

            /*vec3 colorTemperatureToRGB(const in float temperature){
                mat3 m = (temperature <= 6500.0) ? mat3(vec3(0.0, -2902.1955373783176, -8257.7997278925690),
                                                    vec3(0.0, 1669.5803561666639, 2575.2827530017594),
                                                    vec3(1.0, 1.3302673723350029, 1.8993753891711275)) : 
                                                 mat3(vec3(1745.0425298314172, 1216.6168361476490, -8257.7997278925690),
                                                    vec3(-2666.3474220535695, -2173.1012343082230, 2575.2827530017594),
                                                    vec3(0.55995389139931482, 0.70381203140554553, 1.8993753891711275)); 
                return mix(clamp(vec3(m[0] / (vec3(clamp(temperature, 1000.0, 40000.0)) + m[1]) + m[2]), vec3(0.0), vec3(1.0)), vec3(1.0), smoothstep(1000.0, 0.0, temperature));
            }*/
            
            
            

            
            vec3 ColorTemperatureToRGB(float temperatureInKelvins)
            {
                vec3 retColor;
            
                temperatureInKelvins = clamp(temperatureInKelvins, 1000.0, 40000.0) / 100.0;
            
                if (temperatureInKelvins <= 66.0)
                {
                    retColor.r = 1.0;
                    retColor.g = x(0.39008157876901960784 * log(temperatureInKelvins) - 0.63184144378862745098);
                }
                else
                {
                    float t = temperatureInKelvins - 60.0;
                    retColor.r = x(1.29293618606274509804 * pow(t, -0.1332047592));
                    retColor.g = x(1.12989086089529411765 * pow(t, -0.0755148492));
                }
            
                if (temperatureInKelvins >= 66.0)
                retColor.b = 1.0;
                else if(temperatureInKelvins <= 19.0)
                retColor.b = 0.0;
                else
                retColor.b = x(0.54320678911019607843 * log(temperatureInKelvins - 10.0) - 1.19625408914);
            
                return retColor;
            }
    
            void main(){
                vec2 st = gl_FragCoord.xy/u_resolution;
    
                vec4 t1 = texture2D(tOne, vUv) * u_one;
                vec4 t2 = texture2D(tTwo, vUv) * u_two;
                vec4 t3 = texture2D(tThree, vUv) * u_three;
                vec4 t4 = texture2D(tFour, vUv) * u_four;
                vec4 t5 = texture2D(tFive, vUv) * u_five;
                vec4 t6 = texture2D(tSix, vUv) * u_six;
                vec4 t7 = texture2D(tSeven, vUv) * u_seven;
                vec4 t8 = texture2D(tEight, vUv) * u_eight;
                vec4 t9 = texture2D(tNine, vUv) * u_nine;
                vec4 t10 = texture2D(tEleven, vUv) * u_ten;
                vec4 t11 = texture2D(tTwelve, vUv) * u_eleven;
                vec4 t12 = texture2D(tThirteen, vUv) * u_twelve;
                vec4 t13 = texture2D(tFourteen, vUv) * u_thirteen;
                vec4 t14 = texture2D(tFifteen, vUv) * u_fourteen;
                vec4 t15 = texture2D(tSixteen, vUv) * u_fifteen;
                vec4 t16 = texture2D(tSeventeen, vUv) * u_sixteen;
    
                vec3 c;
                float a = 1.0;
                
                vec3 colorTempRGB = ColorTemperatureToRGB(temperature);
    
                c =  t1.rgb + t2.rgb + t3.rgb + t4.rgb + t5.rgb + t6.rgb + t7.rgb + t8.rgb + t9.rgb + t10.rgb + t11.rgb + t12.rgb + t13.rgb + t14.rgb + t15.rgb + t16.rgb;
                c = c * colorTempRGB;
                gl_FragColor = vec4(c, a);
            }
            `
        };

        this.uniforms = this.initUniforms(settings.textures);

        this.camera = new THREE.Camera();
        this.camera.position.z = 1;
        this.camera.position.x = settings.cameraPosition.x;
        this.camera.position.y = settings.cameraPosition.y;

        // 尝试使用OrthographicCamera

        this.plane = new THREE.PlaneBufferGeometry( 2 * settings.size, 2 * settings.size * (settings.height) / (settings.width) );

        let mixShaderMaterial = new THREE.ShaderMaterial({
            uniforms: this.uniforms,
            vertexShader: shaderText.vertexShader,
            fragmentShader: shaderText.fragmentShader,
            transparent: true
        });

        let planeMesh = new THREE.Mesh( this.plane, mixShaderMaterial );

        this.scene.add( planeMesh );
    };
    /**
     * @description 根据传入的图片混合并放入一个uniform中
     * @param textures {THREE.Texture} 传入的纹理图片
     * @returns {uniforms}
     */
    textureMix.prototype.initUniforms = function(textures){
        let uniforms = {
            u_time: { type: "f", value: 1.0 },
            u_resolution: { type: "v2", value: new THREE.Vector2() },
            u_mouse: { type: "v2", value: new THREE.Vector2() },
            temperature: { type: "f", value: 6500 }
        };
        let uNameArr = [
            'u_one','u_two','u_three','u_four','u_five','u_six','u_seven','u_eight',
            'u_nine','u_ten','u_eleven','u_twelve','u_thirteen','u_fourteen','u_fifteen','u_sixteen'
        ];
        let tNameArr =  [
            'tOne','tTwo','tThree','tFour','tFive','tSix','tSeven','tEight',
            'tNine','tTen','tEleven','tTwelve','tThirteen','tFourteen','tFifteen','tSixteen'
        ];
        if ( textures && textures.length > 0 ) {
            for ( let i = 0; i < textures.length; i++ ) {
                uniforms[uNameArr[i]] = { type: "f", value: 1.0 };
                uniforms[tNameArr[i]] = { type: "f", value: textures[i] };
            }
        }
        return uniforms;
    };
    /**
     * @description 渲染纹理场景的方法,如果传入了index 数组或者 数 则会渲染在渲染列表中的内容,
     * @param index {Array|Number}
     */
    textureMix.prototype.render = function(index) {
        if (  Number.isInteger(index) ) {
            let target = this.renderGroup[index];
            if (target) {
                this.singleRender( target.renderTarget, target.camera );
            } else {
                console.warn('index is incorrect')
            }
        } else if ( Array.isArray(index) ){
            for ( let i of index ) {
                if ( Number.isInteger(i) ){
                    let target = this.renderGroup[i];
                    if ( target ) {
                        this.singleRender( target.renderTarget, target.camera );
                    }
                }
            }
        } else {
            this.singleRender( this.renderTarget, this.camera );
        }
    };
    /**
     * @description 渲染更新整个内容 包括不同相机的切片图片以及总图片
     */
    textureMix.prototype.renderAll = function(){
        this.singleRender( this.renderTarget, this.camera );

        for (let target of this.renderGroup ) {
            if ( target ) {
                this.singleRender( target.renderTarget, target.camera );
            }
        }
    };
    /**
     * @description 渲染单个target的方法 render single target
     * @param target {THREE.WebGLRenderTarget} 缓冲目标
     * @param camera {THREE.Camera} 相机
     */
    textureMix.prototype.singleRender = function(target, camera){
        this.renderer.setRenderTarget( target );
        this.renderer.render( this.scene, camera );
        this.renderer.setRenderTarget( null );
        this.renderer.clear();
    };
    /**
     * @description 根据多个相机位置以及大小的设定 生成一系列的图片切割片段并存入当前实例下的内容中
     * @param cameraPositions
     * @param targetSetting
     */
    textureMix.prototype.initClips = function( cameraPositions, targetSetting){
        if ( cameraPositions && cameraPositions.length > 0 ) {
            for ( let cameraPosition of cameraPositions ) {
                if ( cameraPosition && cameraPosition.isVector2 ) {
                    let camera = new THREE.OrthographicCamera(-1,1,1,-1,0,2);
                    camera.position.z = 1;
                    camera.position.x = cameraPosition.x;
                    camera.position.y = cameraPosition.y;

                    let renderTarget;
                    if (targetSetting) {
                        renderTarget = new THREE.WebGLRenderTarget(
                            parseInt( targetSetting.width ),
                            parseInt( targetSetting.height )
                        );
                    }else {
                        renderTarget = new THREE.WebGLRenderTarget(
                            parseInt( targetSetting.width ),
                            parseInt( targetSetting.height )
                        );
                    }
                    this.renderGroup.push({
                        camera,
                        renderTarget
                    });
                    this.textures.push(renderTarget.texture);
                }
            }
        }
    };
    _global = (function(){ return this || ( 0, eval )('this'); }());
    if (typeof module !== "undefined" && module.exports) {
        module.exports = textureMix;
    } else if (typeof define === "function" && define.amd) {
        define(function(){return textureMix;});
    } else {
        !('textureMix' in _global) && (_global.textureMix = textureMix);
    }
}());


var container;
var camera, scene, scene2, renderer;
var uniforms;
var mix,mix2;
var controls;
var gui;
let materials = [];
var guiData = {
  toneMapping: 5.0,
  temperature: 6600.0,
  t1: 1.0,
  t2: 1.0,
  t3: 1.0,
  t4: 1.0,
  t5: 1.0,
  t6: 1.0,
  t7: 1.0,
  t8: 1.0,
  t9: 1.0,
  t10: 1.0,
  t11: 1.0,
  t12: 1.0,
  t13: 1.0,
  t14: 1.0,
  t15: 1.0,
  t16: 1.0,
  times: 0,
  needsUpdate: false,
  start: false
};

init();
animate();

function init() {
  container = document.getElementById( 'container' );

  camera = new THREE.PerspectiveCamera(60, window.innerWidth/2/window.innerHeight, 0.01, 20);
  camera.position.set( 0, 0, 2 );
  camera.lookAt( new THREE.Vector3( 0, 0, 0 ) );

  scene = new THREE.Scene();

  scene2 = new THREE.Scene();


  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setClearAlpha(0);
  renderer.setClearColor(new THREE.Color(0,0,0,0));
  renderer.toneMapping = THREE.Uncharted2ToneMapping;
  renderer.toneMappingExposure = 8;

  var loadingManager = new THREE.LoadingManager();
  loadingManager.onProgress = function (url, finished, all) {
    console.log(`loading${url}, ${finished}finished, total${all}`);
  };

  let textureLoader = new THREE.TextureLoader(loadingManager);
  let rgbeLoader = new THREE.RGBELoader(loadingManager);
  rgbeLoader.setDataType(THREE.FloatType);
  let textures = [
    rgbeLoader.load('https://towrabbit.oss-cn-beijing.aliyuncs.com/js/three/imgs/hdr/SM_YZG_Wall_A_197VRay_1.HDR'),
    rgbeLoader.load('https://towrabbit.oss-cn-beijing.aliyuncs.com/js/three/imgs/hdr/SM_YZG_Wall_A_197VRay_2.HDR'),
    rgbeLoader.load('https://towrabbit.oss-cn-beijing.aliyuncs.com/js/three/imgs/hdr/SM_YZG_Wall_A_197VRay_3.HDR'),
  ];
  let textures2 = [
    textureLoader.load('https://towrabbit.oss-cn-beijing.aliyuncs.com/js/three/imgs/png/SM_YZG_Wall_A_197VRay_1.jpg'),
    textureLoader.load('https://towrabbit.oss-cn-beijing.aliyuncs.com/js/three/imgs/png/SM_YZG_Wall_A_197VRay_2.jpg'),
    textureLoader.load('https://towrabbit.oss-cn-beijing.aliyuncs.com/js/three/imgs/png/SM_YZG_Wall_A_197VRay_3.jpg')
  ]
  for (let texture of textures) {
    //texture.minFilter = THREE.NearestFilter;
    //texture.magFilter = THREE.NearestFilter;
  }

  mix = new textureMix(renderer,{
    textures:textures2,
    loadingManager,
    width:1024,
    height:1024,
  });

  mix2 = new textureMix(renderer,{
    textures:textures,
    loadingManager,
    width:1024,
    height:1024,
    type:THREE.HalfFloatType
  });


  let planeG = new THREE.PlaneBufferGeometry(2,2);
  let planeM = new THREE.MeshBasicMaterial({
    map: mix.texture,
  });
  let planeM2 = new THREE.MeshBasicMaterial({
    map: mix2.texture
  });
  let plane = new THREE.Mesh(planeG,planeM);
  let plane2 = new THREE.Mesh(planeG,planeM2);

  scene2.add(plane2);

  scene.add(plane);

  container.appendChild( renderer.domElement );

  function renderFirstFrame(){
    mix.renderAll();
    mix2.renderAll();
    render();
  }

  controls = new THREE.OrbitControls( camera, renderer.domElement );
  addDataGui();

  loadingManager.onLoad = function(){
    renderFirstFrame();
  };

  onWindowResize();
  window.addEventListener( 'resize', onWindowResize, false );

}

function addDataGui() {
  gui = new dat.GUI();
  gui.add(guiData, 'toneMapping', 0, 10, 0.1).name('exposure').onChange(function (value) {
    renderer.toneMappingExposure = value;
  });
  gui.add(guiData, 't1', 0, 1, 0.01).name('0').onChange(function(value) {
    if (guiData.start === false) {
      guiData.start = true;
      guiData.times =  0;
    }
    guiData.times +=1;
    mix.uniforms.u_one.value = value;
    mix2.uniforms.u_one.value = value;
    guiData.needsUpdate = true;
  }).onFinishChange(function (value) {
    guiData.start = false;
  });
  gui.add(guiData, 't2', 0, 1, 0.01).name('1').onChange( function(value) {
    mix.uniforms.u_two.value = value;
    mix2.uniforms.u_two.value = value;
    guiData.needsUpdate = true;
  });
  gui.add(guiData, 't3', 0, 1, 0.01).name('2').onChange( function(value) {
    mix.uniforms.u_three.value = value;
    mix2.uniforms.u_three.value = value;
    guiData.needsUpdate = true;
  });
}

function onWindowResize( event ) {
  renderer.setSize( window.innerWidth, window.innerHeight );
  camera.aspect = window.innerWidth / 2 / window.innerHeight;
  camera.updateProjectionMatrix();
}

function animate() {
  requestAnimationFrame( animate );

  render();
}



function render() {

  if (guiData.needsUpdate === true) {
    mix.renderAll();
    mix2.renderAll();
    guiData.needsUpdate = false;
  }

  renderer.setClearColor(0x000000);
  renderer.setScissorTest(false);
  renderer.clear();
  renderer.setScissorTest(true);

  let width = renderer.domElement.offsetWidth;
  let height = renderer.domElement.offsetHeight;
  renderer.setScissor(0,0,width/2,height);
  renderer.setViewport(0,0,width/2,height);
  renderer.render(scene,camera);

  renderer.setScissor(width / 2, 0, width / 2, height);
  renderer.setViewport(width / 2, 0, width / 2, height);
  renderer.render(scene2, camera);

  //renderer.render( scene, camera );
}
            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.

Console