Monogame / XNA / HLSL阴影映射仅在播放器周围发生

时间:2014-09-07 16:08:12

标签: c# xna shader hlsl monogame

我最近开始玩Monogame(OpenSource"翻拍" XNA)。我目前的任务是编写一个简单的阴影贴图着色器。在跟随Riemer's XNA Tutorial之后,我得到了阴影。但有趣的是,只有"播放器" (相机)是。当我在光线的半径之外时,相机周围没有光线出现(这很好),但是我的聚光灯当然应该仍然存在。但事实并非如此。我的聚光灯下的阴影和明亮的灯光只出现在玩家周围。

正如我所说,我的HLSL代码与Riemer完全相同(除了我在VertexShaderInput结构中编写SV_POSITION而不是POSITION0,因为MonoGame仅支持Pixel- / Vertexshader 4.0及更高版本)

我也有一种感觉,我的Light-View / -Projection矩阵可能会出错:

Matrix lightsView = Matrix.CreateLookAt(lightPos, new Vector3(lightPos.X, lightPos.Y-1, lightPos.Z), new Vector3(0, 0, 1));
Matrix lightsProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45F), 1f, 1f, 10f);

(我知道我的" up"向量并没有指向上方;这是我让光从它的位置向下指向的唯一方法,否则它总是指向(0 -1 0)即使我写了它以便使用灯光坐标然后它会从光线变为y -1 - 真的很奇怪......)

我真的希望有人知道这里有什么,这个问题阻止我在我的代码中做了几天其他事情......

PS:这是我的渲染代码:

    ////In my Model-Class
    private void DrawModel(string tech)
    {
        Matrix[] transforms = new Matrix[model.Bones.Count];
        model.CopyAbsoluteBoneTransformsTo(transforms);

        foreach (var mesh in model.Meshes)
        {
            foreach (ModelMeshPart part in mesh.MeshParts)
            {
                part.Effect = Game1.effect;
                Matrix tempWorld = ((transforms[mesh.ParentBone.Index] * Matrix.CreateScale(scale)) * rotationMatrix) * Matrix.CreateTranslation(pos);
                part.Effect.CurrentTechnique = part.Effect.Techniques[tech];
                part.Effect.Parameters["xWorldViewProjection"].SetValue(tempWorld * Game1.camera.View * Game1.camera.Projektion);
                part.Effect.Parameters["xTexture"].SetValue(textures[part]);
                part.Effect.Parameters["xWorld"].SetValue(tempWorld);
                part.Effect.Parameters["xLightPos"].SetValue(Game1.currentLevel.lightPos);
                part.Effect.Parameters["xLightPower"].SetValue(Game1.currentLevel.lightPower);
                part.Effect.Parameters["xAmbient"].SetValue(Game1.currentLevel.ambientPower);
                part.Effect.Parameters["xLightsWorldViewProjection"].SetValue(tempWorld * Game1.currentLevel.lightsViewProjectionMatrix);
                part.Effect.Parameters["xShadowMap"].SetValue(Game1.currentLevel.shadowMap);
            }

            mesh.Draw();
        }
    }

    ////In my Level-Class
    public void Render()
    {
        var device = Game1.graphics.GraphicsDevice;

        device.SetRenderTarget(renderTarget);
        device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);

        DrawScene("ShadowMap");

        device.SetRenderTarget(null);
        shadowMap = (Texture2D)renderTarget;

        device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
        DrawScene("ShadowedScene");
    }

    private void DrawScene(string tech)
    {
        foreach (var model in models)
        {
            model.Render(tech);
        }
    }

和光更新代码:

private void UpdateLightData()
    {
        ambientPower = 0.2f;

        lightPos = new Vector3(-0.2F, 1.2F, 1.1F);

        lightPower = 1.8f;

        Matrix lightsView = Matrix.CreateLookAt(lightPos, new Vector3(lightPos.X, lightPos.Y-1, lightPos.Z), new Vector3(0, 0, 1));
        Matrix lightsProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45F), 1f, 1f, 10f);

        lightsViewProjectionMatrix = lightsView * lightsProjection;
    }

0 个答案:

没有答案