代码:https://gitee.com/honbingitee/three-template-next.js/tree/shader/
参考油管视频:https://www.youtube.com/watch?v=oKbCaj1J6EI
核心: 创建循环的图形 应用噪声 顶点按照法相偏移
CustomMaterial(): ShaderMaterial {
const material = new ShaderMaterial({
side: DoubleSide,
uniforms: {
iTime: { value: 1 },
},
vertexShader: `
uniform float iTime;
varying vec3 vNormal;
varying vec3 vColor;
#define PI 3.141592653589793
${perlinNoiseFragment}
${smoothModFragment}
${fitFragment}
void main() {
vec3 transformed = position;
vNormal = normal;
//vec3 myNormal = normal * 3. ;
vec3 myNormal = normal ;
myNormal.y += iTime;
float noiseValue = noise(myNormal) ;
float pattern = fit(smoothMod(noiseValue * 5.,1.0,1.5),0.4,0.6,0.,1.);
transformed += vec3(pattern) * normal;
vColor = vec3(pattern);
vec4 modelViewPosition = modelViewMatrix * vec4(transformed, 1.0);
gl_Position = projectionMatrix * modelViewPosition;
}`,
fragmentShader: `
varying vec3 vNormal;
varying vec3 vColor;
void main() {
vec3 color = vec3(vColor);
gl_FragColor = vec4(color, 1.0);
}`,
});
return material;
}
替换MeshStandardMaterial
ReplaceMaterial(): MeshStandardMaterial {
const material = new MeshStandardMaterial({
color: "#aaa",
emissive: "#ff3311",
metalness: 0.5,
roughness: 0.5,
});
material.onBeforeCompile = (shader) => {
Object.assign(shader.uniforms, this.appendUniforms);
shader.vertexShader = shader.vertexShader.replace(
"#include <common>",
`
#include <common>
uniform float iTime;
uniform float iStepCount;
#define PI 3.141592653589793
${perlinNoiseFragment}
${smoothModFragment}
${fitFragment}
`
);
shader.vertexShader = shader.vertexShader.replace(
"#include <begin_vertex>",
`
#include <begin_vertex>
vec3 myNormal = normal;
myNormal.y += iTime;
float noiseValue = noise(myNormal);
float pattern = fit(smoothMod(noiseValue * iStepCount,1.0,1.5),0.4,0.6,0.,1.);
transformed += vec3(pattern) * normal;
`
);
};
return material;
}