GLSL教程 第10章:高级渲染技术

news2024/9/8 23:04:30

目录

10.1 后处理效果

10.1.1 色彩校正

示例代码:色彩校正

解释:

10.1.2 亮度对比度调整

示例代码:亮度对比度调整

解释:

10.1.3 模糊效果

示例代码:高斯模糊

解释:

10.1.4 边缘锐化

示例代码:Laplacian锐化

解释:

10.1.5 伽马校正

示例代码:伽马校正

解释:

10.2 全屏抗锯齿

10.2.1 多重采样抗锯齿(MSAA)

示例代码:MSAA设置

10.2.2 后期处理抗锯齿(FXAA)

示例代码:FXAA抗锯齿

解释:

10.3 动态模糊

10.3.1 运动模糊

示例代码:运动模糊

解释:

10.3.2 深度模糊(景深)

示例代码:景深

解释:

10.4 体积渲染和体绘制技术

10.4.1 体积光照

示例代码:体积光照

解释:

10.4.2 体绘制技术

示例代码:光线投射

解释:

10.4.3 体积散射

示例代码:体积散射

解释:

总结


        高级渲染技术旨在提升图形渲染的真实性和视觉效果。本章将深入探讨一些常见的高级渲染技术,包括后处理效果、全屏抗锯齿、动态模糊、景深效果、体积渲染和体绘制技术。通过这些技术,我们可以显著改善图形渲染的质量,使得场景更加逼真和生动。

10.1 后处理效果

        后处理效果是在场景渲染完成后,对最终图像进行进一步处理的技术。常见的后处理效果包括色彩校正、亮度对比度调整、模糊、边缘锐化和伽马校正等。这些效果可以使图像看起来更加生动和自然。

10.1.1 色彩校正

        色彩校正技术用于调整图像的颜色,使其更加符合实际场景的颜色或设计需求。色彩校正通常包括色相、饱和度和亮度的调整。

示例代码:色彩校正
#version 330 core

out vec4 FragColor;

in vec2 TexCoords;
uniform sampler2D screenTexture; // 渲染结果纹理

void main() {
    vec4 color = texture(screenTexture, TexCoords);
    
    // 色彩校正
    color.rgb += vec3(0.1, -0.1, 0.0); // 调整红色和绿色的色调
    color.rgb *= 1.2; // 增加亮度

    FragColor = color;
}
解释:
  • color.rgb += vec3(0.1, -0.1, 0.0): 调整颜色通道的偏移量。
  • color.rgb *= 1.2: 增加亮度。

        色彩校正不仅仅是简单的颜色调整,它通常与色彩管理系统(Color Management System, CMS)一起使用,确保在不同显示设备上颜色的一致性。此外,现代渲染引擎还会使用LUT(Look-Up Table)技术进行更复杂的色彩校正,以实现电影级的视觉效果。

10.1.2 亮度对比度调整

        亮度对比度调整用于优化图像的亮暗分布,使得图像的层次感更强。亮度调整可以让图像整体变亮或变暗,而对比度调整则改变图像亮暗区域之间的差异。

示例代码:亮度对比度调整
#version 330 core

out vec4 FragColor;

in vec2 TexCoords;
uniform sampler2D screenTexture; // 渲染结果纹理

uniform float brightness; // 亮度调整系数
uniform float contrast; // 对比度调整系数

void main() {
    vec4 color = texture(screenTexture, TexCoords);
    
    // 亮度调整
    color.rgb += brightness;
    
    // 对比度调整
    color.rgb = (color.rgb - 0.5) * contrast + 0.5;

    FragColor = color;
}
解释:
  • brightness: 控制图像整体亮度的增加或减少。
  • contrast: 调整图像亮暗区域的差异,使图像更有层次感。

        亮度和对比度调整常用于视频处理和游戏开发中,以确保在各种光照条件下,图像的可见度和细节保持最佳状态。

10.1.3 模糊效果

        模糊效果用于柔化图像,使图像看起来更加自然。常见的模糊效果包括高斯模糊和箱式模糊。高斯模糊利用高斯函数对图像进行卷积操作,箱式模糊则通过对图像进行平均滤波来实现。

示例代码:高斯模糊
#version 330 core

out vec4 FragColor;

in vec2 TexCoords;
uniform sampler2D screenTexture; // 渲染结果纹理
uniform float blurRadius; // 模糊半径

void main() {
    vec3 color = vec3(0.0);

    // 高斯模糊核
    float kernel[5] = float[](0.06136, 0.24477, 0.38774, 0.24477, 0.06136);

    // 计算模糊效果
    for (int i = -2; i <= 2; ++i) {
        for (int j = -2; j <= 2; ++j) {
            vec2 offset = vec2(i, j) * blurRadius;
            color += texture(screenTexture, TexCoords + offset).rgb * kernel[abs(i)] * kernel[abs(j)];
        }
    }

    FragColor = vec4(color, 1.0);
}
解释:
  • blurRadius: 控制模糊的强度。
  • kernel: 高斯模糊核,用于计算权重。

        高斯模糊常用于图像处理中的去噪处理,也可用于模拟相机景深效果和运动模糊效果。

10.1.4 边缘锐化

        边缘锐化技术用于增强图像的细节,使得图像看起来更加清晰。常见的方法包括Laplacian锐化和Unsharp Masking。

示例代码:Laplacian锐化
#version 330 core

out vec4 FragColor;

in vec2 TexCoords;
uniform sampler2D screenTexture; // 渲染结果纹理

void main() {
    vec3 color = texture(screenTexture, TexCoords).rgb;
    vec3 sharpenedColor = vec3(0.0);

    // Laplacian核
    float kernel[9] = float[](0, -1, 0, -1, 5, -1, 0, -1, 0);

    // 计算边缘锐化效果
    for (int i = -1; i <= 1; ++i) {
        for (int j = -1; j <= 1; ++j) {
            vec2 offset = vec2(i, j) / vec2(textureSize(screenTexture, 0));
            sharpenedColor += texture(screenTexture, TexCoords + offset).rgb * kernel[(i+1) * 3 + (j+1)];
        }
    }

    FragColor = vec4(sharpenedColor, 1.0);
}
解释:
  • kernel: Laplacian锐化核,用于增强边缘。

        边缘锐化常用于图像处理和计算机视觉中,以提高图像的边缘对比度和细节。

10.1.5 伽马校正

        伽马校正用于调整图像的亮度分布,使其更加符合人眼的感知特点。伽马校正通常用于图像显示和输出设备的颜色调整。

示例代码:伽马校正
#version 330 core

out vec4 FragColor;

in vec2 TexCoords;
uniform sampler2D screenTexture; // 渲染结果纹理
uniform float gamma; // 伽马值

void main() {
    vec4 color = texture(screenTexture, TexCoords);
    
    // 伽马校正
    color.rgb = pow(color.rgb, vec3(1.0 / gamma));

    FragColor = color;
}
解释:
  • gamma: 控制伽马校正的强度。
  • pow(color.rgb, vec3(1.0 / gamma)): 对图像颜色进行伽马校正。

        伽马校正是图像处理中的基本步骤,用于确保图像在不同显示设备上的一致性。

10.2 全屏抗锯齿

        抗锯齿技术用于减少图像中锯齿状的边缘,使其更加平滑。常见的抗锯齿技术包括多重采样抗锯齿(MSAA)和后期处理抗锯齿(如FXAA)。

10.2.1 多重采样抗锯齿(MSAA)

        MSAA通过在每个像素内采样多个子像素来减少锯齿。它通常通过硬件实现,但也可以通过着色器实现后处理抗锯齿效果。

示例代码:MSAA设置
// OpenGL 初始化代码
glEnable(GL_MULTISAMPLE);

        MSAA通过在渲染过程中对每个像素进行多次采样,并在最后阶段对这些采样进行平均,以减少锯齿效果。MSAA是一种硬件支持的抗锯齿技术,通常在现代显卡中得到广泛应用。

10.2.2 后期处理抗锯齿(FXAA)

        FXAA是一种后期处理抗锯齿技术,通过分析图像边缘并对其进行平滑处理来减少锯齿。FXAA是一种基于图像空间的技术,不需要额外的几何信息,因而计算效率较高。

示例代码:FXAA抗锯齿
#version 330 core

out vec4 FragColor;

in vec2 TexCoords;
uniform sampler2D screenTexture; // 渲染结果纹理

// FXAA参数
uniform vec2 resolution;

vec3 FXAA(sampler2D tex, vec2 uv) {
    vec3 color = texture(tex, uv).rgb;
    // 计算边缘检测和抗锯齿效果
    // 这里是FXAA的简化实现
    return color;
}

void main() {
    vec3 color = FXAA(screenTexture, TexCoords);
    FragColor = vec4(color, 1.0);
}
解释:
  • FXAA(): 执行抗锯齿处理,计算边缘检测和颜色平滑。

        FXAA通过对图像进行局部模糊处理,减少了锯齿效果,同时保持了较高的计算效率。FXAA的优势在于其对硬件要求较低,适用于各种平台和设备。

10.3 动态模糊

        动态模糊是一种模拟相机在运动中产生模糊效果的技术。动态模糊可以模拟物体快速移动时的模糊效果,使得动作看起来更加自然和真实。

10.3.1 运动模糊

        运动模糊通过跟踪物体在屏幕上的运动路径,并将这些信息用于模糊效果的计算。它通常通过采样物体的运动轨迹来实现。

示例代码:运动模糊
#version 330 core

out vec4 FragColor;

in vec2 TexCoords;
uniform sampler2D sceneTexture; // 渲染结果纹理
uniform float blurAmount; // 模糊强度

void main() {
    vec3 color = texture(sceneTexture, TexCoords).rgb;
    vec3 blurColor = vec3(0.0);

    // 计算模糊效果
    for (int i = 0; i < 10; ++i) {
        vec2 offset = vec2(float(i) / 10.0 * blurAmount, 0.0);
        blurColor += texture(sceneTexture, TexCoords + offset).rgb;
        blurColor += texture(sceneTexture, TexCoords - offset).rgb;
    }
    blurColor /= 20.0;
    
    FragColor = vec4(blurColor, 1.0);
}
解释:
  • blurAmount: 控制模糊的强度。
  • texture(sceneTexture, TexCoords + offset): 采样偏移位置的纹理值,计算模糊效果。

        运动模糊在模拟快速运动的物体时非常有用,例如在赛车游戏中,动态模糊可以增强速度感,使得玩家体验更加逼真。

10.3.2 深度模糊(景深)

        深度模糊(即景深)模拟相机镜头的景深效果,使得远离焦点的物体变得模糊,从而增强画面的空间感和层次感。

示例代码:景深
#version 330 core

out vec4 FragColor;

in vec2 TexCoords;
in float Depth; // 从深度测试中获取深度值
uniform sampler2D sceneTexture; // 渲染结果纹理
uniform sampler2D depthTexture; // 深度纹理
uniform float focalLength; // 焦距

void main() {
    vec3 color = texture(sceneTexture, TexCoords).rgb;
    float depth = texture(depthTexture, TexCoords).r;
    
    float blur = abs(depth - focalLength) * 10.0; // 根据深度计算模糊程度
    vec3 blurColor = vec3(0.0);

    // 计算景深效果
    for (float i = -blur; i <= blur; i += 0.01) {
        vec2 offset = vec2(i, 0.0);
        blurColor += texture(sceneTexture, TexCoords + offset).rgb;
        blurColor += texture(sceneTexture, TexCoords - offset).rgb;
    }
    blurColor /= (2.0 * blur / 0.01);
    
    FragColor = vec4(blurColor, 1.0);
}
解释:
  • focalLength: 控制景深的焦点位置。
  • blur = abs(depth - focalLength) * 10.0: 根据深度值计算模糊程度。

        景深效果在模拟相机焦点时非常有用,可以突出重要的物体,同时使背景更加柔和。景深效果广泛应用于摄影、电影制作以及3D游戏中。

10.4 体积渲染和体绘制技术

        体积渲染和体绘制技术用于渲染和显示体积数据(如烟雾、云彩、液体等)。这些技术能够模拟复杂的体积效果,使得图像更加真实和生动。

10.4.1 体积光照

        体积光照模拟光线在体积内传播的效果。它可以模拟体积中的光线散射、吸收等现象,从而产生真实的光照效果。

示例代码:体积光照
#version 330 core

out vec4 FragColor;

in vec3 FragPos; // 片段位置
uniform sampler3D volumeTexture; // 体积纹理
uniform vec3 lightPos; // 光源位置
uniform vec3 lightColor; // 光源颜色

void main() {
    vec3 color = vec3(0.0);
    vec3 lightDir = normalize(lightPos - FragPos);
    
    // 采样体积纹理
    color += texture(volumeTexture, FragPos).rgb * max(dot(lightDir, vec3(0.0, 0.0, 1.0)), 0.0);
    
    FragColor = vec4(color * lightColor, 1.0);
}
解释:
  • texture(volumeTexture, FragPos): 从体积纹理中采样颜色值。
  • color += texture(volumeTexture, FragPos).rgb * max(dot(lightDir, vec3(0.0, 0.0, 1.0)), 0.0): 计算光照在体积内的散射效果。

        体积光照广泛应用于模拟雾气、烟雾、云层等效果,使得光线在这些介质中传播时产生更逼真的视觉效果。

10.4.2 体绘制技术

        体绘制技术用于直接渲染三维体积数据。常见的方法包括光线投射(Ray Casting)和体积纹理映射(Volume Texturing)。

示例代码:光线投射
#version 330 core

out vec4 FragColor;

in vec3 FragPos; // 片段位置
uniform sampler3D volumeTexture; // 体积纹理
uniform vec3 viewDir; // 视线方向

void main() {
    vec3 color = vec3(0.0);
    vec3 samplePos = FragPos;

    // 光线投射算法
    for (int i = 0; i < 100; ++i) {
        vec3 sampleColor = texture(volumeTexture, samplePos).rgb;
        color += sampleColor;
        samplePos += viewDir * 0.01; // 沿视线方向步进采样
    }

    color /= 100.0; // 平均采样值

    FragColor = vec4(color, 1.0);
}
解释:
  • samplePos += viewDir * 0.01: 沿视线方向步进采样。
  • color /= 100.0: 对采样值进行平均处理。

        光线投射是一种常用的体绘制技术,通过沿视线方向逐步采样体积数据,并对采样结果进行累加和平均,生成最终的渲染结果。此技术可以用于医学成像、科学可视化等领域。

10.4.3 体积散射

        体积散射模拟光线在不透明或半透明介质中传播时发生的散射现象。它常用于渲染烟雾、雾霭、云层等效果。

示例代码:体积散射
#version 330 core

out vec4 FragColor;

in vec3 FragPos; // 片段位置
uniform sampler3D volumeTexture; // 体积纹理
uniform vec3 lightPos; // 光源位置
uniform vec3 lightColor; // 光源颜色
uniform vec3 viewDir; // 视线方向

void main() {
    vec3 color = vec3(0.0);
    vec3 samplePos = FragPos;
    vec3 lightDir = normalize(lightPos - FragPos);

    // 光线投射和散射计算
    for (int i = 0; i < 100; ++i) {
        vec3 sampleColor = texture(volumeTexture, samplePos).rgb;
        float scatter = max(dot(lightDir, viewDir), 0.0);
        color += sampleColor * scatter;
        samplePos += viewDir * 0.01; // 沿视线方向步进采样
    }

    color /= 100.0; // 平均采样值

    FragColor = vec4(color * lightColor, 1.0);
}
解释:
  • float scatter = max(dot(lightDir, viewDir), 0.0): 计算散射系数。
  • color += sampleColor * scatter: 根据散射系数累加颜色。

        体积散射在渲染烟雾和雾霭等效果时,可以有效地模拟光线在这些介质中发生的散射现象,使得渲染结果更加逼真。

总结

        本章介绍了一些高级渲染技术,通过这些技术可以显著提升图形渲染的质量和视觉效果。后处理效果如色彩校正、亮度对比度调整、模糊、边缘锐化和伽马校正,可以对图像进行进一步的优化。全屏抗锯齿技术如MSAA和FXAA可以减少图像中的锯齿,使其更加平滑。动态模糊技术包括运动模糊和景深,可以模拟相机的动态效果,使得画面更加生动。体积渲染和体绘制技术如体积光照、光线投射和体积散射,可以模拟复杂的体积效果,使得图像更加真实和生动。

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

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

相关文章

成像光学:LCD的工作原理与结构图解

一、主流显示面板技术&#xff1a;LCD&#xff0c;OLED&#xff0c;MicroLED 二、主流显示屏的发展趋势 三、LCD堆叠结构&#xff08;以比较流行的TFT-LCD为例&#xff09; 沿光路方向介绍&#xff1a;背光&#xff0c;下偏光片&#xff08;polarizer&#xff09;&#xff0c;…

python实现图像分割算法2

python实现随机步行算法 随机步行算法数学模型Python 实现详细解释优缺点应用领域随机步行算法是一种常用于图像分割和图像分析的算法。它通过模拟随机游走来确定图像中每个像素的标签或类别。随机步行算法特别适合用于解决有种子标记的图像分割问题,其中用户提供一些初始标记…

【Python】基础语法(上)

本篇文章讲解以下知识&#xff1a; &#xff08;1&#xff09;初始编码 &#xff08;2&#xff09;输出 &#xff08;3&#xff09;初识数据类型 一&#xff1a;初识编码 在计算机中所有的数据本质上都是以0和1的组合来存储。 比如&#xff1a;在一个文件中有以下内容&am…

力扣SQL50 上级经理已离职的公司员工 一题双解

Problem: 1978. 上级经理已离职的公司员工 Code -- 方法 1 -- select e1.employee_id -- from employees e1 -- left join employees e2 -- on e1.manager_id e2.employee_id -- where e1.salary < 30000 -- and e1.manager_id is not null -- and e2.employee_id is…

SpringBoot 整合 Redis 实现验证码登录功能

一、整合Redis 在pom.xml中添加Redis相关依赖&#xff1b; <!--Spring Data Redis依赖配置--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>…

103.qt qml-最全Table新增下拉复制功能

在上篇文章102.qt qml-最全Table交互之多列固定、行列拖拽、自定义委托、标题交互使用教程_qt 表格控件 拖动列-CSDN博客 我们实现了大部分功能,所以本章实现下拉复制功能。 demo截图如下所示: 支持跨界复制,如果下拉的位置大于Table则会动画向下移动,具体可以参考视频链接…

颠覆未来计算!CRAM技术摒弃冯·诺依曼模型,20年研究终迎突破

未来科技&#xff1a;AI计算需求激增&#xff0c;数据中心耗电量堪比派对狂饮&#xff01;明尼苏达大学研究团队或携革命性设备&#xff0c;以惊人能效解决AI能耗难题&#xff01; 研究人员设计了一种新型的"计算随机存取存储器"&#xff08;CRAM&#xff09;原型芯…

查看路由表 netstat -r

“Kernel IP routing table” 是Linux系统中用于展示和配置IP路由的表。它告诉操作系统如何将数据包从一个网络接口发送到另一个网络或主机。下面是对您给出的路由表条目的解释&#xff1a; Destination&#xff1a;目的地地址&#xff0c;可以是具体的IP地址&#xff0c;也可…

Codeforces 962 div3 A-F

A 题目分析 签到 C代码 #include<iostream> using namespace std; int main(){int t;cin>>t;while(t--){int n;cin>>n;cout<<n/4n%4/2<<endl;} } B 题目分析 将n*n的方格分成若干个k*k的方格&#xff0c;每个k*k的方格中所有的数都相同 遍历…

小主机SSD固态硬盘选购攻略,希捷酷鱼 530 SSD固态硬盘表现优秀【附系统无损迁移教程】

小主机SSD固态硬盘选购攻略&#xff0c;希捷酷鱼 530 SSD固态硬盘表现优秀【附系统无损迁移教程】 哈喽小伙伴们好&#xff0c;我是Stark-C~ 这几年随着以零刻为首的小主机市场的兴起&#xff0c;小主机相关的配置周边需求也是越来越大&#xff0c;就比如说SSD固态硬盘就是其…

爬虫程序在采集亚马逊站点数据时如何绕过验证码限制?

引言 在电商数据分析中&#xff0c;爬虫技术的应用日益广泛。通过爬虫技术&#xff0c;我们可以高效地获取大量的电商平台数据&#xff0c;这些数据对于市场分析、竞争情报、价格监控等有着极其重要的意义。亚马逊作为全球最大的电商平台之一&#xff0c;是数据采集的重要目标…

Nacos-微服务注册中⼼(Nacos简介 Nacos配置管理)

目录 一、 微服务的注册中⼼ 1. 注册中⼼的主要作⽤ 2. 常⻅的注册中⼼ 二、Nacos简介 nacos实战⼊⻔ 1. 搭建nacos环境 2.将订单微服务注册到nacos 2.1 在pom.xml中添加nacos的依赖 2.2 在主类上添加EnableDiscoveryClient注解 2.3 在application.yml中添加nacos服…

如何在Linux上构建Raspberry Pi虚拟环境

目录 前置环境需求 Older Version 新版本启动 下面我们来讲讲如何使用QEMU来仿照树莓派环境。这里首先先分成两大类。第一类是跑比较老的&#xff0c;安全性较低的老树莓派&#xff0c;主要指代的是22年4月份发布之前的版本&#xff0c;这个版本当中&#xff0c;树莓派镜像自…

Layui表格合并、表格折叠树

1、核心代码&#xff1a; let tableMerge layui.tableMerge; // 引入合并的插件&#xff0c;插件源文件在最后let tableData [{pid: 0,cid: 111,sortNum: 1, // 序号pName: 数据父元素1,name: 数据1,val: 20,open: true, // 子树是否展开hasChild: true, // 有子数据opt: 数据…

昇思25天学习打卡营第1天 | 快速入门教程

昇思大模型平台&#xff0c;就像是AI学习者和开发者的超级基地&#xff0c;这里不仅提供丰富的项目、模型和大模型体验&#xff0c;还有一大堆经典数据集任你挑。 AI学习有时候就像找不到高质量数据集的捉迷藏游戏&#xff0c;而且本地跑大数据集训练模型简直是个折磨&#xf…

react css module 不生效问题记录

背景&#xff1a;自己使用webpackreactcssless配置的项目框架&#xff0c;在使用过程中发现css module引入不生效。 import React from react import styles from ./index.module.less console.log(styles)//输出 undefinedwebpack配置了css-loader,less-loader,webpack默认cs…

Linux系统之dns服务配置

要求&#xff1a;DNS服务器域解析 www. 11zzj.com为192.168.11.1; ftp.11zzj.com 为192.168.11.2; mail.11zzj.com 为172.16.11.20; 1.打开Linux6&#xff08;服务器&#xff09;和Linux5&#xff08;客户端&#xff09; 配置IP地址和DNS 地址&#xff0c;并ping通。…

PSINS工具箱函数介绍——kfinit

kfinit是kf的参数初始化函数&#xff0c;用于初始化滤波参数 本文所述的代码需要基于PSINS工具箱&#xff0c;工具箱的讲解&#xff1a; PSINS初学指导基于PSINS的相关程序设计&#xff08;付费专题&#xff09; 使用方法 kfinit这个函数的字面意思是&#xff1a;kf的初始化…

游戏制作中没想明白的事情

当一个备忘录&#xff0c;有的是还没有时间去深入研究&#xff0c;或者没有从头了解 什么是建模绑定&#xff1f;为什么人物建模&#xff0c;初始化都是双手打开的&#xff1f;平着放武器&#xff0c;但运行的时候武器会自动竖起来&#xff0c;这是怎么做到的&#xff1f; 思…

嵌入式学习Day13---C语言提升

目录 一、二级指针 1.1.什么是二级指针 2.2.使用情况 2.3.二级指针与数组指针 二、指针函数 2.1.含义 2.2.格式 2.3.注意 2.4.练习 三、函数指针 3.1.含义 3.2.格式 3.3.存储 3.4.练习 ​编辑 四、void*指针 4.1.void缺省类型 4.2.void* 4.3.格式 4.4.注…