如何做几何投影阴影?

我已经决定,因为我的游戏世界大多是平坦的,我不需要比几何投影更好的阴影 – 至less现在。

唯一的问题是,我甚至不知道如何正确地做这些 – 也就是生成一个4×4的matrix,这个matrix会为我的对象渲染阴影(也就是我猜测它们是在一个水平的XZ平面上)。

我想要一个无穷远处的光源(例如,天空中的某个点的太阳),从而平行投影。

我目前的代码对于小型飞行物体来说看起来几乎是正确的,但实际上是一个非常粗略的近似值,因为它不会将物体投影到地面上,而只是将它们移动到那里(我认为)。 也总是错误地认为太阳总是在天顶(直射下来)。

Gdx.gl20.glEnable(GL10.GL_BLEND); Gdx.gl20.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); //shells shellTexture.bind(); shader.begin(); for (ShellState state : shellStates.values()) { transform.set(camera.combined); transform.mul(state.transform); shader.setUniformMatrix("u_worldView", transform); shader.setUniformi("u_texture", 0); shellMesh.render(shader, GL10.GL_TRIANGLES); } shader.end(); // shadows shader.begin(); for (ShellState state : shellStates.values()) { transform.set(camera.combined); m4.set(state.transform); state.transform.getTranslation(v3); m4.translate(0, -v3.y + 0.5f, 0); // TODO HACK: + 0.5f is a hack to ensure the shadow appears above the ground; this is overall a hack as we are just moving the shell to the surface instead of projecting it on the surface! transform.mul(m4); shader.setUniformMatrix("u_worldView", transform); shader.setUniformi("u_texture", 0); // TODO: make shadow black somehow shellMesh.render(shader, GL10.GL_TRIANGLES); } shader.end(); Gdx.gl.glDisable(GL10.GL_BLEND); 

所以我的问题是:

a)产生一个Matrix4传递给openGL的正确方法是什么,它会渲染我的对象的阴影?

b)我应该使用另一个片段着色器来处理半透明灰色的阴影,对吗?

c)这种简单化方法的局限性在于,只要地面上有物体(不平坦),阴影就不会被绘制出来,是正确的吗?

d)我是否需要在y(向上)坐标上添加一些非常小的东西,以避免与地面纹理进行z对战? 或者事实上它们是半透明的以解决这个问题?

(a)为了产生一个“南瓜”matrix,它将物体平行于给定的太阳vector砸碎到地平面上,我将通过构造两个matrix来构建它:

  1. 剪切matrix将太阳向量映射到+ Y(直线向上),同时保持X和Z轴不变。
  2. 一个缩放matrix,可将Y缩放为零,而X和Z保持不变。

具体来说,假设你正在使用列向量(因为这是通常的OpenGL惯例),乘以后,这就是:

 [ 1 (-sun.x / sun.y) 0 0 ] [ 0 0 0 0 ] [ 0 (-sun.z / sun.y) 1 0 ] [ 0 0 0 1 ] 

sun是指向sun的向量。 我认为它总是在天空的上半部分,即sun.y> 0。

(b)你可以在这里做各种各样的事情。 以半透明的黑色或灰色绘制压扁的阴影几何graphics是一种可能性。 如果你这样做,你也应该使用模板缓冲区,以确保每个像素只有一个黑暗。 (例如,如果模板== 0configuration模板testing通过,并且在绘制阴影像素时将模板缓冲区写入1到模板缓冲区)。否则,如果被压扁的对象有多个“图层”,则会多次变暗。

另一种可能性是添加环境光和定向光通过,并使用模板缓冲区来屏蔽掉任何有阴影的方向光。

(c)正确。

(d)是的,z战斗可能是一个问题。 你可以添加一个小的偏移量,或者更好的方法是使用硬件多边形偏移量 。