Vertex And Fragment Shader(顶点和片段着色器)

Vertex And Fragment Shader(顶点和片段着色器)

Shader "Unlit/ Vertex­_And_Fragment_Shader "

{

                  Properties

         {

                   _MainColor("主颜色", color) = (1, 1, 1, 1)

         }

         SubShader

         {

                   Tags { "RenderType"="Opaque" }

                   LOD 100

                   Pass

                   {

      //固定的一些格式

                            Tags{"LightModel" = "ForwardBase"}             

                            CGPROGRAM

                   //声明为顶点着色器  vertex 关键字  vert是顶点着色器渲染时执行的函数

                            #pragma vertex vert

                   //声明为片段着色器 fragment 为关键字 frag是片段着色器渲染时执行的函数

                            #pragma fragment frag

                            //调用的unity中的指令(标签)

                            #include "UnityCG.cginc"

                            #include "Lighting.cginc"

                   //应用阶段数据  获取应用阶段的数据 模型的顶点颜色 法线 切线之类的数据

                            struct appdata

                            {

                            //float4  变量的属性  vertex是变量名 POSITION是一个语义 作用:把模型空间的顶点位置放入前面的变量中  这个语义可以自动填充

                                     float4 vertex : POSITION;

                                     float3 normal : NORMAL;//获取模型的顶点法线

                            };

                            //V  To F 顶点着色器的数据传递给片段着色器

                            struct v2f

                            {

//SV_POSITION 也是一个语义  规定变量只能接收投影空间下的顶点位置

                                     float4 vertex : SV_POSITION; 

                                     fixed3 col:Color0;                         //得到颜色传到片段着色器

                            };

                            float4 _MainColor;   //声明主颜色

                            v2f vert (appdata v)

                            {

                                     v2f o;                           //得到v2f数据

                                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);    //获得position

                                     //归一化后的光照方向向量 

                                     float3 LiaghtDir = normalize(ObjSpaceLightDir(v.vertex));

                                     //对顶点的法线方向向量和光照方向向量进行点积

                                     float Ndotl =saturate(dot(normalize(v.normal), LiaghtDir));

                                     //环境光、unity自带光线、主颜色叠加

fixed3 diffus =  Ndotl*_LightColor0.rgb + UNITY_LIGHTMODEL_AMBIENT.rgb+_MainColor.rgb;

                                     o.col = diffus;   //赋值

                                     return o;        

                            }

                            fixed4 frag (v2f i) : SV_Target   //SV_Target  缓冲区 

                            {

                               return fixed4 (i.col, 1);  //渲染到窗口

                            }

                            ENDCG

                   }

         }

}

 注:POSITION、SV_POSITION等是Unity为了方便对模型数据的传输,进行了特别的含义规定。语义就是一个赋给Shader输入和输出的字符串,表达了一些参数的含义,也就是让Shader知道从哪里读取数据,并把数据输出到哪里。

转载于:https://www.cnblogs.com/XiaoLang0/p/9524688.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,你需要创建一个顶点着色器和一个片段着色器的文件。这些文件通常使用GLSL语言编写。 下面是一个简单的顶点着色器的例子: ``` #version 330 core layout (location = 0) in vec3 aPos; void main() { gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); } ``` 这个着色器接受一个顶点坐标,将其作为输入变量 aPos,并将其转换为标准化设备坐标(NDC)中的位置。然后,它将位置赋值给内置输出变量 gl_Position。 下面是一个简单的片段着色器的例子: ``` #version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); } ``` 这个着色器只是简单地将输出颜色设置为橙色。 接下来,你需要在代码中加载这些着色器文件并编译它们。以下是一个使用GLFW和GLEW库的简单示例: ```c++ #include <GL/glew.h> #include <GLFW/glfw3.h> #include <iostream> const char* vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "void main()\n" "{\n" " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" "}\0"; const char* fragmentShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "void main()\n" "{\n" " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" "}\n\0"; int main() { // 初始化 GLFW glfwInit(); // 创建窗口 GLFWwindow* window = glfwCreateWindow(800, 600, "My Title", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // 初始化 GLEW glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cout << "Failed to initialize GLEW" << std::endl; return -1; } // 编译顶点着色器 GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); // 检查顶点着色器编译是否成功 GLint success; GLchar infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "Failed to compile vertex shader\n" << infoLog << std::endl; return -1; } // 编译片段着色器 GLuint 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 << "Failed to compile fragment shader\n" << infoLog << std::endl; return -1; } // 创建着色器程序 GLuint 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 << "Failed to link shader program\n" << infoLog << std::endl; return -1; } // 删除着色器对象 glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // 渲染循环 while (!glfwWindowShouldClose(window)) { glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // 使用着色器程序 glUseProgram(shaderProgram); // 绘制三角形 glBegin(GL_TRIANGLES); glVertex3f(-0.5f, -0.5f, 0.0f); glVertex3f(0.5f, -0.5f, 0.0f); glVertex3f(0.0f, 0.5f, 0.0f); glEnd(); // 交换缓冲区并检查是否有触发事件 glfwSwapBuffers(window); glfwPollEvents(); } // 删除着色器程序 glDeleteProgram(shaderProgram); // 终止 GLFW glfwTerminate(); return 0; } ``` 在这个示例中,我们首先定义了顶点着色器片段着色器的源代码字符串。然后,我们编译这些着色器并链接它们成一个着色器程序。最后,我们在渲染循环中使用这个着色器程序。 注意,着色器程序在使用后需要删除,以释放内存。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值