好的。如果您在寻找工作着色器时遇到问题,可以参考示例(老实说,您可以在任何 OpenGL 书籍中找到它)。
此着色器程序将使用您的对象的世界矩阵和相机的矩阵来变换顶点,然后将一个纹理映射到像素并用一个定向光照亮它们(根据材质属性和光方向)。
顶点着色器:
#version 330
// Vertex input layout
attribute vec3 inPosition;
attribute vec3 inNormal;
attribute vec4 inVertexCol;
attribute vec2 inTexcoord;
attribute vec3 inTangent;
attribute vec3 inBitangent;
// Output
struct PSIn
{
vec3 normal;
vec4 vertexColor;
vec2 texcoord;
vec3 tangent;
vec3 bitangent;
};
out PSIn psin;
// Uniform buffers
layout(std140)
uniform CameraBuffer
{
mat4 mtxView;
mat4 mtxProj;
vec3 cameraPosition;
};
layout(std140)
uniform ObjectBuffer
{
mat4 mtxWorld;
};
void main()
{
// transform position
vec4 pos = vec4(inPosition, 1.0f);
pos = mtxWorld * pos;
pos = mtxView * pos;
pos = mtxProj * pos;
gl_Position = pos;
// just pass-through other stuff
psin.normal = inNormal;
psin.tangent = inTangent;
psin.bitangent = inBitangent;
psin.texcoord = inTexcoord;
psin.vertexColor = inVertexCol;
}
和片段着色器:
#version 330
// Input
in vec3 position;
in vec3 normal;
in vec4 vertexColor;
in vec2 texcoord;
in vec3 tangent;
in vec3 bitangent;
// Output
out vec4 fragColor;
// Uniforms
uniform sampler2D sampler0;
layout(std140)
uniform CameraBuffer
{
mat4 mtxView;
mat4 mtxProj;
vec3 cameraPosition;
};
layout(std140)
uniform ObjectBuffer
{
mat4 mtxWorld;
};
layout(std140)
uniform LightBuffer
{
vec3 lightDirection;
};
struct Material
{
float Ka; // ambient quotient
float Kd; // diffuse quotient
float Ks; // specular quotient
float A; // shininess
};
layout(std140)
uniform MaterialBuffer
{
Material material;
};
// function to calculate pixel lighting
float Lit( Material material, vec3 pos, vec3 nor, vec3 lit, vec3 eye )
{
vec3 V = normalize( eye - pos );
vec3 R = reflect( lit, nor);
float Ia = material.Ka;
float Id = material.Kd * clamp( dot(nor, -lit), 0.0f, 1.0f );
float Is = material.Ks * pow( clamp(dot(R,V), 0.0f, 1.0f), material.A );
return Ia + Id + Is;
}
void main()
{
vec3 nnormal = normalize(normal);
vec3 ntangent = normalize(tangent);
vec3 nbitangent = normalize(bitangent);
vec4 outColor = texture(sampler0, texcoord); // texture mapping
outColor *= Lit( material, position, nnormal, lightDirection, cameraPosition ); // lighting
outColor.w = 1.0f;
fragColor = outColor;
}
如果你不想要纹理,就不要采样纹理,而是等同outColor
于vertexColor
.
如果您不需要照明,只需注释掉Lit()
功能。
编辑:
对于 2D 对象,您仍然可以使用相同的程序,但许多功能将是多余的。你可以去掉:
- 相机
- 光
- 材料
- 所有的 vertex
attribute
s,但是inPosition
and inTexcoord
(也许inVertexCol
你也需要 vertexs 有颜色)和所有与不需要attribute
的 s相关的代码
inPosition
可vec2
- 您将需要传递正交投影矩阵而不是透视一
- 您甚至可以剥离矩阵,并以像素为单位传递顶点缓冲区。请参阅我的回答,了解如何将这些像素位置转换为屏幕空间位置。您可以在 C/C++ 代码或 GLSL/HLSL 中执行此操作。
希望它以某种方式有所帮助。