Skip to content

案例展示

自定义着色器效果

TIP

经典 GLSL ShaderMaterial 仅 WebGL 模式可用(renderer: 'webgl')。

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

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

onMounted(() => {
    // 经典 GLSL ShaderMaterial 仅兼容 WebGL
    new ThingOrigin(
        'fileModel',
        document.getElementById('TO'),
        {
            scene: {
                renderQuality: {
                    renderer: 'webgl'
                },
                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
                }
            }
        },
        async (TO) => {
            //顶点着色器代码片段(在下面创建着色器材质时,作为参数传入)
            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 = await 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