);?
?
? ? EyeNormal = normalize(NormalMatrix * VertexNormal);?
? ? EyePosition = ModelViewMatrix * pos4;?
? ? ProjTexCoord = ProjectorMatrix * (ModelMatrix * pos4);?
? ? gl_Position = MVP * pos4;?
}?
上面的代码前两行是将法线和顶点坐标变换到eye space。
然后是计算投影纹理坐标:先将位于object space的坐标变换到world space,然后通过左乘纹理投影矩阵变换计算出纹理投影坐标。
最后计算内置的gl_Position即剪切平面坐标。
片断着色器projtex.fs(下面只列出一部分):
#version 400?
?
in vec3 EyeNormal;? ? ? // Normal in eye coordinates?
in vec4 EyePosition;? ? // Position in eye coordinates?
in vec4 ProjTexCoord;?
?
uniform sampler2D ProjectorTex;?
?
layout( location = 0 ) out vec4 FragColor;?
?
void main() {?
? ? vec3 color = phongModel(vec3(EyePosition), EyeNormal);?
?
? ? vec4 projTexColor = vec4(0.0);?
? ? if( ProjTexCoord.z > 0.0 )?
? ? ? ? //textureProj:纹理坐标各分量会除以最后一个分量?
? ? ? ? projTexColor = textureProj( ProjectorTex, ProjTexCoord );?
?
? ? FragColor = vec4(color,1.0) + projTexColor * 0.5;?
}?
#version 400?
?
in vec3 EyeNormal;? ? ? // Normal in eye coordinates?
in vec4 EyePosition;? ? // Position in eye coordinates?
in vec4 ProjTexCoord;?
?
uniform sampler2D ProjectorTex;?
?
layout( location = 0 ) out vec4 FragColor;?
?
void main() {?
? ? vec3 color = phongModel(vec3(EyePosition), EyeNormal);?
?
? ? vec4 projTexColor = vec4(0.0);?
? ? if( ProjTexCoord.z > 0.0 )?
? ? ? ? //textureProj:纹理坐标各分量会除以最后一个分量?
? ? ? ? projTexColor = textureProj( ProjectorTex, ProjTexCoord );?
?
? ? FragColor = vec4(color,1.0) + projTexColor * 0.5;?
}?
函数phongModel是计算phong光照模型的。
注意其中的textureProj函数,它专门用于投影纹理访问的。它的纹理坐标的各分量会除以最后一个分量,然后才访问纹理。
在这个例子中,我们假设投影仪位于(2.0,5.0,5.0),朝向是(-2.0,-4.0,0.0),方向(0.0,1.0,0.0)是向上的。我们采用了一个外部库GLM库来根据投影仪的这些信息计算出各个变换矩阵,代码如下:
vec3 projPos = vec3(2.0f,5.0f,5.0f);?
vec3 projAt = vec3(-2.0f,-4.0f,0.0f);?
vec3 projUp = vec3(0.0f,1.0f,0.0f);?
mat4 projView = glm::lookAt(projPos, projAt, projUp);?
mat4 projProj = glm::perspective(30.0f, 1.0f, 0.2f, 1000.0f);?
mat4 projScaleTrans = glm::translate(vec3(0.5f)) * glm::scale(vec3(0.5f));?
prog.setUniform("ProjectorMatrix", projScaleTrans * projProj * projView);?
?
vec3 projPos = vec3(2.0f,5.0f,5.0f);?
vec3 projAt = vec3(-2.0f,-4.0f,0.0f);?
vec3 projUp = vec3(0.0f,1.0f,0.0f);?
mat4 projView = glm::lookAt(projPos, projAt, projUp);?
mat4 projProj = glm::perspective(30.0f, 1.0f, 0.2f, 1000.0f);?
mat4 projScaleTrans = glm::translate(vec3(0.5f)) * glm::scale(vec3(0.5f));?
prog.setUniform("ProjectorMatrix", projScaleTrans * projProj * projView);?