Threejs实现加载模型的一些效果
中心渐变网格地板
const {
size = 10,
divisions = 10,
colorCenterLine = new THREE.Color('#444444'),
colorGrid = new THREE.Color('#CCCCCC'),
position,
alpha,
planeAlpha = 0.5,
centerColor = new THREE.Color('#282A2F'),
edgeColor = new THREE.Color('#171F26'),
} = options.gridOptions
const gridHelper = new THREE.GridHelper(size, divisions, colorCenterLine, colorGrid)
const pos = position.toThreeJSPosition()
gridHelper.position.copy(pos)
if (alpha) {
gridHelper.material.transparent = true
gridHelper.material.opacity = alpha
}
/**
* varying 是 GLSL 中的一种变量类型,用于在顶点着色器和片元着色器之间传递数据。
* vUv 是一个二维向量,用于存储纹理坐标(UV 坐标)。
* uv 是 Three.js 提供的默认纹理坐标,范围是 [0, 1]
* gl_Position 是 GLSL 的内置变量,表示顶点的最终位置。
* projectionMatrix 是投影矩阵,将 3D 坐标转换为 2D 屏幕坐标。
* modelViewMatrix 是模型视图矩阵,将模型坐标转换为相机坐标。
* position 是顶点的原始位置。
* 通过矩阵乘法将顶点位置转换到裁剪空间。
*
* smoothstep(float t1,float t2,float x) 是 GLSL 的内置函数,用于生成平滑的过渡效果。x取 0 -> 1,smoothstep()取 t1 -> t2
* mix(x,y,a) 是一个用于线性插值的内置函数。a取0->1,mix()取x -> 0.5x+0.5y -> y
* */
// 定义 uniforms
const uniforms = {
u_centerRange: {type:'f', value: 0.4 }, // 白色区域的半径
u_centerColor: {type:'c', value: new THREE.Vector3(centerColor.r, centerColor.g, centerColor.b) }, // 中心颜色
u_edgeColor: {type:'c', value: new THREE.Vector3(edgeColor.r, edgeColor.g, edgeColor.b) }, // 边缘颜色
u_alpha: { value: planeAlpha }, // 透明度
}
// 创建渐变材质
const gradientMaterial = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}`,
fragmentShader: `
uniform float u_centerRange;
uniform float u_alpha;
uniform vec3 u_centerColor;
uniform vec3 u_edgeColor;
varying vec2 vUv;
void main() {
// 计算当前片元到中心的距离
float distanceFromCenter = length(vUv - ve2(0.5, 0.5));
// 调整中心渐变范围(TODO:可以修改为具体距离控制)
float gradient = 1.0 - smoothstep(0.0, u_centerRange, distanceFromCenter);
// 可以调整颜色亮度
// gradient = gradient * 0.4; // 将白色亮度降低到40%
// 定义中心颜色 RGB 值
// vec3 centerColor = vec3(0.155, 0.165, 0.185);
// 定义边缘颜色 RGB 值
// vec3 edgeColor = vec3(0.045, 0.06, 0.075);
// 混合中心和边缘颜色
// vec3 finalColor = mix(edgeColor, centerColor, gradient);//vec3(gradient)
vec3 finalColor = mix(u_edgeColor, u_centerColor, gradient);//vec3(gradient)
// 颜色转rgba
gl_FragColor = vec4(vec3(finalColor), u_alpha);
}`,
side: THREE.FrontSide,
})
// 创建地板平面
const floorGeometry = new THREE.PlaneGeometry(size, size, divisions, divisions)
const floorMesh = new THREE.Mesh(floorGeometry, gradientMaterial)
floorMesh.rotation.x = -Math.PI / 2 // 旋转平面使其水平
floorMesh.position.copy(pos)
水印功能(水印不遮挡模型)
1.设置threejs场景背景透明
// 设置threejs场景背景透明
const scene = new THREE.Scene()
scene.background = null
const renderer = new THREE.WebGLRenderer({ alpha:true })
renderer.setClearAlpha(0)
2.设置水印
.watermark {
/* 水印位置 */
position: absolute;
width: 100%;
height: 100%;
top: 0px;
right: 0px;
/* 平铺 */
background-color: #171f26;
background-size: 200px 200px;
background-image: url("watermark.png");
background-repeat: repeat;
overflow: hidden;
/* 防止遮挡点击事件 */
pointer-events: none;
/* 禁止文字选中 */
user-select: none;
/* !!! z-index 设置在threejs canvas画布之下 */
z-index: -1;
}
3.水印和渐变色地板的融合
地板色加了透明度,会与水印背景产生色差:
通过调整颜色可实现无色差
const planeAlpha = 0.5
const cColor = new THREE.Color('#50555E')
const centerColor = new THREE.Color(cColor.r * planeAlpha, cColor.g * planeAlpha, cColor.b * planeAlpha)
const eColor = new THREE.Color('#171F26')
const edgeColor = new THREE.Color(eColor.r * planeAlpha, eColor.g * planeAlpha, eColor.b * planeAlpha)