OpenGL(二十) 投影 的shader实现

简单说来 投影 是将一个纹理贴到另一个模型或图片上的技术。在现实生活中,皮影戏就是根据这个原理产生的。

原理

参照皮影戏,我们需要一个投射器,一个采样图和一个成像模型。这样一想,跟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值来衡量是否需要投影采样图。具体可以结合之前的文章,比较简单就不实现了。

总结

本文介绍了如何制造投影。另外,在非平行光的情况下,可以制作出有形变的投影哦。

你可能感兴趣的:(OpenGL,OpenGL,从入门到起飞)