当前位置: 首页 > news >正文

GLSL教程 第十三章:综合项目:创建一个完整的渲染场景(一更)

 

目录

13.1 项目规划和设计

13.1.1 项目目标

13.1.2 设计要求

13.2 实现场景中的光照、材质和纹理

13.2.1 创建基础场景

13.2.2 应用材质和纹理

13.3 集成高级渲染效果和后期处理

13.3.1 阴影映射(Shadow Mapping)

13.3.2 环境光遮蔽(AO)

13.3.3 简单的景深效果(Depth of Field)

13.3.4 阴影技术

13.4 性能优化

13.4.1 批处理渲染

13.4.2 LOD(细节层次)

13.4.3 减少状态切换

13.4.4 延迟渲染


     在本章中,我们将创建一个完整的渲染场景,涵盖从基础的场景设置到高级的渲染效果和后期处理。我们将使用OpenGL和GLSL来实现场景的渲染,并逐步引入光照、材质、纹理、阴影映射、环境光遮蔽(AO)以及景深效果等技术。

13.1 项目规划和设计

13.1.1 项目目标

       本项目的目标是创建一个包含地面、墙壁和一个简单3D模型(如立方体)的基本渲染场景。除此之外,我们还将实现以下高级渲染效果:

  • 阴影映射(Shadow Mapping)
  • 环境光遮蔽(Ambient Occlusion,AO)
  • 简单的景深效果(Depth of Field)
13.1.2 设计要求
  1. 场景内容:
    • 地面
    • 墙壁
    • 3D模型(立方体)
  2. 光照效果:
    • 点光源
    • 环境光
  3. 材质效果:
    • 漫反射和高光
  4. 高级渲染效果:
    • 阴影映射
    • 环境光遮蔽(AO)
    • 简单的景深效果

13.2 实现场景中的光照、材质和纹理

13.2.1 创建基础场景

       首先,我们将设置基础场景,包括地面、墙壁和一个简单的3D模型(立方体)。我们使用OpenGL创建这些基本几何体,并为每个对象定义适当的顶点和片段着色器。

顶点着色器 (shader.vert):

#version 330 corelayout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aTexCoord;out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoord;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main() {vec4 worldPosition = model * vec4(aPos, 1.0);FragPos = worldPosition.xyz;Normal = mat3(transpose(inverse(model))) * aNormal;TexCoord = aTexCoord;gl_Position = projection * view * worldPosition;
}

片段着色器 (shader.frag):

#version 330 corein vec3 FragPos;
in vec3 Normal;
in vec2 TexCoord;out vec4 FragColor;struct Material {vec3 ambient;vec3 diffuse;vec3 specular;float shininess;
};struct Light {vec3 position;vec3 ambient;vec3 diffuse;vec3 specular;
};uniform Material material;
uniform Light light;
uniform vec3 viewPos;
uniform sampler2D diffuseTexture;void main() {// Ambientvec3 ambient = material.ambient * light.ambient;// Diffusevec3 norm = normalize(Normal);vec3 lightDir = normalize(light.position - FragPos);float diff = max(dot(norm, lightDir), 0.0);vec3 diffuse = material.diffuse * diff * light.diffuse;// Specularvec3 viewDir = normalize(viewPos - FragPos);vec3 reflectDir = reflect(-lightDir, norm);float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);vec3 specular = material.specular * spec * light.specular;vec3 result = ambient + diffuse + specular;FragColor = vec4(result, 1.0) * texture(diffuseTexture, TexCoord);
}
13.2.2 应用材质和纹理

       接下来,我们为场景中的物体应用基础的材质和纹理。材质的主要属性包括漫反射、镜面反射和环境光成分。纹理则用于为物体添加更多的细节和颜色。

纹理加载和绑定 (texture.cpp):

#include "texture.hpp"
#include <iostream>Texture::Texture(const char* imagePath) {glGenTextures(1, &ID);glBindTexture(GL_TEXTURE_2D, ID);// 设置纹理参数glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// 加载并生成纹理int width, height, nrChannels;unsigned char* data = stbi_load(imagePath, &width, &height, &nrChannels, 0);if (data) {GLenum format;if (nrChannels == 1)format = GL_RED;else if (nrChannels == 3)format = GL_RGB;else if (nrChannels == 4)format = GL_RGBA;glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);glGenerateMipmap(GL_TEXTURE_2D);} else {std::cerr << "Failed to load texture: " << imagePath << std::endl;}stbi_image_free(data);
}void Texture::bind() const {glBindTexture(GL_TEXTURE_2D, ID);
}

场景对象加载 (scene_object.cpp):

#include "scene_object.hpp"
#include <glm/gtc/matrix_transform.hpp>SceneObject::SceneObject(const std::vector<Vertex>& vertices, const std::vector<unsigned int>& indices, const char* texturePath): vertices(vertices), indices(indices), texture(texturePath) {setupMesh();
}void SceneObject::setupMesh() {glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);// 顶点位置glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);// 法线glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));// 纹理坐标glEnableVertexAttribArray(2);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));glBindVertexArray(0);
}void SceneObject::draw(const Shader& shader) {shader.use();glBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);glBindVertexArray(0);
}

13.3 集成高级渲染效果和后期处理

13.3.1 阴影映射(Shadow Mapping)

       阴影映射用于在场景中生成逼真的阴影效果。我们将使用深度贴图来计算阴影,并在片段着色器中进行深度比较。

阴影映射Shader (shadow_mapping_shader.vert and shadow_mapping_shader.frag):

顶点着色器 (shadow_mapping_shader.vert):

#version 330 corelayout(location = 0) in vec3 aPos;uniform mat4 lightSpaceMatrix;
uniform mat4 model;void main() {gl_Position = lightSpaceMatrix * model * vec4(aPos, 1.0);
}

片段着色器 (shadow_mapping_shader.frag):

#version 330 corevoid main() {// 这里不需要输出颜色,深度缓冲会自动存储深度值
}
<

相关文章:

GLSL教程 第十三章:综合项目:创建一个完整的渲染场景(一更)

目录 13.1 项目规划和设计 13.1.1 项目目标 13.1.2 设计要求 13.2 实现场景中的光照、材质和纹理 13.2.1 创建基础场景 13.2.2 应用材质和纹理 13.3 集成高级渲染效果和后期处理 13.3.1 阴影映射(Shadow Mapping) 13.3.2 环境光遮蔽(AO) 13.3.3 简单的景深效果(…...

pgvector: 30 倍构建向量嵌入索引

使用 pgvector 为 HNSW 并行构建索引 Postgres 最受欢迎的向量搜索扩展 pgvector 最近实现了并行索引构建功能&#xff0c;这将分层可导航小世界 (HNSW) 索引构建时间显著提高了 30 倍。 祝贺 Andrew Kane 和 pgvector 的贡献者发布此版本&#xff0c;这巩固了 Postgres 作为最…...

GNSS形变监测系统

TH-WY1 GNSS形变监测系统采用扼流圈设计有以下几个优势&#xff1a; 高精度测量&#xff1a;扼流圈是一种高精度的传感器&#xff0c;可以提供非常精确的测量结果。这使得GNSS形变监测系统能够准确地测量结构物的形变变化。 高稳定性&#xff1a;扼流圈设计使得传感器具有良好…...

每天一个数据分析题(四百五十三)- 随机抽样

在进行随机抽样时由于某些原因会产生抽样误差&#xff0c;以下关于抽样误差的说法&#xff0c;正确的是 A. 抽样误差是随机抽样调查中偶然发生的代表性误差 B. 抽样误差的大小同样本单位数成正比关系 C. 简单随机抽样比分层抽样误差大 D. 重复抽样比不重复抽样误差小 数据…...

Python爬虫知识体系-----Selenium

数据科学、数据分析、人工智能必备知识汇总-----Python爬虫-----持续更新&#xff1a;https://blog.csdn.net/grd_java/article/details/140574349 文章目录 一、安装和基本使用二、元素定位三、访问元素信息四、自动化交互五、PhantomJS六、Chrome headless 一、安装和基本使用…...

springboot+webSocket对接chatgpt

webSocket对接参考 话不多说直接上代码 WebSocket package com.student.config;import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springfram…...

【ROS2】 默认的DDS通信中间件替换为Eclipse Cyclone_DDS (DDS配置方法)

ROS2替换中间件为Cyclone_DDS 1.一些介绍&#xff1a;&#xff09;2.不同DDS的RMW实现3.默认的FastDDS替换为Cyclone DDSi.安装依赖ii.编译 cyclone-dds 4.配置网络 1.一些介绍&#xff1a;&#xff09; 上一篇我们探讨了ros1和ros2编写launch的区别 【ROS2】launch启动文件编…...

迈向数智金融:机器学习金融科技新纪元的新风采

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…...

Nginx+PHP+CI框架实现,访问静态文件带权限验证

1、访问来源验证配置nginx #文件访问来源校验 如路径&#xff1a;https://ys.test.com/test/api/uploads/test.png #不是该允许域名的将返回403页面 location /test/api/uploads/ {valid_referers ys.test.com ys.test2.com;if ($invalid_referer) {return 403;} }2、拦截访问…...

javascript 第二天

正则表达式 a/正则表达式内容/ a.test(“需要检测的内容”) 焦点事件 onfocus 获得焦点 onblur 失去焦点 他们都是事件&#xff0c;和onclick一样 onchange 内容改变 失去焦点时生效&#xff0c;多了内容检测&#xff0c;如果内容不变不触发&#xff0c;内容改变才触发 onk…...

unity2D游戏开发17战斗精灵

导入 将PlayerFight32x32.png拖Player文件夹进去 设置属性 创建动画剪辑 选中前四帧,右键Create|Animation,将动画命名为player-ire-east 其他几个动画也创建好后,将其拖到Animations|Animations文件夹 选中PlayerController,再点击Animator 创建新的Blend Tree Graph,并重…...

kafka架构+原理+源码

1.安装jdk17 sudo yum -y update sudo wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.rpm sudo yum -y install ./jdk-17_linux-x64_bin.rpm sudo java -version 2.安装kafka How to easily install kafka without zookeeper | Aditya’s Blog 1.…...

实力共鉴!微风企斩获2024年浙江省专精特新中小企业

日前&#xff0c;微风企斩获2024年浙江省专精特新中小企业荣誉&#xff0c;这是继获得“国家高新技术企业”“浙江省科技中小企业”“杭州市雏鹰计划企业”等权威性认证后&#xff0c;微风企荣获的又一重磅殊荣。 “专精特新中小企业”是国家对具有“专业化、精细化、特色化、新…...

C#:枚举及位标志周边知识详解(小白入门)

文章目录 枚举为什么要有枚举?枚举的性质设置默认类型和显式设置成员的值 位标志(重要)位标记是什么及作用位标志周边知识HasFlag判断是否有该功能枚举前面加Flags的好处 关于枚举的更多知识using static简化代码获取枚举成员的字面量 枚举 为什么要有枚举? 为了增加代码的…...

这本vue3编译原理开源电子书,初中级前端竟然都能看懂

前言 众所周知vue提供了很多黑魔法&#xff0c;比如单文件组件(SFC)、指令、宏函数、css scoped等。这些都是vue提供的开箱即用的功能&#xff0c;大家平时用这些黑魔法的时候有没有疑惑过一些疑问呢。 我们每天写的vue代码一般都是写在*.vue文件中&#xff0c;但是浏览器却只…...

小白如何安装WNO(小波神经算子),需要安装python3.8,torch,ptwt,pywt等

下载项目 WNO在github上面的项目地址如下&#xff1a; https://github.com/csccm-iitd/WNO/tree/main 下载下来后&#xff0c;里面的数据集需要用matlab代码生成&#xff0c;也可以到里面提到的google云盘里面下载数据集 安装环境 然后需要安装环境 注意python版本一定要…...

Java HashMap 源码解读笔记(一)--xunznux

文章目录 HashMap介绍实现说明:源码解读静态常量和内部节点类 Node静态工具方法属性字段 Fields未完待续。。。 HashMap 本文主要是用于记录我在阅读Java1.8的 HashMap 源码所做的笔记。对于源码中的注释会进行翻译下来&#xff0c;并且会对其中部分源码进行注释。 这一篇文章…...

“等保测评下的数据加密与隐私保护“

在当今数字化时代&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;数据泄露、隐私侵犯等事件频发&#xff0c;不仅给企业带来经济损失&#xff0c;更严重损害了公众信任。等保测评&#xff0c;作为国家信息安全等级保护制度的重要组成部分&#xff0c;对数据加密…...

Oat++ 后端实现跨域

这里记录在官方的例子中&#xff0c;加入跨域。Oat Example-CRUD 在官方的例子中&#xff0c;加入跨域。 Oat Example-CRUD 修改AppComponent.hpp文件中的代码&#xff0c;如下&#xff1a; #include "AppComponent.hpp"#include "controller/UserController…...

Three basic starting points to do AI

Computers have been based on memory/storage for so many years. Don’t try to come up with something else. For so many years, AI has been based on fixed precise rules or fuzzy matching rules. Don’t think about coming up with the third one by yourself. Vi…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

FOPLP vs CoWoS

以下是 FOPLP&#xff08;Fan-out panel-level packaging 扇出型面板级封装&#xff09;与 CoWoS&#xff08;Chip on Wafer on Substrate&#xff09;两种先进封装技术的详细对比分析&#xff0c;涵盖技术原理、性能、成本、应用场景及市场趋势等维度&#xff1a; 一、技术原…...

验证redis数据结构

一、功能验证 1.验证redis的数据结构&#xff08;如字符串、列表、哈希、集合、有序集合等&#xff09;是否按照预期工作。 2、常见的数据结构验证方法&#xff1a; ①字符串&#xff08;string&#xff09; 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...

aurora与pcie的数据高速传输

设备&#xff1a;zynq7100&#xff1b; 开发环境&#xff1a;window&#xff1b; vivado版本&#xff1a;2021.1&#xff1b; 引言 之前在前面两章已经介绍了aurora读写DDR,xdma读写ddr实验。这次我们做一个大工程&#xff0c;pc通过pcie传输给fpga&#xff0c;fpga再通过aur…...

Qt学习及使用_第1部分_认识Qt---Qt开发基本流程

前言 学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面. 参考书:<Qt 6 C开发指南>(以下称"本书") 标识说明:概念用粗体倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字), 本书原话内容用深蓝色标识,比较重要的内容用加粗倾…...

轻量安全的密码管理工具Vaultwarden

一、Vaultwarden概述 Vaultwarden主要作用是提供一个自托管的密码管理器服务。它是Bitwarden密码管理器的第三方轻量版&#xff0c;由国外开发者在Bitwarden的基础上&#xff0c;采用Rust语言重写而成。 &#xff08;一&#xff09;Vaultwarden镜像的作用及特点 轻量级与高性…...