如何用花生壳做网站,seo技巧是什么,网站的彩色标签怎么做的,天天向上做图网站我们在现实生活中看到某一物体的颜色并不是这个物体真正拥有的颜色#xff0c;而是它所反射的(Reflected)颜色。物体的颜色为物体从一个光源反射各个颜色分量的大小。
创建光照场景
首先需要创建一个光源#xff0c;因为我们以及有一个立方体数据#xff0c;我们只需要进行…我们在现实生活中看到某一物体的颜色并不是这个物体真正拥有的颜色而是它所反射的(Reflected)颜色。物体的颜色为物体从一个光源反射各个颜色分量的大小。
创建光照场景
首先需要创建一个光源因为我们以及有一个立方体数据我们只需要进行模型变换就可以将它变成我们的光源
unsigned int lightVAO;
glGenVertexArrays(1, lightVAO);
glBindVertexArray(lightVAO);
// 只需要绑定VBO不用再次设置VBO的数据因为箱子的VBO数据中已经包含了正确的立方体顶点数据
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 设置灯立方体的顶点属性对我们的灯来说仅仅只有位置数据
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
要注意的是当我们修改顶点或者片段着色器后灯的位置或颜色也会随之改变这并不是我们想要的效果。我们不希望灯的颜色在接下来的教程中因光照计算的结果而受到影响而是希望它能够与其它的计算分离。我们希望灯一直保持明亮不受其它颜色变化的影响这样它才更像是一个真实的光源。
为了实现这个目标我们需要为灯的绘制创建另外的一套着色器从而能保证它能够在其它光照着色器发生改变的时候不受影响。顶点着色器与我们当前的顶点着色器是一样的所以你可以直接把现在的顶点着色器用在灯上。灯的片段着色器给灯定义了一个不变的常量白色保证了灯的颜色一直是亮的
然后再渲染完物体以后把光源渲染出来 lightShader.use();lightShader.setMat4(projection, projection);lightShader.setMat4(view, view);model glm::mat4(1.0f);model glm::translate(model, lightPos);model glm::scale(model, glm::vec3(0.2f)); // a smaller cubelightShader.setMat4(model, model);glBindVertexArray(lightVAO);glDrawArrays(GL_TRIANGLES, 0, 36);
基础光照模型
环境光照(Ambient Lighting)即使在黑暗的情况下世界上通常也仍然有一些光亮月亮、远处的光所以物体几乎永远不会是完全黑暗的。为了模拟这个我们会使用一个环境光照常量它永远会给物体一些颜色。漫反射光照(Diffuse Lighting)模拟光源对物体的方向性影响(Directional Impact)。它是冯氏光照模型中视觉上最显著的分量。物体的某一部分越是正对着光源它就会越亮。镜面光照(Specular Lighting)模拟有光泽物体上面出现的亮点。镜面光照的颜色相比于物体的颜色会更倾向于光的颜色
法线变换矩阵
法向量只是一个方向向量不能表达空间中的特定位置。同时法向量没有齐次坐标顶点位置中的w分量。这意味着位移不应该影响到法向量。因此如果我们打算把法向量乘以一个模型矩阵我们就要从矩阵中移除位移部分只选用模型矩阵左上角3×3的矩阵注意我们也可以把法向量的w分量设置为0再乘以4×4矩阵这同样可以移除位移。对于法向量我们只希望对它实施缩放和旋转变换。
其次如果模型矩阵执行了不等比缩放顶点的改变会导致法向量不再垂直于表面了。因此我们不能用这样的模型矩阵来变换法向量。下面的图展示了应用了不等比缩放的模型矩阵对法向量的影响 每当我们应用一个不等比缩放时注意等比缩放不会破坏法线因为法线的方向没被改变仅仅改变了法线的长度而这很容易通过标准化来修复法向量就不会再垂直于对应的表面了这样光照就会被破坏。
修复这个行为的诀窍是使用一个为法向量专门定制的模型矩阵。这个矩阵称之为法线矩阵(Normal Matrix)。
这里对法线矩阵的解释参照了入门精要里的
变换后的法线与切线的点乘的结果也应该是0这里将变换后的矩阵与切线转置的原因是M*T得到的结果是一个3行1列的矩阵GN的结果是3行1列的矩阵而我们是为了获得法线变换的矩阵将前面得到的矩阵进行转置矩阵乘法才可以继续进行而且书里前面说过一个向量是可以当作列矩阵或者行矩阵的。最后的结果就是原变换矩阵的逆转置矩阵。 光照合并
顶点着色器
#version 330 core
layout (location 0) in vec3 aPos;
layout (location 1) in vec3 aNormal;out vec2 TexCoord;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;out vec3 FragPos;
out vec3 Normal;void main()
{gl_Position projection * view * model * vec4(aPos, 1.0);FragPos vec3(model * vec4(aPos, 1.0));Normal mat3(transpose(inverse(model))) * aNormal;
}
片段着色器
#version 330 core
out vec4 FragColor;
in vec3 FragPos;
in vec3 Normal;uniform vec3 objectColor;
uniform vec3 lightColor;
uniform vec3 lightPos;
uniform vec3 viewPos;void main()
{float ambientStrength 0.1;float specularStrength 0.5;vec3 ambient ambientStrength * lightColor;vec3 norm normalize(Normal);vec3 lightDir normalize(lightPos - FragPos);float diff max(dot(norm, lightDir), 0.0);vec3 diffuse diff * lightColor;vec3 viewDir normalize(viewPos - FragPos);vec3 reflectDir reflect(-lightDir, norm);float spec pow(max(dot(viewDir, reflectDir), 0.0), 16);vec3 specular specularStrength * spec * lightColor;vec3 result (ambient diffusespecular) * objectColor;FragColor vec4(result, 1.0);
} 材质
将三个材质的构成分量创建一个结构体
将光的属性也设置成结构体进而可以更好的控制着色器的各种属性
顶点着色器
#version 330 core
layout (location 0) in vec3 aPos;
layout (location 1) in vec3 aNormal;out vec3 FragPos;
out vec3 Normal;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main()
{FragPos vec3(model * vec4(aPos, 1.0));Normal mat3(transpose(inverse(model))) * aNormal; gl_Position projection * view * vec4(FragPos, 1.0);
}
片段着色器
#version 330 core
out vec4 FragColor;struct Material {vec3 ambient;vec3 diffuse;vec3 specular; float shininess;
}; struct Light {vec3 position;vec3 ambient;vec3 diffuse;vec3 specular;
};in vec3 FragPos;
in vec3 Normal; uniform vec3 viewPos;
uniform Material material;
uniform Light light;void main()
{// ambientvec3 ambient light.ambient * material.ambient;// diffuse vec3 norm normalize(Normal);vec3 lightDir normalize(light.position - FragPos);float diff max(dot(norm, lightDir), 0.0);vec3 diffuse light.diffuse * (diff * material.diffuse);// specularvec3 viewDir normalize(viewPos - FragPos);vec3 reflectDir reflect(-lightDir, norm); float spec pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);vec3 specular light.specular * (spec * material.specular); vec3 result ambient diffuse specular;FragColor vec4(result*10, 1.0);
}
光照贴图
效果 因为很多物体并不只是由一种材质构成的我们控制不同部分的属性所以引入了光照贴图
修改原来的结构体把漫反射和高光都修改为贴图,另外练习中增加的自发光贴图也加进去
贴图采样的原理和之前的教程差不多
顶点着色器
#version 330 core
layout (location 0) in vec3 aPos;
layout (location 1) in vec3 aNormal;
layout (location 2) in vec2 aTexCoords;out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoords;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main()
{FragPos vec3(model * vec4(aPos, 1.0));Normal mat3(transpose(inverse(model))) * aNormal; TexCoords aTexCoords;gl_Position projection * view * vec4(FragPos, 1.0);
}
片段着色器
最后的自发光贴图的加了个随时间移动和淡入淡出的效果并且箱子的钢铁部分是不应该有自发光的对自发光进行了限制
#version 330 core
out vec4 FragColor;struct Material {sampler2D diffuse;sampler2D specular; sampler2D emission;float shininess;
}; struct Light {vec3 position;vec3 ambient;vec3 diffuse;vec3 specular;
};in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords;uniform vec3 viewPos;
uniform Material material;
uniform Light light;
uniform float time;void main()
{// ambientvec3 ambient light.ambient * vec3(texture(material.diffuse, TexCoords)); // diffuse vec3 norm normalize(Normal);vec3 lightDir normalize(light.position - FragPos);float diff max(dot(norm, lightDir), 0.0);vec3 diffuse light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); // specularvec3 viewDir normalize(viewPos - FragPos);vec3 reflectDir reflect(-lightDir, norm); float spec pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);vec3 specular light.specular * spec * vec3(texture(material.specular, TexCoords)); vec3 emission texture(material.emission,TexCoordsvec2(0.0,time/2)).rgb;vec3 result ambient diffuse specularemission;FragColor vec4(result, 1.0);}