// shaders/phong.vert #version 330 core // 输入顶点属性 layout(location = 0) in vec3 vertexPosition_modelspace; layout(location = 1) in vec3 vertexNormal_modelspace; layout(location = 2) in vec2 vertexUV; // 输出到片元着色器 out vec3 Position_worldspace; out vec3 Normal_cameraspace; // 法线在相机空间计算,更准确 out vec3 EyeDirection_cameraspace; out vec3 LightDirection_cameraspace; out vec2 UV; // Uniform 变量 uniform mat4 MVP; // 模型-视图-投影 矩阵 uniform mat4 M; // 模型矩阵 uniform mat4 V; // 视图矩阵 uniform vec3 lightPos_worldspace; // 光源位置(世界空间) void main(){ // 输出顶点在世界空间的位置 Position_worldspace = (M * vec4(vertexPosition_modelspace, 1)).xyz; // 顶点在相机空间的位置 vec3 Position_cameraspace = (V * M * vec4(vertexPosition_modelspace, 1)).xyz; EyeDirection_cameraspace = vec3(0,0,0) - Position_cameraspace; // 视线方向 // 光源在相机空间的位置 vec3 LightPosition_cameraspace = (V * vec4(lightPos_worldspace, 1)).xyz; // 从顶点指向光源的方向(修正) LightDirection_cameraspace = LightPosition_cameraspace - Position_cameraspace; // 法线在相机空间 (M的逆转置矩阵乘以法线,这里简化为只用V*M,如果M有非等比缩放,需要更正规的 (transpose(inverse(M*V))) ) // 对于法线,我们通常使用模型视图矩阵的逆转置矩阵来变换。 // mat3 NormalMatrix = transpose(inverse(mat3(V * M))); // Normal_cameraspace = NormalMatrix * vertexNormal_modelspace; // 简化版,如果M只有旋转和平移,或者等比缩放: Normal_cameraspace = (V * M * vec4(vertexNormal_modelspace, 0)).xyz; // 计算裁剪空间中的顶点位置 gl_Position = MVP * vec4(vertexPosition_modelspace, 1); // 传递UV坐标 UV = vertexUV; }