一些学习three的小记录

这篇主要用来记录我学习3d渲染相关的疑问记录,后续会持续的更新,如果我的理解不对欢迎评论区更正。

目录

1.WebGLRenderer和WebGPURenderer的区别

1.1 WebGLRenderer

1.2 WebGPURenderer

二、scene.background和renderer.setClearColor有什么区别

三、renderer.setAnimationLoop和requestAnimationFrame的区别

四、renderer.toneMapping的属性区别和使用场景

五、什么时候用纹理贴图的magFilter、minFilter属性

5.1 texture.magFilter

5.2 texture.minFilter

六、position和translate的区别

七、将渲染结果保存为图片

八、深度冲突Z-fighting

九、射线拾取

1.WebGLRenderer和WebGPURenderer的区别

1.1 WebGLRenderer

文档地址:three.js docs

  • 基于WebGL,使用 WebGL API,广泛支持各种浏览器。
  • 成熟稳定,具有广泛的兼容性和社区支持。
  • 性能:虽然性能不错,但在处理复杂场景或高多边形数时可能会有瓶颈;使用纹理压缩、实例化等技术优化性能。
  • 着色器:使用 GLSL 着色器。
  • 适用于需要广泛兼容性的项目
const renderer = new THREE.WebGLRenderer();

1.2 WebGPURenderer

官方文档地址:WebGPU

  • 基于WebGPU,使用WebGPU API,更现代的图形API
  • 浏览器支持有限。
  • 着色器:使用 WGSL 或 SPIR-V 着色器语言,可能需要额外配置。
  • 性能:更高效的资源管理、更低的 CPU 开销。
  • 旨在提供更高的性能和更低的延迟,特别是复杂场景和计算(偏向用于性能要求高的场景中)。
const renderer = new THREE.WebGPURenderer();

二、scene.background和renderer.setClearColor有什么区别

共同点:都可以设置背景颜色。

不同点:

  • 作用范围:background只能影响特定的场景背景,setClearColor设置渲染器清除颜色,影响所有场景
  • 支持类型:background可以设置颜色、纹理;setClearColor只能设置颜色。

三、renderer.setAnimationLoop和requestAnimationFrame的区别

共同点:两个都用于创建动画循环。

不同点:

  • renderer.setAnimationLoop可以自动处理虚拟现实(VR)和增强现实(AR)渲染,简化了动画循环的管理,对于WebXR项目,必须使用此函数
  • requestAnimationFrame是原生js方法,需要手动调用渲染逻辑。

用法如下:

// setAnimationLoop的用法
renderer = new WebGPURenderer({ antialias: true });
renderer.setAnimationLoop(() => {
    renderer.render(scene, camera);
    
}); // 如果是WebXR必须使用这个



// requestAnimationFrame的用法
function animate() {
  requestAnimationFrame(animate);
  // 渲染逻辑
  renderer.render(scene, camera);
}
animate();

四、renderer.toneMapping的属性区别和使用场景

  • THREE.NoToneMapping
    • 描述:不进行色调映射
    • 使用场景:场景不需要任何色调调整
  • THREE.LinearToneMapping:
    • 描述:线性映射,不做特殊处理。
    • 使用场景:简单场景,通常用于调试。
  • THREE.ReinhardToneMapping:
    • 描述:逐渐压缩高亮部分,保持细节
    • 使用场景:游戏和实时渲染,需要平衡高亮和细节。
  • THREE.CineonToneMapping:
    • 描述:模拟胶片的色调映射
    • 使用场景:电影渲染,追求胶片效果。
  • THREE.ACESFilmicToneMapping:
    • 描述:高质量色调映射,模拟电影胶片的宽动态范围。
    • 使用场景:高动态范围(HDR)场景,追求真实感和高质量视觉效果。
  • THREE.AgXToneMapping:
    • 描述:过度暴露的区域提供了更好的颜色处理。尤其是明亮部偏于白色,更接近真实相机。
    • 使用场景:适用于需要表现真实光照效果的场景,比如摄影模拟、游戏中的环境光照效果,细致表现光线变化和阴影的应用场景,如建筑可视化。
  • THREE.NeutralToneMapping:
    • 描述:旨在提供一种中性(平衡)色调映射方式,保持图像的自然色彩和亮度。
    • 使用场景:这种方法提供了一种较为简单的转换方式,能够在不显著改变图像原始色彩的情况下,适当降低亮度。
  • THREE.CustomToneMapping:
    • 描述:允许开发者自定义色调映射的方法。

五、什么时候用纹理贴图的magFilter、minFilter属性

当有需要纹理在放大和缩小时的视觉效果可以用。

5.1 texture.magFilter

  • 定义:当一个纹素覆盖大于一个像素时,贴图将如何采样。
  • 常用属性值:
    • THREE.NearestFilter: 使用最近邻过滤,像素会变得很尖锐,可能会出现锯齿状。适合像素风格的图像
    • THREE.LinearFilter: 这是默认值。使用线性过滤,提供更平滑的放大效果,适合需要平滑过渡的图像。
  • 使用场景:
    • 在需要放大纹理并希望保持视觉质量时,可以选择 THREE.LinearFilter
    • 当需要保持像素化效果时(例如,在像素艺术或复古风格游戏中),可以选择 THREE.NearestFilter。

5.2 texture.minFilter

  • 定义:当一个纹素覆盖小于一个像素时,贴图将如何采样。
  • 常用属性值:
    • THREE.NearestFilter: 最近邻过滤,适合像素风格图像。
    • THREE.NearestMipMapNearestFilter: 使用最近邻过滤,并选择最接近的 MIP 贴图。
    • THREE.NearestMipMapLinearFilter: 使用最近邻过滤,并在 MIP 贴图中进行线性插值。
    • THREE.LinearFilter: 线性过滤。
    • THREE.LinearMipMapNearestFilter: 线性过滤并选择最接近的 MIP 贴图。
    • THREE.LinearMipMapLinearFilter: 线性过滤,并在 MIP 贴图中进行线性插值,通常提供最佳视觉效果。
  • 使用场景:
    • 对于需要保持清晰轮廓的纹理(如 UI 元素),可以选择 THREE.NearestFilter。
    • 当纹理需要缩小并且希望保持平滑效果时,使用 THREE.LinearFilter 或 THREE.LinearMipMapLinearFilter。

六、position和translate的区别

共同点:都是用于控制对象的位置

不同点:

  • position是THREE.Vector3对象;translateX、translateY、translateZ是对象方法。
  • position是直接设置对象的绝对位置,translate改变模型自身对坐标原点的位置(意思是:position改变位置后,旋转还是按照几何体的中心旋转;但translate是改变几何体坐标系后旋转)
const geometry = new THREE.Mesh(geometry, material);
geometry.position.set(1, 2, 3); // 设置绝对位置为 (1, 2, 3)




const geometry = new THREE.Mesh(geometry, material);
geometry.translateX(1); // 沿 x 轴平移 1 单位
geometry.translateY(2); // 沿 y 轴平移 2 单位
geometry.translateZ(3); // 沿 z 轴平移 3 单位

七、将渲染结果保存为图片

// render的配置
const renderer = new THREE.WebGLRenderer({
    preserveDrawingBuffer:true
})

// 调用方法
function download(){
const link = document.createElement('a')
const canvas = renderer.domElement
link.href = canvas.toDataURL("image/png")
link.download='1.png'
link.click()
}

八、深度冲突Z-fighting

当两个矩形平面重合,GPU分不清谁在前谁在后,这种现象,可以称为深度冲突Z-fighting。

const renderer = new THREE.WebGLRenderer({
    logarithmicDepthBuffer:true // 两个面间距较小的时候,让threejs更容易区分两个面谁在前、在后
})

但是如果两个面重合、间距过小logarithmicDepthBuffer无法解决。

九、射线拾取

renderer.domElement.addEventListener('click',function(event){
        const px = event.offsetX;
        const py = event.offsetY;
        // 屏幕坐标转webgl标准设备坐标
        const x = (px / window.innerWidth) * 2 + 1
        const y = -(py / window.innerHeight) * 2 + 1
        const raycaster = new THREE.Raycaster();
        raycaster.setFromCamera(new THREE.Vector2(x,y),camera)
        const obj = model.getObjectByName('物品')
        
        for(let i = 0; i <obj.children.length; i++){
            const group = obj.children[i]
            group.traverse((tobj)=> {
                if(tobj.isMesh){
                  tobj.ancestors = group
                }
            })
        }
        const intersects = raycaster.intersectObjects(obj.children)
        if(intersects.length > 0){
            //假设是这个操作
            outlinePass.selectedObjects = [intersects[0].object.ancestors]
        }
})

十、动画基础代码

const geometry = new THREE.BoxGeometry(15,15,15)
const material = new THREE.MeshLambertMaterial({
    color:0xff0000
})
const mesh = new THREE.Mesh(geometry,material)
mesh.name = 'BOX'

const times = [0,3,6] // 时间轴上,设置三个时刻0、3、6
const values = [0,0,0,100,0,0,0,0,100]
const posKF = new THREE.KeyframeTrack('Box.position',times,values)
const colorKF = new THREE.KeyframeTrack('Box.material.color',[2,5],[1,0,0,0,0,1])
// 定义动画
const clip = new THREE.AnimationClip("test",6,[posKF,colorKF])

const mixer = new THREE.AnimationMixer(mesh)
const clipAction = mixer.clipAction(clip)
clipAction.play()

const clock = new THREE.Clock()
function loop(){
    requestAnimationFrame(loop)
    const frameT=clock.getDelta()
    mixer.update(frameT)
}
loop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值