OpenGL 着色器

一、‌着色器基础结构
  1. 版本声明与入口函数

    • 首行版本声明‌:必须指定 GLSL 版本和模式(如 #version 450 core)‌。
      #version 450 core  // 声明使用 OpenGL 4.5 Core Profile
    • 入口函数‌:所有着色器的入口均为 main() 函数,负责处理输入变量并输出结果‌。
  2. 输入/输出变量

    • 顶点属性输入‌:通过 layout(location=N) 指定顶点属性位置(如位置、法线、纹理坐标),通过 in 关键字声明‌。
      layout (location = 0) in vec3 aPos;  // 位置属性(location 对应 VBO 的布局)
      layout (location = 1) in vec2 aTexCoord; // 纹理坐标
    • 跨阶段传递‌:顶点着色器的 out 变量需与片段着色器的 in 变量名称、类型一致以实现数据传递‌。
      out vec2 TexCoord;  // 顶点着色器输出,片段着色器输入
      
  3. Uniform 全局变量

    • 作用‌:用于从 CPU 向 GPU 传递全局数据(如变换矩阵、光源参数)‌。
    • 特点‌:同一着色器程序中所有着色器共享相同的 uniform 值‌。
      uniform mat4 model;      // 模型矩阵
      uniform sampler2D tex;   // 纹理采样器
二、‌着色器类型与功能
  1. 顶点着色器 (Vertex Shader)

    • 职责‌:处理顶点属性(位置、法线等),执行模型-视图-投影变换,输出裁剪空间坐标‌。
    • 限制‌:可用的顶点属性数量由硬件决定,需通过 GL_MAX_VERTEX_ATTRIBS 查询上限‌。
  2. 片段着色器 (Fragment Shader)

    • 职责‌:计算像素颜色,支持纹理采样、光照计算,输出最终颜色到帧缓冲区‌。
    • 优化场景‌:逐片元计算光照可避免逐顶点着色的视觉瑕疵(如马赫带效应)‌。
  3. 其他着色器类型

    • 几何着色器‌:动态生成/修改图元拓扑结构(如将点扩展为四边形)‌。
    • 曲面细分着色器‌:控制曲面细分级别,生成高精度几何体‌。
三、‌核心语法与数据操作
  1. 数据类型

    • 基础类型‌:floatintboolvec2、vec3、vec4mat3、mat4 、sampler2D等‌。
    • 容器操作‌:向量支持分量重组(如 vec3 pos = myVec.xyz),矩阵为列优先存储‌。
      vec3 color = vec3(1.0, 0.0, 0.0);  // 红色
      mat4 view = mat4(1.0);             // 单位矩阵
      
    • 内置变量‌:
      顶点着色器必须赋值 gl_Positiongl_Position接收顶点经过模型-视图-投影(MVP)矩阵变换后的坐标值,其类型为vec4

      gl_Position = projection * view * model * vec4(aPos, 1.0); 

      裁剪空间坐标范围通常为[-1, 1],超出此范围的顶点会被裁剪‌。

    • 片段着色器必须赋值 FragColor

      out vec4 FragColor;  // 输出颜色到帧缓冲区
      
  2. 控制流与函数

    • 分支/循环‌:支持 if-elseforwhile 语句‌。
    • 自定义函数‌:类似 C 语言风格,支持参数传递和返回值‌。
      float calculateLight(vec3 normal, vec3 lightDir) {return max(dot(normal, lightDir), 0.0);
      }
      
  3. 纹理采样

    • 函数调用‌:使用 texture(sampler2D, uv) 读取纹理,需确保 UV 坐标在 [0,1] 范围内‌。
四、‌完整示例:带光照的纹理着色器‌

顶点着色器(Vertex Shader)

#version 450 core
layout (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() {FragPos = vec3(model * vec4(aPos, 1.0));  // 世界空间坐标Normal = mat3(transpose(inverse(model))) * aNormal; // 法线矩阵修正TexCoord = aTexCoord;gl_Position = projection * view * model * vec4(aPos, 1.0);
}

 片段着色器(Fragment Shader)

#version 450 core
in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoord;out vec4 FragColor;uniform vec3 lightPos;      // 光源位置
uniform vec3 lightColor;    // 光源颜色
uniform sampler2D diffuseTex; // 漫反射贴图void main() {// 采样纹理vec3 diffuse = texture(diffuseTex, TexCoord).rgb;// 计算光照vec3 norm = normalize(Normal);vec3 lightDir = normalize(lightPos - FragPos);float diff = max(dot(norm, lightDir), 0.0);vec3 result = diff * lightColor * diffuse;FragColor = vec4(result, 1.0);
}
五、‌关键注意事项
  1. 变量精度修饰符‌(可选但推荐)

    precision highp float;  // 指定浮点数精度(highp/mediump/lowp)
    
  2. 矩阵乘法顺序
    GLSL 矩阵乘法是列优先,需注意与 CPU 端矩阵操作的顺序一致性:

    mat4 mvp = projection * view * model;  // 正确顺序
    
  3. 纹理采样

    • 使用 texture(sampler, uv) 函数采样纹理
    • 纹理坐标需归一化到 [0,1] 范围
  4. 错误排查
    通过 glGetShaderInfoLog 获取编译错误信息:

    // Qt 中的调试代码示例
    if (!shaderProgram.link()) {qDebug() << "Shader Error:" << shaderProgram.log();
    }
    
六、‌常见问题
  1. 变量未传递‌:确保 uniform 变量在 CPU 端正确设置(如 setUniformValue("model", matrix))。

  2. 版本不匹配‌:GLSL 版本需与 OpenGL 上下文版本兼容(如 450 core 需 OpenGL 4.5+)。

  3. 纹理绑定错误‌:检查纹理单元是否激活(glActiveTexture(GL_TEXTURE0))。

  4. 调试日志输出‌:通过 glGetShaderInfoLog 获取编译错误详情‌。

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

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

相关文章

Docker容器之Dockerfile

用来构建镜像的文件。是指就是命令&#xff0c;参数&#xff0c;脚本。 指令合集以及说明 构建镜像图解: 实战测试&#xff1a; 构建自己的ubuntu&#xff1a; FROM ubuntu MAINTAINER liux ENV MYPATH /usr/local WORKDIR $MYPATH RUN apt-get update RUN apt install net-…

STM32G030移植RT-Thread

移植流程 移植前需要安装Keil.STM32G0xx_DFP.1.2.0.pack组件&#xff0c;大致的移植过程&#xff1a; CubeMX配置RT-Thread组件配置工程模板配置 参考例程配置&#xff1a;拷贝仓库原有的stm32g070-st-nucleo工程&#xff0c;然后另起一个名字&#xff0c;目录结构如下 完整…

【网络】网关

【网络】网关 网关 是计算机网络中用于连接两个不同网络的设备或服务器&#xff0c;它充当着“翻译器”和“转发器”的角色&#xff0c;将数据包从一个网络传递到另一个网络&#xff0c;并在必要时进行协议转换和数据重包装。 主要功能 数据转发&#xff1a;当本地网络设备发…

用JS+Promise实现简单消息队列

一、什么是消息队列 消息队列是一种用于在软件系统之间传递消息的技术。它常被用于解耦不同组件或模块之间的通信&#xff0c;减少系统中各个部分之间的直接依赖关系。消息队列可以实现异步通信&#xff0c;发送方将消息发送到队列中&#xff0c;接收方从队列中获取消息并进行处…

【Python爬虫】使用python脚本拉取汽车网站品牌数据

示例代码说明&#xff1a; 在汽车之家网站拉取当月排行榜中汽车品牌、销量和价格信息&#xff0c;存为csv文档输出&#xff0c;使用正则表达式获取网页内容 import re import pandas as pd import requests# 汽车之家车型列表页URL url https://cars.app.autohome.com.cn/ca…

批量修改 PPT 文档中主题、编辑时长、来源等元数据信息

每一个 PPT 文档被创建之后&#xff0c;都会包含一些元数据信息。这些元数据信息记录着文件的作者、创建时间、修改时间、打印时间等信息。这些信息默认都是自动生成的&#xff0c;如果我们想要对这些元数据进行修改&#xff0c;当然也是可以的。今天就给大家介绍一下如何批量修…

丐版插入selectdb模拟

为了模拟不断插入数据到库里&#xff0c;写个简单的循环脚本 #!/bin/bash #计算时差 function getTiming(){start$1end$2start_secho $start | cut -d . -f 1start_nsecho $start | cut -d . -f 2end_secho $end | cut -d . -f 1end_nsecho $end | cut -d . -f 2time_micro$((…

Off-Road-Freespace-Detection配置pytorch2.0.0

一、概述 在github上进行开源代码搜索&#xff0c;发现了Off-Road-Freespace-Detection&#xff08;链接如下所示&#xff09;。这是对越野环境可通行区域的检测&#xff0c;在经过测试之后&#xff0c;发现对自己有益。 GitHub - chaytonmin/Off-Road-Freespace-Detection: O…

常见中间件漏洞之四:Apache

1. CVE-2021-41773 Apache HTTP Server 路径穿越漏洞 漏洞简介 该漏洞是由于Apache HTTP Server 2.4.49版本存在⽬录穿越漏洞,在路径穿越⽬录<Directory/>Require all granted</Directory>允许被访问的的情况下&#xff08;默认开启&#xff09;&#xff0c;攻击…

Pytorch中Tensorboard的学习

1、Tensorboard介绍 TensorBoard 是 TensorFlow 开发的一个可视化工具&#xff0c;用于帮助用户理解和调试机器学习模型的训练过程。尽管它最初是为 TensorFlow 设计的&#xff0c;但通过 PyTorch 的 torch.utils.tensorboard 模块&#xff0c;PyTorch 用户也可以方便地使用 Te…

刷机维修进阶教程-----adb禁用错了系统app导致无法开机 如何保数据无损恢复机型

在刷机维修过程中 。我们会遇到一些由于客户使用adb指令来禁用手机app而导致手机无法开机进入系统的故障机型。通常此类问题机型有好几种解决方法。但如果客户需要保数据来恢复机型。其实操作也是很简单的.还有类似误删除应用导致不开机等等如何保数据。 通过博文了解💝💝�…

哪吒汽车:一边熬夜蹦迪,一边找药投医

两年前&#xff0c;威马CEO沈晖发了个短视频&#xff0c;内容是“活下去&#xff0c;像牲口一样活下去”。 如今最能体会沈晖当时心情的&#xff0c;估计就是方运舟了。 作为哪吒汽车创始人兼董事长&#xff0c;他连续多次被限高&#xff0c;为了让哪吒汽车活下去&#xff0c…

2025 cs144 Lab Checkpoint 1小白超详细版

cs144官网&#xff1a;https://cs144.github.io/ 我的github&#xff1a;https://github.com/Albert-tru/cs144-2025 文章目录 1 手动发送internet数据报协议号5、7&#xff1f;思路&#xff1f; 2 实现一个Reassembler类2.1 几个帮助理解代码的Q&AQ1&#xff1a;insert的参…

使用 OpenCV 拼接进行图像处理对比:以形态学操作为例

图像处理在计算机视觉中起着至关重要的作用&#xff0c;而 OpenCV 作为一个强大的图像处理库&#xff0c;提供了丰富的函数来实现各类图像处理任务。形态学操作&#xff08;Morphological Operations&#xff09;是其中常用的技术&#xff0c;尤其适用于二值图像的处理。常见的…

单链表的查找和插入,删除操作

1.单链表的查找 snode* slistfind(snode* stlheap, stltype x) {while (stlheap){if (stlheap->data x){return stlheap;}stlheap stlheap->next;}return NULL; } 2.单链表的插入操作 2.1在指定位置之前插入节点 void slistinsert(snode** stlheap, snode* pos, stl…

一文速通Python并行计算:00 并行计算的基本概念

一文速通 Python 并行计算&#xff1a;00 并行计算的基本概念 摘要&#xff1a; 该文介绍了 Python 并行计算的核心概念、编程模型及其应用&#xff0c;并介绍了了并行程序的性能分析与优化方法&#xff0c;如并行效率、加速比及 Amdahl 定律。此外&#xff0c;该文介绍了共享…

vue中keep-alive组件的使用

keep-alive是vue的内置组件&#xff0c;它的主要作用是对组件进行缓存&#xff0c;避免组件在切换时被重复创建和销毁&#xff0c;从而提高应用的性能和用户体验。它自身不会渲染一个 DOM 元素&#xff0c;也不会出现在父组件链中。使用时&#xff0c;只需要将需要缓存的组件包…

Python Excel表格数据对比工具

【Excel对比工具】提升工作效率的神奇助手&#xff1a;基于PyQt5和Pandas的文件数据对比应用 相关资源文件已经打包成EXE文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Python相关程序案例…

注册登录表单

html登录页面&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>创建一个登录页面</t…

JAVA:Spring Boot @Conditional 注解详解及实践

1、简述 在 Spring Boot 中&#xff0c;Conditional 注解用于实现 条件化 Bean 装配&#xff0c;即根据特定的条件来决定是否加载某个 Bean。它是 Spring 框架中的一个扩展机制&#xff0c;常用于实现模块化、可配置的组件加载。 本文将详细介绍 Conditional 相关的注解&…