GLSL中的std140注意事项

2024-04-21 05:20
文章标签 注意事项 glsl std140

本文主要是介绍GLSL中的std140注意事项,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、关于bool的注意事项

以下是笔者在学习OpenGL相关内容时遇到的问题

struct UniformBufferObject {alignas(16) igm::vec3 viewPos;alignas(4) bool useColor;
};

这是我在C++程序中声明的一个UBO,对应于着色器中的:

layout(std140, binding = 1) uniform UniformBufferObject {vec3 viewPos;bool useColor;
} ubo;

我在C++程序中给声明的UBO进行赋值,也就是

UniformBufferObject ubo;
ubo.viewPos = igm::vec3(1.0f);
ubo.useColor = false;

但是这段代码在实际运行中并不能得到正确的答案,原因就在于笔者对C++的alignas(4)用法不熟悉
首先先看GLSL中的std140布局规则(以下内容引用自LearnOpenGL)

类型布局规则
标量,比如int和bool每个标量的基准对齐量为N
向量2N或者4N。这意味着vec3的基准对齐量为4N
标量或向量的数组每个元素的基准对齐量与vec4的相同
矩阵储存为列向量的数组,每个向量的基准对齐量与vec4的相同
结构体等于所有元素根据规则计算后的大小,但会填充到vec4大小的倍数

std140布局规则的对齐偏移量实例

layout (std140) uniform ExampleBlock
{// 基准对齐量       // 对齐偏移量float value;     // 4               // 0 vec3 vector;     // 16              // 16  (必须是16的倍数,所以 4->16)mat4 matrix;     // 16              // 32  (列 0)// 16              // 48  (列 1)// 16              // 64  (列 2)// 16              // 80  (列 3)float values[3]; // 16              // 96  (values[0])// 16              // 112 (values[1])// 16              // 128 (values[2])bool boolean;    // 4               // 144int integer;     // 4               // 148
};

因此可以知道,我们的UBO占用16个字节,在我们C++的处理中确实可以让struct UniformBufferObject对齐到16字节,通过std::cout << sizeof(UniformBufferObject) << std::endl;得到16就是一个验证。

layout(std140, binding = 1) uniform UniformBufferObject {// 基准对齐量       // 对齐偏移量vec3 viewPos;  	// 16			   // 0bool useColor;  // 4			   // 12
} ubo;

但最重要的是struct UniformBufferObject中的alignas(4) bool useColor;,由于bool类型在C++中只占一个字节,如果我们对useColor进行赋值时只会对alignas(4)对齐到的4字节的第一个字节进行赋值,后续三个字节是由C++进行随机填充的,用以下代码就可以查看ubo中的字节码

struct UniformBufferObject {alignas(16) igm::vec3 viewPos;alignas(4) bool useColor;
};UniformBufferObject ubo;
ubo.viewPos = igm::vec3(1.0f);
ubo.useColor = false;// Convert the struct pointer to char pointer
char* bytes = reinterpret_cast<char*>(&ubo);// Print bytes in hexadecimal format
std::cout << "Byte representation of ubo:" << std::endl;
for (size_t i = 0; i < sizeof(ubo); ++i) {std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(bytes[i]) << " ";
}
std::cout << std::endl;

输出结果为:

Byte representation of ubo:
00 00 ffffff80 3f 00 00 ffffff80 3f 00 00 ffffff80 3f 00 ffffffcc ffffffcc ffffffcc

可以看到对齐到四字节的bool类型最终字节码为00 ffffffcc ffffffcc ffffffcc,也就是说,当该串字节传入GLSL时,最后四字节的表示不等于0,因此也就不为false,由于GLSL基于std140的解释会将bool类型的四个字节合到一起进行解释,因此我们需要对四个字节一起进行赋值,一个简单的办法就是alignas(4) bool useColor;更改为alignas(4) int useColor;,我们在C++中也将四个字节当作一个整体进行赋值,这样就能保证GLSL中四个字节所解释成的bool类型为正确的数值,重新运行上诉代码
输出结果为:

Byte representation of ubo:
00 00 ffffff80 3f 00 00 ffffff80 3f 00 00 ffffff80 3f 00 00 00 00

由此保证了C++中的数据与GLSL中的数据的解释一致性。

这篇关于GLSL中的std140注意事项的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922247

相关文章

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

MySQL 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二

详解MySQL中DISTINCT去重的核心注意事项

《详解MySQL中DISTINCT去重的核心注意事项》为了实现查询不重复的数据,MySQL提供了DISTINCT关键字,它的主要作用就是对数据表中一个或多个字段重复的数据进行过滤,只返回其中的一条数据... 目录DISTINCT 六大注意事项1. 作用范围:所有 SELECT 字段2. NULL 值的特殊处

MySQL 打开binlog日志的方法及注意事项

《MySQL打开binlog日志的方法及注意事项》本文给大家介绍MySQL打开binlog日志的方法及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、默认状态二、如何检查 binlog 状态三、如何开启 binlog3.1 临时开启(重启后失效)

电脑死机无反应怎么强制重启? 一文读懂方法及注意事项

《电脑死机无反应怎么强制重启?一文读懂方法及注意事项》在日常使用电脑的过程中,我们难免会遇到电脑无法正常启动的情况,本文将详细介绍几种常见的电脑强制开机方法,并探讨在强制开机后应注意的事项,以及如何... 在日常生活和工作中,我们经常会遇到电脑突然无反应的情况,这时候强制重启就成了解决问题的“救命稻草”。那

Python中__new__()方法适应及注意事项详解

《Python中__new__()方法适应及注意事项详解》:本文主要介绍Python中__new__()方法适应及注意事项的相关资料,new()方法是Python中的一个特殊构造方法,用于在创建对... 目录前言基本用法返回值单例模式自定义对象创建注意事项总结前言new() 方法在 python 中是一个

Springboot的自动配置是什么及注意事项

《Springboot的自动配置是什么及注意事项》SpringBoot的自动配置(Auto-configuration)是指框架根据项目的依赖和应用程序的环境自动配置Spring应用上下文中的Bean... 目录核心概念:自动配置的关键特点:自动配置工作原理:示例:需要注意的点1.默认配置可能不适合所有场景

Spring Cloud Hystrix原理与注意事项小结

《SpringCloudHystrix原理与注意事项小结》本文介绍了Hystrix的基本概念、工作原理以及其在实际开发中的应用方式,通过对Hystrix的深入学习,开发者可以在分布式系统中实现精细... 目录一、Spring Cloud Hystrix概述和设计目标(一)Spring Cloud Hystr

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2