【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.rhkb.cn/news/468621.html

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

相关文章

TeamTalk知识点梳理一(单聊)

文章目录 db_proxy_serverdb_proxy_server reactor响应处理流程连接池redis连接池MySQL连接池 单聊消息消息如何封装?如何保证对端完整解析一帧消息?协议格式?单聊消息流转流程消息序号(msg_id )为什么使用redis生成&a…

LLaMA-Factory学习笔记(1)——采用LORA对大模型进行SFT并采用vLLM部署的全流程

该博客是我根据自己学习过程中的思考与总结来写作的,由于初次学习,可能会有错误或者不足的地方,望批评与指正。 1. 安装 1.1 LLaMA-Factory安装 安装可以参考官方 readme (https://github.com/hiyouga/LLaMA-Factory/blob/main/…

Linux -- 进程初印象

目录 预备知识 切入点 PCB 看见进程 pid getpid 函数 预备知识 Linux -- 冯诺依曼体系结构(硬件)-CSDN博客https://blog.csdn.net/2301_76973016/article/details/143598784?spm1001.2014.3001.5501 Linux -- 操作系统(软件&#xf…

342--358作业整理(错误 + 重点)

目录 1. 在需要运行的类中 定义 main 方法 2. this 。访问逻辑:先访问本类中,再访问父类中可以访问的成员(不包括和本类中重名的成员) 3. super 。访问逻辑:super(父类对象)直接访问父类及以…

Jekins篇(搭建/安装/配置)

目录 一、环境准备 1. Jenkins安装和持续集成环境配置 2. 服务器列表 3. 安装环境 Jekins 环境 4. JDK 环境 5. Maven环境 6. Git环境 方法一:yum安装 二、JenKins 安装 1. JenKins 访问 2. jenkins 初始化配置 三、Jenkins 配置 1. 镜像配置 四、Mave…

【Linux】冯诺依曼体系结构

目录 一、冯诺依曼体系结构二、冯诺依曼体系结构的基本组成三、关于冯诺依曼体系结构的一些问题结尾 一、冯诺依曼体系结构 冯诺依曼体系结构,也称为普林斯顿结构,是现代计算机设计的基础框架。这一体系结构由数学家冯诺依曼在20世纪40年代提出&#xf…

M1M2 MAC安装windows11 虚拟机的全过程

M1/M2 MAC安装windows11 虚拟机的全过程 这两天折腾了一下windows11 arm架构的虚拟机,将途中遇到的坑总结一下。 1、虚拟机软件:vmware fusion 13.6 或者 parallel 19 ? 结论是:用parellel 19。 这两个软件都安装过&#xff0…

NAT、代理服务与内网穿透技术全解析

🍑个人主页:Jupiter. 🚀 所属专栏:Linux从入门到进阶 欢迎大家点赞收藏评论😊 目录 NAT 技术背景NAT IP 转换过程NAPTNAT 技术的缺陷 代理服务器正向代理工作原理功能特点应用场景 反向代理基本原理应用场景 NAT 和代理…

优选算法 - 1 ( 双指针 移动窗口 8000 字详解 )

一&#xff1a;双指针 1.1 移动零 题目链接&#xff1a;283.移动零 class Solution {public void moveZeroes(int[] nums) {for(int cur 0, dest -1 ; cur < nums.length ; cur){if(nums[cur] 0){}else{dest; // dest 先向后移动⼀位int tmp nums[cur];nums[cur] num…

qt配合映美精取图开发

最近开发一个项目&#xff0c;用映美精相机配合halcon做取图开发&#xff0c;由于网上资料小特意写个记录。到映美精官网下载驱动&#xff0c;映美精官网&#xff0c;下载映美精的工具开发包SDK 映美精的SDK下载SDK后找到classlib文件夹 里面就是SDK新建一个qt程序&#xff0c…

华为云计算HCIE-Cloud Computing V3.0试验考试北京考场经验分享

北京试验考场 北京考场位置 1.试验考场地址 北京市海淀区北清路156号中关村环保科技示范园区M地块Q21楼 考试场选择北京&#xff0c;就是上面这个地址&#xff0c;在预约考试的时候会显示地址&#xff0c;另外在临近考试的时候也会给你发邮件&#xff0c;邮件内会提示你考试…

LeetCode 509.斐波那契数

动态规划思想 五步骤&#xff1a; 1.确定dp[i]含义 2.递推公式 3.初始化 4.遍历顺序 5.打印dp数组 利用状态压缩&#xff0c;简化空间复杂度。在原代码中&#xff0c;dp 数组保存了所有状态&#xff0c;但实际上斐波那契数列的计算只需要前两个状态。因此&#xff0c;我们…

反向代理开发

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当于…

RabbitMQ — 异步调用

RabbitMQ 是一个开源的消息代理中间件&#xff0c;它使用高级消息队列协议&#xff08;AMQP, Advanced Message Queuing Protocol&#xff09;来实现不同系统之间的消息传递。它以 Erlang 语言编写&#xff0c;具有高可靠性、灵活性和易于扩展的特点&#xff0c;被广泛应用于异…

2025 年使用 Python 和 Go 解决 Cloudflare 问题

作为一名从事网络自动化和爬取工作的开发者&#xff0c;我亲眼目睹了日益复杂的安全性措施带来的挑战。其中一项挑战是 Cloudflare 的 Turnstile CAPTCHA 系统&#xff0c;目前该系统已在全球 2600 多万个网站上使用。这种先进的解决方案重新定义了我们对机器人检测的处理方式&…

大数据的实时处理:工具和最佳实践

在当今的数字世界中&#xff0c;数据以前所未有的速度从无数来源生成&#xff0c;包括社交媒体、物联网设备、电子商务平台等。随着组织认识到这些数据的潜在价值&#xff0c;他们越来越多地转向实时处理&#xff0c;以获得即时、可操作的见解。但是&#xff0c;实时处理大数据…

104、Python并发编程:基于事件Event实现多线程间的同步

引言 继续介绍关于多线程同步的实现方式&#xff0c;本文将介绍基于Event的线程同步方式。 本文的主要内容有&#xff1a; 1、什么是Event 2、Event的使用场景 3、Event的代码实例 4、Event与Condition的比较 什么是Event 在Python的多线程编程中&#xff0c;Event是一个…

第2章2.3立项【硬件产品立项的核心内容】

硬件产品立项的核心内容 2.3 硬件产品立项的核心内容2.3.1 第一步&#xff1a;市场趋势判断2.3.2 第二步&#xff1a;竞争对手分析1.竞争对手识别2.根据竞争对手分析制定策略 2.3.3 第三步&#xff1a;客户分析2.3.4 第四步&#xff1a;产品定义2.3.5 第五步&#xff1a;开发执…

ReactPress数据库表结构设计全面分析

ReactPress Github项目地址&#xff1a;https://github.com/fecommunity/reactpress 欢迎Star。 ReactPress是一个基于React框架开发的开源发布平台和内容管理系统&#xff08;CMS&#xff09;。它不仅支持用户在支持React和MySQL数据库的服务器上搭建自己的博客和网站&#…

ANDROIDWORLD: A Dynamic BenchmarkingEnvironment for Autonomous Agents论文学习

这个任务是基于androidenv的。这个环境之前学过&#xff0c;是一个用来进行强化学习的线上环境。而这篇文章的工作就是要给一些任务加上中间的奖励信号。这种训练环境的优点就是动态&#xff0c;与静态的数据集&#xff08;比如说我自己的工作&#xff09;不同&#xff0c;因此…