Shader基础学习入门--计算机图形学--第二课

这里简单的讲解一下学习shader所涉及的一些图形学知识

Unity程序员必了解的图形程序接口

OpenGL(Open Graphics Library)

中文翻译过来是开放图形库,它定义了一个跨平台、跨语言的编程接口规格的专业图形程序接口,可以用于3D、2D图形渲染,是一个功能强大、调用方便的底层图形库。由于它跨平台、跨语言、出现时间早,因此它的应用极其广泛!

OpenGL ES(OpenGL for Embedded Systems)

中文翻译过来是用于嵌入式系统的开放图形库,它是OpenGL的子级主要针对手机、游戏主机等嵌入式设备而设计,免授权费、跨平台、功能完善。

GLES2.0、GLES3.0 指的就是OpenGL ES这套标准,他们也是Android和IOS手机上常用的图形处理标准。

Unity在移动平台进行图形渲染处理时,就包含了OpenGL ES方案

Vulkan

“下一代”开放的图形显示API,是与DX12能够匹敌的GPU API标准。它有一套最新的图形加速API接口,目标是提供更灵活和丰富的底层操作接口,以替代OpenGL 和 OpenGL ES接口,以把Vulkan看做是OpenGL的升级版,目前新版本的Unity支持使用Vulkan方案

Directx(Direct eXtension)

中文翻译过来是直接拓展,简称DX。它是由微软公司创建的多媒体编程接口。它不跨平台,只针对微软的相关产品,被广泛使用于Windows操作系统、xBox游戏主机的图形应用程序开发中。

其中的D3D算是DX一部分,是对标OpenGL的图形程序接口

WebGL(Web Graphics Library)

中文翻译过来是网页图形库,它是针对Web端(网页)的3D绘图协议,这个标准允许把JavaScript和OpenGL ES 2.0结合在一起,网页开发人员可以借助系统显卡在浏览器里流畅的展示3D场景和模型,可以在网页里进行3D图形开发。

Metal

中文翻译过来是金属,它是苹果公司为游戏开发者提供的图形技术,该技术能够为3D图像提高10倍渲染性能,但是它不支持跨平台,主要针对IOS、macOS苹果自家的操作系统,只有苹果手机、电脑能够使用。

总而言之就是:

1. OpenGL(跨平台,几乎所有平台都能使用)

2. DX(针对微软相关平台,微软的Windows)

3. Metal(针对苹果相关平台,苹果的Mac OS )

4. Web GL(针对网页相关)

Shader和图形接口程序的关系

Shader(着色器)是一种小型程序,用于自定义渲染数据的处理,从而决定最 终的渲染效果。 图形接口程序(OpenGL、DX等)为Shader开发提供了各种API,Shader开发 需要针对不同的图形接口程序使用不同的Shader开发语言来调用相关API。 图形接口程序会将Shader程序和渲染管线的各个阶段连接起来,它会把我们的 数据和指令传递给硬件(GPU等),从而实现图形渲染的最终呈现。

图形接口程序对应Shader开发的语言

 OpenGL:GLSL(OpenGL Shading Language)

DX: HLSL(High-Level Shading Language)

Metal: MSL(Metal Shading Language)

WebGL: GLSL ES(OpenGL ES Shading Language)

注意:OpenGL、WebGL、Metal: 原点位于屏幕左下角 DX:原点位于屏幕左上角(注意:最新的DX12可以改为左下角原点)

这里提供一个简单的OpenGL代码示例,演示如何进行着色、纹理映射等基本图形渲染操作。 ```c++ #include <glad/glad.h> #include <GLFW/glfw3.h> #include <iostream> // 窗口大小 const unsigned int SCR_WIDTH = 800; const unsigned int SCR_HEIGHT = 600; // 顶点着色器代码 const char *vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "layout (location = 1) in vec3 aColor;\n" "layout (location = 2) in vec2 aTexCoord;\n" "out vec3 ourColor;\n" "out vec2 TexCoord;\n" "void main()\n" "{\n" " gl_Position = vec4(aPos, 1.0);\n" " ourColor = aColor;\n" " TexCoord = vec2(aTexCoord.x, aTexCoord.y);\n" "}\0"; // 片段着色器代码 const char *fragmentShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "in vec3 ourColor;\n" "in vec2 TexCoord;\n" "uniform sampler2D ourTexture;\n" "void main()\n" "{\n" " FragColor = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0f);\n" "}\n\0"; int main() { // 初始化GLFW glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // 初始化GLAD if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; return -1; } // 编译顶点着色器 int success; char infoLog[512]; unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // 编译片段着色器 unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // 创建着色器程序 unsigned int shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // 设置顶点数据 float vertices[] = { // 位置 // 颜色 // 纹理坐标 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // 右上角 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 右下角 -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // 左下角 -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // 左上角 }; unsigned int indices[] = { 0, 1, 3, // 第一个三角形 1, 2, 3 // 第二个三角形 }; unsigned int VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); glEnableVertexAttribArray(2); // 创建纹理 unsigned int texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); // 设置纹理参数 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; stbi_set_flip_vertically_on_load(true); unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0); if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } else { std::cout << "Failed to load texture" << std::endl; } stbi_image_free(data); // 渲染循环 while (!glfwWindowShouldClose(window)) { // 输入处理 processInput(window); // 渲染指令 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // 绑定纹理 glBindTexture(GL_TEXTURE_2D, texture); // 设置uniform glUseProgram(shaderProgram); int textureLocation = glGetUniformLocation(shaderProgram, "ourTexture"); glUniform1i(textureLocation, 0); // 绘制矩形 glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // 交换缓冲区和轮询IO事件 glfwSwapBuffers(window); glfwPollEvents(); } // 释放资源 glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); glfwTerminate(); return 0; } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); } ``` 这段代码实现了一个简单的矩形渲染,并将颜色和纹理信息传递到顶点和片段着色器中进行处理。在渲染循环中,先绑定纹理,设置uniform,然后绘制矩形。注意,这里使用了stb_image库来加载纹理图片。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值