版权声明:本文为 松阳 (blog.csdn.net/fansongy) 原创文章,转载必须注明出处: https://blog.csdn.net/fansongy/article/details/79303734
简单说来 投影 是将一个纹理贴到另一个模型或图片上的技术。在现实生活中,皮影戏就是根据这个原理产生的。
原理
参照皮影戏,我们需要一个投射器,一个采样图和一个成像模型。这样一想,跟OpenGL(十九)阴影 通过ShadowMap的shader实现中提到的投影模型是差不多的。不同之处在于,不需要采集深度图,当进行到第二步时,也不需要比较深度。而是直接取出采样图中texcoord对应的颜色进行混合。
实现
依照之前所述,在shader中我们需要像素上的点转换到投影视口中,然后依照texcoord从采样图中取色。
//vs
attribute vec3 pos;
attribute vec2 texcoord;
attribute vec3 normal;
uniform mat4 M;
uniform mat4 P;
uniform mat4 V;
uniform mat4 U_ProjectorMatrix;
varying vec2 V_Texcoord;
varying vec3 V_WorldPos;
varying vec4 V_ProjectCoord;
void main()
{
V_Texcoord=texcoord;
vec4 worldPos=M*vec4(pos,1.0);
V_WorldPos=worldPos.xyz;
V_ProjectCoord=U_ProjectorMatrix*worldPos;
gl_Position=P*V*worldPos;
}
//fs
uniform sampler2D U_ProjectiveTexture;//projective texture
uniform sampler2D U_MainTexture;
varying vec2 V_Texcoord;
varying vec3 V_WorldPos;
varying vec4 V_ProjectCoord;
void main()
{
if(V_ProjectCoord.z>0.0)
{
gl_FragColor=texture2D(U_MainTexture,V_Texcoord)*textureProj(U_ProjectiveTexture,V_ProjectCoord);
}
else
{
gl_FragColor=texture2D(U_MainTexture,V_Texcoord);
}
}
有遮挡的投影
当成像物体不止一个时,投影通常要能体现出被投影物体的遮挡关系。这时就要用到深度图的比较了,根据z值来衡量是否需要投影采样图。具体可以结合之前的文章,比较简单就不实现了。
总结
本文介绍了如何制造投影。另外,在非平行光的情况下,可以制作出有形变的投影哦。