three 特殊数据库中的 查找表 Lut

511 阅读5分钟

Lut 是一个颜色查找表(Lookup Table)工具,通常用于映射数值到颜色。你可以通过指定一个预定义的调色板(比如 'rainbow')和分辨率(比如 512)来创建一个 Lut 对象。然后,使用 getColor() 方法根据给定的数值(在这个例子中是 0.5)来获取相应的颜色。

  1. 颜色映射和风格化 Lut 常用于根据某种规则对图像或对象的颜色进行映射和风格化处理。在 Three.js 中,它通常被用来根据某些输入(如亮度、深度、时间等)映射到某种预设的颜色调色板上,从而实现图像的色调变化。例如:
    • 亮度映射:可以根据图像的亮度值映射到不同的颜色,使得图像在视觉上具有特定的艺术效果或情感效果。
    • 风格化处理:通过 LUT 可以应用各种艺术风格,如将图片转换为彩虹色调、蓝色调、黑白风格等。
  2. 图像处理和特效 在一些图像特效和图像处理应用中,Lut 是一种常见的工具。例如:
    • 色调映射(Tone Mapping):在高动态范围(HDR)图像处理中,LUT 可以用于将图像的高亮部分压缩到标准动态范围内,控制图像的对比度和亮度。
    • 色彩校正:在摄影或视频处理中,LUT 用于校正图像的颜色,以达到理想的色彩效果。
  3. 数据可视化 在数据可视化中,LUT 可以用来映射数据的数值范围到颜色,从而帮助更好地理解数据分布。例如:
    • 热力图:可以使用 LUT 将数值(如温度、密度等)映射到颜色,以便直观展示数据的分布和变化。
    • 科学可视化:例如,在医学成像、地理信息系统(GIS)或气象数据可视化中,可以通过 LUT 将不同的数值范围映射到不同的颜色,帮助分析和解释数据。
  4. 后处理效果 在 Three.js 等 3D 引擎中,LUT 可以用来对渲染结果进行后期处理,例如:
    • 后处理颜色调整:在渲染场景后,可以使用 LUT 对图像进行后期色调、对比度、饱和度等调整。
    • 电影效果和滤镜:使用 LUT 可以模仿电影中的色彩滤镜效果,为场景增添特定的视觉风格。
  5. 模拟不同的摄影效果 在一些 3D 渲染中,可以使用 LUT 模拟不同的摄影效果,如胶片模拟、复古色调等,这些效果在影视制作、游戏设计中尤为常见。

Lut 有五个属性八个方法

Lut( colormap : String, count : Number )
    colormap - 设置预定义色彩映射中的一个。可用的色彩映射有:rainbow, cooltowarm, blackbody, grayscale。 默认为 rainbow。
    count - 设置用于表示数据数组的颜色数量。默认为 32// 以下为一个改变图片风格的示例
<template>
    <div id="parkingLot" ref="parkingLot">
    </div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import * as THREE from 'three';
import { Lut } from 'three/addons/math/Lut.js';
import person from "@public/person.jpg"
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js';
const parkingLot = ref();

onMounted(async () => {
    const DOMEl = parkingLot.value;
    // 获取 DOMEl 的宽度和高度,以设置渲染器的大小。
    const width = DOMEl.clientWidth;
    const height = DOMEl.clientHeight;

    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize( width, height );
    renderer.localClippingEnabled = true; 
    // 启用阴影
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 阴影类型
    DOMEl.appendChild( renderer.domElement );
    const scene = new THREE.Scene();
    renderer.setClearColor(0x000000);
    const camera = new THREE.PerspectiveCamera( 75, width / height, 0.1, 1000 );
    camera.position.set( 0, 80, 0 );
    camera.lookAt( 0, 0, 0 );


    // 创建一个 LUT 实例,选择 'rainbow' 调色板,分辨率为 512
    const lut = new Lut('rainbow', 512);
    const color = lut.getColor(0.5);
    console.log(color);  // 输出调色板中的颜色

    // 使用 TextureLoader 加载图片
    const textureLoader = new THREE.TextureLoader();
    const texture = textureLoader.load(person, () => {
        // 图片加载完成后,创建一个 PlaneGeometry
        const geometry = new THREE.PlaneGeometry(200, 200); // 设置平面的大小
        const material = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide });
        const plane = new THREE.Mesh(geometry, material);
        plane.position.set(0, 50, 0);  // 设置平面位置,使其位于相机前面
        scene.add(plane);

        // 获取图片像素数据
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = texture.image.width;
        canvas.height = texture.image.height;
        ctx.drawImage(texture.image, 0, 0);
        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        const data = imageData.data;

        // 遍历每个像素并应用 LUT 颜色
        for (let i = 0; i < data.length; i += 4) {
        const r = data[i] / 255;  // 归一化为 [0, 1]
        const g = data[i + 1] / 255;
        const b = data[i + 2] / 255;
        const brightness = (r + g + b) / 3;  // 获取亮度值

        // 获取 LUT 映射后的颜色
        const mappedColor = lut.getColor(brightness);

        // 更新像素颜色
        data[i] = mappedColor.r * 255;
        data[i + 1] = mappedColor.g * 255;
        data[i + 2] = mappedColor.b * 255;
        }

        // 更新 canvas 上的图像数据,并重新加载纹理
        ctx.putImageData(imageData, 0, 0);
        texture.image = canvas;  // 更新纹理的图像数据
        texture.needsUpdate = true;  // 标记纹理为需要更新
    });

    // 添加光源
    const light = new THREE.DirectionalLight(0xffffff, 1);
    light.position.set(100, 100, 100).normalize();
    light.castShadow = true;
    scene.add(light);

    // 创建 OrbitControls 实例
    const controls = new OrbitControls(camera, renderer.domElement);
    // 设置控制器的目标点
    controls.target.set(0, 0, 0); // 将目标点设置为立方体的中心
    function animate() {
        requestAnimationFrame(animate);
        controls.update(); // 更新 OrbitControls
        renderer.render(scene, camera);
    }
    animate();
});

</script>
<style lang="scss" scoped="scoped">

    #parkingLot {
        width: 940px;
        height: 940px;
        border: 1px solid #ccc;
        margin: 30px auto;
    }

</style>

属性

  • lut : Array 所选颜色映射的查找表,表示为 Color 数组。
  • map : Array 当前选择的颜色映射。默认是 rainbow。
  • minV : Number 用查找表表示的最小值。默认值为 0。
  • maxV : Number 用查找表表示的最大值。默认值为 1。
  • n : Number 当前所选颜色映射的颜色数。默认为 32。

方法

  • copy ( lut : Lut ) : this this : Lut color — Lut 复制。 复制给定的 lut。
  • addColorMap ( name : String, arrayOfColors : Array ) : this name — 颜色映射的名称。 arrayOfColors — 颜色值数组。每个值都是一个数组,其中包含阈值和十六进制数形式的实际颜色值。 将一个颜色映射添加到此 Lut 实例。
  • createCanvas () : HTMLCanvasElement 创建一个画布以将查找表可视化为纹理。
  • getColor ( alpha : Number ) : Color value -- 要显示为颜色的数据值。 返回给定数据值的 Color 实例。
  • setColorMap ( colormap : String, count : Number ) : this colormap — 颜色映射的名称。 count — 颜色的数量。默认为 32。 为给定的颜色映射和颜色数量配置查找表。
  • setMin ( minV : Number ) : this minV — 用查找表表示的最小值 设置此 Lut 的表示最小值。
  • setMax ( maxV : Number ) : this maxV — 用查找表表示的最大值。 设置此 Lut 的表示最大值。
  • updateCanvas ( canvas : HTMLCanvasElement ) : HTMLCanvasElement 使用 Lut 的数据更新画布。