<Shader>第一段Shader程序

本文介绍了Shader的基础知识,包括Shader程序的结构,如Properties、SubShader和FallBack的重要性。通过示例展示了如何编写Shader来定义物体颜色、材质、透明度,并解释了SubShader中的pass和相关参数设置,如blend、material、lighting等,帮助初学者入门OpenGL Shader编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一段OpenGL代码

Shader "Shader/Shader_001" {

    properties{
        _Color("Main Color",color) = (1,1,1,1)     
    }

    SubShader{
        pass {
            color [_Color] //顶点的颜色
        }
    }
}

在Shader 程序中,Properties 和 FallBack 是可有可无的,但是SubShaders 在程序片段中是必须有的,但是没有Properties 我们讲无法为Shader定制属性,没有FallBack的时候,当任何一个SubShaders都无效的时候,我们的着色将失败。

下面为一个完整的Shader ,可以设置物体的材质,和透明度

Shader "Shader/Shader_002" {

    properties{
        _Color("Main Color",color) = (1,0.5,0.5,1)
        _Ambient("Main Ambien",color) = (0.3,0.3,0.3,0.3)
        _Specular("Main Specular",color) = (0.3,0.3,0.3,0.3)
        _Shininess("Main shininess",range(0,8)) = 8
        _Emission("Main Color",color) = (1,1,1,1)
        _Constantcolor("main constantcolor",color) = (1,1,1,1)
        _Texture("Main Texture",2d) = ""
        _Texture1("sceond tetxure",2d) = ""
    }

    SubShader
    {
        Tags { "Queue" = "Transparent" }
        pass 
        {
            blend SrcAlpha OneMinusSrcAlpha
            material 
            {
                diffuse [_Color]
                ambient    [_Ambient]  //环境光
                specular[_Specular] //高光
                shininess [_Shininess]     //高光反射的强度 到底有多强
                emission [_Emission]  //自发光
            }
            lighting on
            separatespecular on  //像镜子一样的独立的高光

            settexture[_Texture]
            {
                combine texture * primary  double
            }

            settexture[_Texture1]
            {
                constantcolor [_Constantcolor]
                combine texture * previous doubletexture * constant
            }
        }
    }
}

为什么下面这段程序会报错[错误] ld returned 1 exit status#include <GL/glew.h> #include <GLFW/glfw3.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <bits/stdc++.h> #include <iostream> const int WIDTH = 800; const int HEIGHT = 600; struct GameObject { glm::vec3 position; glm::vec3 color; unsigned int VAO; int vertexCount; }; struct Physics { glm::vec3 velocity; bool isShooting = false; }; GameObject basketball; GameObject hoop; Physics ballPhysics; float hoopHeight = 3.0f; unsigned int shaderProgram; // 创建着色器程序 unsigned int createShaderProgram(const char* vs, const char* fs) { unsigned int vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vs, NULL); glCompileShader(vertex); unsigned int fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fs, NULL); glCompileShader(fragment); unsigned int program = glCreateProgram(); glAttachShader(program, vertex); glAttachShader(program, fragment); glLinkProgram(program); glDeleteShader(vertex); glDeleteShader(fragment); return program; } // 生成球体模型 void generateSphere(GameObject& obj, float radius) { std::vector<float> vertices; const int sectors = 32; const int stacks = 32; for(int i = 0; i <= stacks; ++i) { float phi = glm::pi<float>() * (float)i / stacks; for(int j = 0; j <= sectors; ++j) { float theta = 2 * glm::pi<float>() * (float)j / sectors; float x = radius * sin(phi) * cos(theta); float y = radius * cos(phi); float z = radius * sin(phi) * sin(theta); vertices.insert(vertices.end(), {x, y, z}); } } unsigned int VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(float), vertices.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0); glEnableVertexAttribArray(0); obj.VAO = VAO; obj.vertexCount = (int)vertices.size()/3; } // 生成篮筐模
03-30
void CreateClosedRoad(GameObject customQuadGO, List<Vector3> points, Material loadedMat) { if (points.计数 < 4) throw new ArgumentException(“至少需要4个以上的点才能创建一条闭合道路”); // 确保道路是闭合的,复制首个元素到末尾模拟闭合效果 List<Vector3> closedPoints = DuplicatePathToFormStrip(points); List<int> indices = GenerateTriangleIndicesForClosure(closedPoints.Count); // 构建 Mesh 数据 Mesh mesh = new Mesh(); mesh.vertices = closedPoints.ToArray(); // 设置顶点位置 mesh.triangles = indices.ToArray(); // 设置三角形索引 // 计算法线和 UV 映射 (可选,提升视觉质量) mesh.RecalculateNormals(); // 将生成的 Mesh 应用到游戏对象上 var mf = customQuadGO.AddComponent<MeshFilter>(); mf.mesh = mesh; // 添加渲染组件 customQuadGO.AddComponent<MeshRenderer>(); Renderer renderer = customQuadGO.GetComponent<Renderer>(); renderer.material = loadedMat; // 应用材质 } 私有 List<Vector3> DuplicatePathToFormStrip(List<Vector3> originalPoints) { List<Vector3> duplicatedPoints = new List<Vector3>(); for (int i = 0; i < originalPoints.Count; i++) { // 每个原有点都对应两条平行路径 Vector3 direction = GetDirectionAtPoint(originalPoints, i).normalized; Vector3 perpendicular = Vector3.Cross(direction, Vector3.up).normalized; // 左侧点(偏移向外) duplicatedPoints.Add(originalPoints[i] - perpendicular * roadWidth / 2f); // 右侧点(偏移向内) duplicatedPoints.Add(originalPoints[i] + perpendicular * roadWidth / 2f); } return duplicatedPoints; } // 辅助方法:获取某一点的方向向量(假设两点间方向) 私有 Vector3 GetDirectionAtPoint(List<Vector3> points, int index) { 如果 (索引 == 0) 返回点数[1] - 点数[0];// 第一个点采用下一段方向 else if (index == points.计数 - 1) 返回点数[index] - 点数[index - 1];// 最后一个点采用前一段方向 还 返回 (points[index + 1] - points[index - 1]).normalized;// 其他点取中间方向 } List<int> GenerateTriangleIndicesForClosure(int vertexCount) { if (vertexCount < 4 || vertexCount % 2 != 0) throw new ArgumentException(“顶点计数应为偶数且大于或等于 4。”); List<int> indices = new List<int>(); // 构建内部矩形分割 for (int i = 0; i < vertexCount - 2; i += 2) { int leftStart = i; int rightStart = i + 1; // 添加第一个三角形 indices.AddRange(new int[] { leftStart, rightStart, leftStart + 2 }); // 添加第二个三角形 indices.AddRange(new int[] { rightStart, rightStart + 2, leftStart + 2 }); } // 完善闭环处理 if (vertexCount >= 4) { int firstLeft = 0; int firstRight = 1; int lastLeft = vertexCount - 2; int lastRight = vertexCount - 1; // 关联最后一排回到第一列构成封闭结构 indices.AddRange(new int[] { lastLeft, lastRight, firstLeft }); indices.AddRange(new int[] { lastRight, firstRight, firstLeft }); } return indices; }上面代码中顶点坐标围成的mesh是带状的 如何给围成的区域染色
03-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值