Skip to content

案例展示

自定义着色器效果

<template>
  <div id="TO"></div>
</template>

<script setup>
import { onMounted } from 'vue';

onMounted(() => {
  //初始化场景
  let TO = new ThingOrigin("fileModel", document.getElementById("TO"), {
    scene: {
      ground: { // 地面
        active: false,
      },
      background: {
        type: 'color',//设置背景颜色
        color: {
          alpha: 1, // 透明度 取值范围0~1
          color: "#999999",// 背景颜色
        },
      },
    },
    camera: { //相机
      position: {
        x: 0,
        y: 0,
        z: 20,
      }
    },
    lights: [ //设置环境光
      {
        name: "light1",
        type: "AmbientLight",
        color: '#eeeeee',
        intensity: 1,
        visible: true,
        position: {
          x: 150,
          y: 150,
          z: 150,
        },
      },
    ],
    helper: {//辅助工具
      axes: {
        active: false,
      },
      grid: {
        active: false,
      },
    }
  })
  //顶点着色器代码片段(在下面创建着色器材质时,作为参数传入)
  var vertexShader = `
      varying vec2 v_Uv;    //顶点纹理坐标
      void main () {
        v_Uv = uv;
        gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 );
      }
    `

  //片元着色器代码片段(RGBA分量操作,在下面创建着色器材质时,作为参数传入)
  var fragmentShader = `uniform sampler2D e_Texture;
      varying vec2 v_Uv;
      void main () {
        vec4 textureColor = texture2D( e_Texture, v_Uv );
        float green = textureColor.g * 0.0;     //修改颜色值的绿色(G)分量为0
        gl_FragColor = vec4(textureColor.r, green, textureColor.b, 1.0);
      }`

  //加载贴图纹理图像
  var earthTexture = TO.material.initTextureMap({
    url: `${import.meta.env.BASE_URL}img/materials/earth-light.png`,
    mapType: 'map'
  })
  //创建着色器材质
  var shaderMaterial = TO.material.initShaderMaterial({
    vertexShader,
    fragmentShader,
    uniforms: {
      e_Texture: {
        value: earthTexture   //纹理图像
      },
    }
  })
  const sphereRadius = 3;   // 球体半径

  //创建球体
  let model = TO.model.initSphere({
    base: {
      radius: sphereRadius,
      widthSegments: 64,
      heightSegments: 64,
    }
  });
  model.material = shaderMaterial;
  //添加到场景中
  TO.scene.add(model);

  //渲染循环
  var animate = function () {
    requestAnimationFrame(animate)
    // var delta = clock.getDelta()
    model.rotation.y -= 0.02       //整体转动
  }

  animate()
});
</script>

<style scoped>
#TO {
  width: 100%;
  height: 400px;
  position: relative;
}
</style>

API 介绍

material.initShaderMaterial

方法签名返回值描述
initShaderMaterial(params: Partial<ShaderMaterialParameters> = {})ShaderMaterial创建自定义着色器材质

ShaderMaterialParameters 参数说明:

参数名说明类型必填默认值
vertexShader顶点着色器的 GLSL 代码string--
fragmentShader片元着色器的 GLSL 代码string--
uniformsUniforms 变量{ [p: string]: IUniform<any> }--
transparent是否开启透明度boolean-false
side渲染面:FrontSide(正面)、BackSide(背面)、DoubleSide(双面)string-FrontSide
wireframe是否将几何体渲染为线框boolean-false