【Three.js基础学习】21.Realistic rendering

前言

课程回顾

        渲染器

        1.色调映射

            值意在将高动态范围](HDR)值转换为低动态范围(LDR)

            Three.is中的色调映射实际上会伪造将LDR转换为HDR的过程,即使颜色不是HDR,

            结果会产生非常逼真的渲染效果

            THREE .NoToneMapping (default)  无色调映射

            THREE.LinearToneMapping         线性色调映射

            THREE.ReinhardToneMapping      

            THREE.CineonToneMapping

            THREE.ACESFilmicToneMapping

        2.色调映射曝光

            放了多少光

            toneMappingExposure

        3.抗锯齿 Antialiasing(混叠) 取决于像素比

            讨论两种方法

            1.超级采样(SSAA)或全屏采样(FSAA)

            我们把分辨率提高到实际分辨率以外。当调整为正常尺寸时,每个像素颜色将自动从渲染的4个像素中平均出来

            简单但对性能不好

            2.多采样(MSAA)

            由最新的GPU自动执行

            将检查被渲染像素的邻居。如果是几何图形的边缘,将将其颜色与邻居的颜色混合。

            仅适用于几何边缘

   

        平行光投射阴影

        环境地图不能投射阴影我们需要添加一盏与环境图的照明大致相符的光,并用它投射阴影

        阴影

            开启

            renderer.shadowMap.enabled = true ; // 开启阴影

            renderer.shadowMap.type = THREE.PCFSoftShadowMap // 设置阴影类型

            设置光辅助相机

            平行光开启阴影-》设置相机更行矩阵

            updateWorldMatrix

            在物体模型上开启阴影 ,并且接受阴影

        纹理和颜色空间

            使用木橱柜磨损长度/纹理在模型下方创建一个8x8平面

            使用castle brick broken 06/纹理在模型后面创建一个8x8的平面

        纹理看起来奇怪的白色,这是由于“颜色空间”颜色空间是一种根据人眼敏感度优化颜色存储方式的方法。

            主要涉及应该被看到的纹理(在我们的例子中,bricksColorTexture)

        需要改变颜色空间 , 哪些图gl,arm属于线性,diff属于sRGB ,需要变成线性

        为什么不对模型使用颜色空间?

            原因是GLTF已经包含这些颜色信息

       

        在颜色纹理上更改颜色空间

        floorColorTexture.colorSpace = THREE.SRGBColorSpace

        换成汉堡包

        降低环境强度发现很奇怪,有线的条纹

        原因:由于计算时精确原因,阴影痤疮可能发生在光滑,平坦的表面上;表面是否在阴影中 ;汉堡包正在给自己蒙上一层阴影

        解决:1. 在平行光上,正常量偏移,让汉堡包变大或变小,这样表面没有深度,不会接受阴影

        bias:

        normalBias:

        贴图强度会降低阴影的可见性

一、代码

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import GUI from 'lil-gui'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'
import { floor } from 'three/examples/jsm/nodes/nodes'/*** Loaders*/
const gltfLoader = new GLTFLoader()
const rgbeLoader = new RGBELoader()/*TextureLoad*/
const textureLoader = new THREE.TextureLoader()/*** Base*/
// Debug
const gui = new GUI()
const global = {}// Canvas
const canvas = document.querySelector('canvas.webgl')// Scene
const scene = new THREE.Scene()/*** Update all materials*/
const updateAllMaterials = () =>
{scene.traverse((child) =>{if(child.isMesh && child.material.isMeshStandardMaterial){child.material.envMapIntensity = global.envMapIntensitychild.castShadow = true // 在物体上开启阴影child.receiveShadow = true}})
}/*** Environment map*/
// Global intensity
global.envMapIntensity = 1
gui.add(global, 'envMapIntensity').min(0).max(10).step(0.001).onChange(updateAllMaterials)// HDR (RGBE) equirectangular
rgbeLoader.load('/environmentMaps/0/2k.hdr', (environmentMap) =>
{environmentMap.mapping = THREE.EquirectangularReflectionMappingscene.background = environmentMapscene.environment = environmentMap
})/* Directional Light
*/
const directionalLight = new THREE.DirectionalLight('#ffffff',2)
directionalLight.position.set(-4,6.5,2.5)scene.add(directionalLight)gui.add(directionalLight,'intensity').min(0).max(10).step(0.001).name('lightIntensity') // 光强度
gui.add(directionalLight.position,'x').min(-10).max(10).step(0.001).name('lightX') // 光x轴
gui.add(directionalLight.position,'y').min(-10).max(10).step(0.001).name('lightY')
gui.add(directionalLight.position,'z').min(-10).max(10).step(0.001).name('lightZ')// Shadows
directionalLight.castShadow = true
directionalLight.shadow.camera.far = 15
directionalLight.shadow.normalBias = 0.027
directionalLight.shadow.bias = -0.004
directionalLight.shadow.mapSize.set(512,512) // 数值越大 阴影越清晰
gui.add(directionalLight,'castShadow')gui.add(directionalLight.shadow,'normalBias').min(-0.05).max(0.05).step(0.001)
gui.add(directionalLight.shadow,'bias').min(-0.05).max(0.05).step(0.001)// Helper  光辅助相机
// const directionalLightCameraHelper = new THREE.CameraHelper(directionalLight.shadow.camera)
// scene.add(directionalLightCameraHelper)// target
directionalLight.target.position.set(0,4,0)  //若只是设置这个不生效 , 
directionalLight.target.updateWorldMatrix()  // 加上这个 渲染时,更新矩阵模型 就可以/*** Models*/
// Helmet
// gltfLoader.load(
//     '/models/FlightHelmet/glTF/FlightHelmet.gltf',
//     (gltf) =>
//     {
//         gltf.scene.scale.set(10, 10, 10)
//         scene.add(gltf.scene)//         updateAllMaterials()
//     }
// )
// 汉堡包
gltfLoader.load('/models/hamburger.glb',(gltf) =>{gltf.scene.scale.set(0.4, 0.4, 0.4)gltf.scene.position.set(0,2.5,0)scene.add(gltf.scene)updateAllMaterials()}
)/* floor
*/
const floorColorTexture = textureLoader.load('/textures/wood_cabinet_worn_long/wood_cabinet_worn_long_diff_1k.jpg')
const floorColorNormalTexture = textureLoader.load('/textures/wood_cabinet_worn_long/wood_cabinet_worn_long_nor_gl_1k.jpg')
const floorColorAORoughnessMetalnessTexture = textureLoader.load('/textures/wood_cabinet_worn_long/wood_cabinet_worn_long_arm_1k.jpg')
floorColorTexture.colorSpace = THREE.SRGBColorSpaceconst floorPlaneInWooden = new THREE.Mesh(new THREE.PlaneGeometry(8,8),new THREE.MeshStandardMaterial({map:floorColorTexture,normalMap:floorColorNormalTexture, // 法线贴图 ,保持细节aoMap:floorColorAORoughnessMetalnessTexture, // AO贴图,金属度和粗糙度roughnessMap:floorColorAORoughnessMetalnessTexture,metalnessMap:floorColorAORoughnessMetalnessTexture,// color:new THREE.Color(10, 4, 2)})
)
floorPlaneInWooden.rotation.x = - Math.PI * 0.5
scene.add(floorPlaneInWooden)/* wall
*/
const wallColorTexture = textureLoader.load('/textures/castle_brick_broken_06/castle_brick_broken_06_diff_1k.jpg')
const wallColorNormalTexture = textureLoader.load('/textures/castle_brick_broken_06/castle_brick_broken_06_nor_gl_1k.jpg')
const wallColorAORoughnessMetalnessTexture = textureLoader.load('/textures/castle_brick_broken_06/castle_brick_broken_06_arm_1k.jpg')wallColorTexture.colorSpace = THREE.SRGBColorSpaceconst wallPlaneInWooden = new THREE.Mesh(new THREE.PlaneGeometry(8,8),new THREE.MeshStandardMaterial({map:wallColorTexture,normalMap:wallColorNormalTexture, // 法线贴图 ,保持细节aoMap:wallColorAORoughnessMetalnessTexture, // AO贴图,金属度和粗糙度roughnessMap:wallColorAORoughnessMetalnessTexture,metalnessMap:wallColorAORoughnessMetalnessTexture,// color:new THREE.Color(10, 4, 2)})
)
// wallPlaneInWooden.rotation.x = - Math.PI * 0.5
wallPlaneInWooden.position.y = 4
wallPlaneInWooden.position.z = - 4
scene.add(wallPlaneInWooden)/*** Sizes*/
const sizes = {width: window.innerWidth,height: window.innerHeight
}window.addEventListener('resize', () =>
{// Update sizessizes.width = window.innerWidthsizes.height = window.innerHeight// Update cameracamera.aspect = sizes.width / sizes.heightcamera.updateProjectionMatrix()// Update rendererrenderer.setSize(sizes.width, sizes.height)renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})/*** Camera*/
// Base camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
camera.position.set(4, 5, 4)
scene.add(camera)// Controls
const controls = new OrbitControls(camera, canvas)
controls.target.y = 3.5
controls.enableDamping = true/*** Renderer*/
const renderer = new THREE.WebGLRenderer({canvas: canvas,antialias:true // 反别名
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))// tone mapping
renderer.toneMapping = THREE.ReinhardToneMapping 
renderer.toneMappingExposure = 3gui.add(renderer,'toneMapping',{No:THREE.NoToneMapping,Linear:THREE.LinearToneMapping,Reinhard:THREE.ReinhardToneMapping,Cineon:THREE.CineonToneMapping,ACESFimlmic:THREE.ACESFilmicToneMapping,
})
gui.add(renderer,'toneMappingExposure').min(0).max(10).step(0.001)// Shadows
renderer.shadowMap.enabled = true ; // 开启阴影
renderer.shadowMap.type = THREE.PCFSoftShadowMap // 设置阴影类型/*** Animate*/
const tick = () =>
{// Update controlscontrols.update()// Renderrenderer.render(scene, camera)// Call tick again on the next framewindow.requestAnimationFrame(tick)
}tick()

二、知识点

1.色调映射,抗锯齿     

可以看的在颜色变化的周围,没有想锯齿一样的,而是很平滑

const renderer = new THREE.WebGLRenderer({canvas: canvas,antialias:true // 反别名
})

色调映射:值意在将高动态范围](HDR)值转换为低动态范围(LDR)

            THREE .NoToneMapping (default)  无色调映射

            THREE.LinearToneMapping         线性色调映射

            THREE.ReinhardToneMapping      

            THREE.CineonToneMapping

            THREE.ACESFilmicToneMapping

色调映射曝光

            放了多少光

            toneMappingExposure

抗锯齿 Antialiasing(混叠) 取决于像素比

讨论两种方法

            1.超级采样(SSAA)或全屏采样(FSAA)

            我们把分辨率提高到实际分辨率以外。当调整为正常尺寸时,每个像素颜色将自动从渲染的4个像素中平均出来

            简单但对性能不好

            2.多采样(MSAA) (采用这种)

            由最新的GPU自动执行

            将检查被渲染像素的邻居。如果是几何图形的边缘,将将其颜色与邻居的颜色混合。

            仅适用于几何边缘

2. 平行光投射阴影,阴影

激活灯光投射阴影,开启阴影,物体上开启阴影接受        

renderer.shadowMap.enabled = true ; // 开启阴影
renderer.shadowMap.type = THREE.PCFSoftShadowMap // 设置阴影类型
const updateAllMaterials = () =>
{scene.traverse((child) =>{if(child.isMesh && child.material.isMeshStandardMaterial){child.material.envMapIntensity = global.envMapIntensitychild.castShadow = true // 在物体上开启阴影child.receiveShadow = true}})
}
const directionalLight = new THREE.DirectionalLight('#ffffff',2)
directionalLight.position.set(-4,6.5,2.5)scene.add(directionalLight)gui.add(directionalLight,'intensity').min(0).max(10).step(0.001).name('lightIntensity') // 光强度
gui.add(directionalLight.position,'x').min(-10).max(10).step(0.001).name('lightX') // 光x轴
gui.add(directionalLight.position,'y').min(-10).max(10).step(0.001).name('lightY')
gui.add(directionalLight.position,'z').min(-10).max(10).step(0.001).name('lightZ')// Shadows
directionalLight.castShadow = true
directionalLight.shadow.camera.far = 15
directionalLight.shadow.normalBias = 0.027
directionalLight.shadow.bias = -0.004
directionalLight.shadow.mapSize.set(512,512) // 数值越大 阴影越清晰
gui.add(directionalLight,'castShadow')

3.颜色空间设置

设置之后可以看到原本黄色的墙正常

wallColorTexture.colorSpace = THREE.SRGBColorSpacefloorColorTexture.colorSpace = THREE.SRGBColorSpace

4.不同模型 阴影设置

设置之后对应条纹优化

global.envMapIntensity = 0directionalLight.shadow.normalBias = 0.027directionalLight.shadow.bias = -0.004gui.add(directionalLight.shadow,'normalBias').min(-0.05).max(0.05).step(0.001)gui.add(directionalLight.shadow,'bias').min(-0.05).max(0.05).step(0.001)


总结

让显示的效果更好!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/60162.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot集成Flink-CDC

Flink CDC CDC相关介绍 CDC是什么? CDC是Change Data Capture(变更数据获取)的简称。核心思想是,监测并捕获数据库的变动(包括数据或数据表的插入、更新以及删除等),将这些变更按发生的顺序完整记录下来,写入到MQ以…

ORB_SLAM3安装

ORB_SLAM3安装 一.前期准备1.1ubuntu查看当前版本的命令1.2 根据ubuntu版本,更新下载软件源1.3 先下载git1.4 vim语法高亮1.5 常见的linux命令 二.ORB-SLAM3下载2.1 ORB_SLAM3源码下载2.2 安装依赖库2.2.1 依赖库2.2.2 安装pangolin2.2.3 安装opencv2.2.4 Eigen3安装…

无需云端!国产开源大语言模型llama.cpp本地实战

作者:高瑞冬 注: 文章是2023年底写的。代码和运行方式虽有些旧,但基本原理一样。现在出来ollama,vllm等工具框架用来本地部署大模型,顺便更新一下。 [TOC](最后有彩蛋) 背景 上海人工智能实验室与商汤科技…

leetcode20.括号匹配

题目描述 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个…

横向思维导图前端样式

追溯记录图路上 代码如下 index.vue <template><div style"margin-left: 5%;margin-top: 6%"> <el-form style"margin-top: -5%; " :inline"true"><el-form-item label"药品名称"><el-select v-model&qu…

实验报告6-项目测试与部署

资料下载 实验报告4-实现分页功能 一、实现思路 打包运行商品分页项目。要求&#xff1a; 1、测试项目service层的分页功能&#xff0c; 2、controller层添加first()并测试 3、将项目打为JAR包并运行&#xff0c; 4、将项目打为WAR包并运行。 二、实验步骤 1、测试项目s…

深度学习:微调(Fine-tuning)详解

微调&#xff08;Fine-tuning&#xff09;详解 微调&#xff08;Fine-tuning&#xff09;是机器学习中的一个重要概念&#xff0c;特别是在深度学习和自然语言处理&#xff08;NLP&#xff09;领域。该过程涉及调整预训练模型的参数&#xff0c;以适应特定的任务或数据集。以下…

清华大学提出Mini-Omni2:开源多模态模型,功能与GPT-4o媲美!

&#x1f310; 在人工智能领域&#xff0c;多模态模型的发展正如火如荼。今天&#xff0c;我们要介绍的是由清华大学提出的Mini-Omni2&#xff0c;这是一个开源的多模态语言模型&#xff0c;它在功能上与GPT-4o相媲美&#xff0c;能够理解和生成视觉、听觉和文本内容&#xff0…

简单叙述 Spring 是如何解决循环依赖问题的呢?

文章目录 什么是循环依赖&#xff1f;为什么Spring要解决循环依赖&#xff1f;Spring是如何解决循环依赖的&#xff1f;具体过程是这样的&#xff1a;结论推荐阅读文章 什么是循环依赖&#xff1f; 首先&#xff0c;我们得知道什么是循环依赖。想象一下&#xff0c;如果有两个…

HarmonyOS入门 : 获取网络数据,并渲染到界面上

1. 环境搭建 开发HarmonyOS需要安装DevEco Studio&#xff0c;下载地址 : https://developer.huawei.com/consumer/cn/deveco-studio/ 2. 如何入门 入门HarmonyOS我们可以从一个实际的小例子入手&#xff0c;比如获取网络数据&#xff0c;并将其渲染到界面上。 本文就是基于…

【计网不挂科】计算机网络期末考试(综合)——【选择题&填空题&判断题&简述题】完整试卷

前言 大家好吖&#xff0c;欢迎来到 YY 滴计算机网络 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 本博客主要内容&#xff0c;收纳了一部门基本的计算机网络题目&#xff0c;供yy应对期中考试复习。大家可以参考 本章是去答案版本。带答案的版本在下…

msvcr100.dll丢失怎么解决?高效靠谱的六种解决方法分享

在我们使用电脑的时候&#xff0c;有一种叫动态链接库&#xff08;DLL&#xff09;的文件特别重要。比如&#xff0c;msvcr100.dll是Microsoft Visual C 2010 Redistributable包里的一部分&#xff0c;很多应用程序在运行的时候都需要用到它。但是&#xff0c;有些用户在使用的…

【C++练习】二进制到十进制的转换器

题目&#xff1a;二进制到十进制的转换器 描述 编写一个程序&#xff0c;将用户输入的8位二进制数转换成对应的十进制数并输出。如果用户输入的二进制数不是8位&#xff0c;则程序应提示用户输入无效&#xff0c;并终止运行。 要求 程序应首先提示用户输入一个8位二进制数。…

【SpringBoot】19 文件/图片下载(MySQL + Thymeleaf)

Git仓库 https://gitee.com/Lin_DH/system 介绍 从 MySQL 中&#xff0c;下载保存的 blob 格式的文件。 代码实现 第一步&#xff1a;配置文件 application.yml spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT8datasource:driver-class-name: com.mysql.…

C++——异常

异常是在程序执行的过程中发生了某种错误&#xff0c;异常的处理机制允许我们讲发生的异常抛出给程序的另外一部分&#xff0c;对这个错误进行处理。这个机制让问题检测的环节和问题处理的环节分离。检测环节只需要负责检测即可&#xff0c;无需关系解决的细节问题。在C语言中处…

Docker 配置镜像加速

docker 拉取代码时出现 ERROR: failed to solve: node:16: unexpected status from HEAD request to https:// xxxxxx.mirror.aliyuncs.com/v2/library/node/m…

Android 文件带进度的下载功能实现与封装

网络框架 现在基本都是okhttp3rotrofit同时你可以加入rxjava3&#xff0c;今天就讲一下这几个结合实现简单的下载功能 先定义接口,下面两个区别就是一个可以断点续传而已 /*** 大文件官方建议用 Streaming 来进行注解&#xff0c;不然会出现IO异常&#xff0c;小文件可以忽略不…

Linux相关概念和易错知识点(19)(HDD、Block group)

目录 1.HDD &#xff08;1&#xff09;HDD存储描述 &#xff08;2&#xff09;HDD结构图 &#xff08;3&#xff09;磁盘管理的分治思想 &#xff08;4&#xff09;硬盘中文件系统的整体划分图 2.Block group &#xff08;1&#xff09;文件管理 ①文件属性的存储 ②in…

Windows上安装与使用 Jupyter Notebook

1. 了解 Jupyter Notebook Jupyter Notebook 是一个交互式计算环境&#xff0c;非常适合进行数据科学和机器学习的研究和实验。可以在 Notebook 中直接编写代码、运行代码块、保存结果&#xff0c;非常直观。 在安装 Jupyter Notebook 时&#xff0c;可以选择全局环境&#x…

WWDC24(Xcode 16)中全新的 Swift Testing 使用进阶

概述 WWDC 24 祭出的全新单元测试系统着实让苹果开发者们眼前一亮。“原来测试还可以这么爽&#xff01;&#xff1f;”&#xff0c;日渐逼近蟋蟀发型的某位码农如是说。 Swift Testing 在简洁性以及灵活性全面超越老大哥 XCTest 的同时&#xff0c;也让秃头码农们真正见识到了…