Lew*_*wis 9 opengl shader glsl
我最近在GLSL中写了一个Phong着色器作为学校作业的一部分.我从教程开始,然后使用代码,直到我开始工作.据我所知,它的工作完全正常,但我特别写了一行,我不明白它为什么会起作用.
顶点着色器:
#version 330
layout (location = 0) in vec3 Position; // Vertex position
layout (location = 1) in vec3 Normal; // Vertex normal
out vec3 Norm;
out vec3 Pos;
out vec3 LightDir;
uniform mat3 NormalMatrix; // ModelView matrix without the translation component, and inverted
uniform mat4 MVP; // ModelViewProjection Matrix
uniform mat4 ModelView; // ModelView matrix
uniform vec3 light_pos; // Position of the light
void main()
{
Norm = normalize(NormalMatrix * Normal);
Pos = Position;
LightDir = NormalMatrix * (light_pos - Position);
gl_Position = MVP * vec4(Position, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
片段着色器:
#version 330
in vec3 Norm;
in vec3 Pos;
in vec3 LightDir;
layout (location = 0) out vec4 FragColor;
uniform mat3 NormalMatrix;
uniform mat4 ModelView;
void main()
{
vec3 normalDirCameraCoords = normalize(Norm);
vec3 vertexPosLocalCoords = normalize(Pos);
vec3 lightDirCameraCoords = normalize(LightDir);
float dist = max(length(LightDir), 1.0);
float intensity = max(dot(normalDirCameraCoords, lightDirCameraCoords), 0.0) / pow(dist, 1.001);
vec3 h = normalize(lightDirCameraCoords - vertexPosLocalCoords);
float intSpec = max(dot(h, normalDirCameraCoords), 0.0);
vec4 spec = vec4(0.9, 0.9, 0.9, 1.0) * (pow(intSpec, 100) / pow(dist, 1.2));
FragColor = max((intensity * vec4(0.7, 0.7, 0.7, 1.0)) + spec, vec4(0.07, 0.07, 0.07, 1.0));
}
Run Code Online (Sandbox Code Playgroud)
所以我正在做的方法是计算光矢量和相机矢量之间的半矢量,然后用法线点.这一切都很好.但是,我做了两件很奇怪的事情.
通常,一切都在眼睛坐标中完成.但是,我从顶点着色器传递到片段着色器的位置在本地坐标中.
这是困扰我的部分.就行了vec3 h = normalize(lightDirCameraCoords - vertexPosLocalCoords);
,我减去光矢量相机在顶点位置坐标的本地坐标.这似乎是完全错误的.
简而言之,我理解这段代码应该做什么,以及phong着色的半矢量方法是如何工作的.
但为什么这段代码有效呢?
编辑:我们提供的入门代码是开源的,因此您可以下载已完成的项目,如果您愿意,可以直接查看.该项目适用于Windows上的VS 2012(您需要设置GLEW,GLM和freeGLUT),并且应该在GCC上工作而不需要更改代码(可能是makefile库路径的一两个更改).
请注意,在源文件中,"light_pos"被称为"gem_pos",因为我们的光源是您使用WSADXC移动的小宝石.按M键以获得多个灯光的Phong.
这种作用的原因是偶然的,但有趣的是看它为何仍然有效.
Phong着色是三种技术于一体
使用phong着色,我们有三个术语:镜面反射,漫反射和环境 ; 这三个术语代表了phong着色中使用的三种技术.
这些术语都不严格要求向量空间; 只要你是一致的,你就可以在世界,地方或相机空间中进行phong着色.眼睛空间通常用于照明,因为它更容易使用,转换也很简单.
但是如果你在原点呢?现在你乘以零; 很容易看出原点上任何向量空间之间没有区别.巧合的是,在起源时,你所处的向量空间并不重要; 它会工作的.
vec3 h = normalize(lightDirCameraCoords - vertexPosLocalCoords);
Run Code Online (Sandbox Code Playgroud)
请注意,它基本上减去0; 这是本地唯一使用的时间,并且它在一个地方使用它可以造成最小的伤害.由于物体位于原点,因此它的所有顶点也应该位于原点或非常接近原点.在原点,近似是精确的; 所有向量空间汇合.非常接近原点,它非常接近精确; 即使我们使用精确的实数,它也是一个非常小的分歧,但我们不使用精确的实数,我们使用浮点数,使问题复杂化.
基本上,你很幸运; 如果对象不在原点,这将不起作用.尝试移动它,看看!
另外,你没有使用Phong着色 ; 你正在使用Blinn-Phong着色(这是用半向量替换reflect()的名称,仅供参考).
归档时间: |
|
查看次数: |
832 次 |
最近记录: |