您现在的位置是:主页 > news > 山西省新农村建设网站/营销方案

山西省新农村建设网站/营销方案

admin2025/5/17 15:07:57news

简介山西省新农村建设网站,营销方案,开公司的基本条件,做博彩网站代理犯法吗文章目录实现方式调用成果封装类参考实现方式 three.js的material提供了一个方法用来修改材质 这个方法第一个参数中有材质的glsl代码,在计算前修改材质的glsl代码 插入自己的代码即可以实现自定义shader并且继承提供类的光线,贴图,物理等能…

山西省新农村建设网站,营销方案,开公司的基本条件,做博彩网站代理犯法吗文章目录实现方式调用成果封装类参考实现方式 three.js的material提供了一个方法用来修改材质 这个方法第一个参数中有材质的glsl代码,在计算前修改材质的glsl代码 插入自己的代码即可以实现自定义shader并且继承提供类的光线,贴图,物理等能…

文章目录

        • 实现方式
        • 调用成果
        • 封装类
        • 参考

请添加图片描述

实现方式

three.js的material提供了一个方法用来修改材质
在这里插入图片描述
这个方法第一个参数中有材质的glsl代码,在计算前修改材质的glsl代码 插入自己的代码即可以实现自定义shader并且继承提供类的光线,贴图,物理等能力,不用自己写对应的glsl非常有意思。

以下
封装一个基于THREE.MeshStandardMaterial的材质
通过修改uniform来更改颜色实现上图的效果

调用成果

const cusMaterial = new StandardMaterial({color: 0xccc,uniforms: {time: { value: 0 },},fragmentShader: `gl_FragColor.x += time;
`,
});
const box = new THREE.Mesh(new THREE.BoxGeometry(40, 40, 40, 40, 40, 40),cusMaterial.material
);
scene.add(box);cusMaterial.onRender(() => {cusMaterial.uniforms.time.value = Math.sin(cusMaterial.getElapsedTime());
});

封装类

/** @Author: hongbin* @Date: 2022-12-31 10:53:53* @LastEditors: hongbin* @LastEditTime: 2022-12-31 20:41:09* @Description:修改THREE提供的material加入动画 且具有材质的灯光,贴图,物理渲染等*/
import * as THREE from "three";interface IStandardMaterial extends THREE.MeshStandardMaterialParameters {uniforms?: Record<string, THREE.IUniform<any>>;varyings?: Record<string, { type: string }>;vertexShader?: string;fragmentShader?: string;
}/*** 检测uniform的类型*/
function checkType(key: string, value: THREE.IUniform<any>) {let type = "";switch (typeof value.value) {case "number":type = "float";break;case "object":if (value.value.isVector3 || value.value.isColor) {type = "vec3";break;} else if (value.value.isVector2) {type = "vec2";break;}throw new Error(`无法分辨${key}的类型`);default:throw new Error(`无法分辨${key}的类型`);}return type;
}/*** 生成uniform声明字符串 并且添加uniform*/
function genUniformsStr(uniforms: IStandardMaterial["uniforms"],shader: THREE.Shader
) {let uniformStr = "";//添加uniformsfor (const [key, value] of Object.entries(uniforms ?? {})) {//确保不破坏已有的uniformif (shader.uniforms[key]) {throw new Error(`${key}已在uniforms中`);}shader.uniforms[key] = uniforms![key];//生成uniform 声明// const v = new THREE.Vector3();let type = checkType(key, value);uniformStr += `uniform ${type} ${key};`;}return uniformStr;
}/*** 生成varying声明字符串*/
function genVaryingStr(varyings: IStandardMaterial["varyings"]) {let str = "";for (const [key, value] of Object.entries(varyings ?? {})) {str += `varying ${value.type} ${key};`;}return str;
}const handleShader =(uniforms: IStandardMaterial["uniforms"],varyings: IStandardMaterial["varyings"],vertexShader: IStandardMaterial["vertexShader"],fragmentShader: IStandardMaterial["fragmentShader"]) =>(shader: THREE.Shader) => {// console.log(shader.uniforms);let uniformStr = genUniformsStr(uniforms, shader);let varyingStr = genVaryingStr(varyings);//顶点着色器插入uniforms 和 varyingshader.vertexShader = shader.vertexShader.replace("#include <common>",`${uniformStr}${varyingStr}#include <common>`);//片元着色器插入uniforms 和 varyingshader.fragmentShader = shader.fragmentShader.replace("#include <common>",`${uniformStr}${varyingStr}#include <common>`);// 着色器运算代码vertexShader &&(shader.vertexShader = shader.vertexShader.replace("#include <fog_vertex>",`#include <fog_vertex>${vertexShader}`));fragmentShader &&(shader.fragmentShader = shader.fragmentShader.replace("#include <dithering_fragment>",`#include <dithering_fragment>${fragmentShader}`));// console.log(shader.vertexShader);// console.log(shader.fragmentShader);};/*** 自定义标准材质*/
export class StandardMaterial {uniforms: Record<string, THREE.IUniform<any>> | undefined;material: THREE.MeshStandardMaterial;clock = new THREE.Clock();constructor(parameters: IStandardMaterial = {}) {const { uniforms, varyings, vertexShader, fragmentShader, ...params } =parameters;const material = new THREE.MeshStandardMaterial(params);material.onBeforeCompile = handleShader(uniforms,varyings,vertexShader,fragmentShader);this.uniforms = uniforms;this.material = material;}getDelta() {return this.clock.getDelta();}getElapsedTime() {return this.clock.getElapsedTime();}onRender(call: VoidFunction) {//@ts-ignorethis.material.onBeforeRender = call;}
}

参考

调整材质