1

大家好,我目前正在尝试使用 c# 和 SlimDX 为我的图形引擎创建延迟渲染器。作为资源,我使用教程非常有用,尽管它是为 XNA 设计的。但是现在我被困住了……我将渲染器设置为绘制所有几何图形的颜色、法线和深度,以分离渲染目标纹理。这行得通。我可以将生成的纹理作为精灵绘制到恢复的后台缓冲区,并且我可以看到它们包含了它们应该包含的内容。但是当我尝试将这些纹理传递给另一个着色器时,在这种情况下创建光照贴图时,会发生奇怪的事情。这是我绘制一帧的方法:

public bool RenderFrame(FrameInfo fInfo){
    if(!BeginRender()) //checks Device, resizes buffers, calls BeginScene(), etc.
         return false;
    foreach(RenderQueue queue in fInfo.GetRenderQueues()){
        RenderQueue(queue);
    }
    EndRender(); //currently only calls EndScene, used to do more
    ResolveGBuffer();
    DrawDirectionalLight(
        new Vector3(1f, -1f, 0), 
        new Color4(1f,1f,1f,1f), 
        fi.CameraPosition, 
        SlimMath.Matrix.Invert(fi.ViewProjectionMatrix));
}

private void ResolveGBuffer() {
    if(DeviceContext9 == null || DeviceContext9.Device == null)
        return;
    DeviceContext9.Device.SetRenderTarget(0, _backbuffer);
    DeviceContext9.Device.SetRenderTarget(1, null);
    DeviceContext9.Device.SetRenderTarget(2, null);
}

private void DrawDirectionalLight(Vector3 lightDirection, Color4 color, SlimMath.Vector3 cameraPosition, SlimMath.Matrix invertedViewProjection) {
    if(DeviceContext9 == null || DeviceContext9.Device == null)
        return;
        DeviceContext9.Device.BeginScene();
       _directionalLightShader.Shader.SetTexture(
           _directionalLightShader.Parameters["ColorMap"], 
           _colorTexture);
       _directionalLightShader.Shader.SetTexture(
           _directionalLightShader.Parameters["NormalMap"], 
           _normalTexture);
       _directionalLightShader.Shader.SetTexture(
           _directionalLightShader.Parameters["DepthMap"], 
           _depthTexture);
       _directionalLightShader.Shader.SetValue<Vector3>(
           _directionalLightShader.Parameters["lightDirection"], 
           lightDirection);
       _directionalLightShader.Shader.SetValue<Color4>(
           _directionalLightShader.Parameters["Color"], 
           color);
       _directionalLightShader.Shader.SetValue<SlimMath.Vector3>(
           _directionalLightShader.Parameters["cameraPosition"], 
           cameraPosition);
       _directionalLightShader.Shader.SetValue<SlimMath.Matrix>(
           _directionalLightShader.Parameters["InvertViewProjection"], 
           invertedViewProjection);
       _directionalLightShader.Shader.SetValue<Vector2>(
           _directionalLightShader.Parameters["halfPixel"], 
           _halfPixel);

       _directionalLightShader.Shader.Technique = 
           _directionalLightShader.Technique("Technique0");

       _directionalLightShader.Shader.Begin();
       _directionalLightShader.Shader.BeginPass(0);
       RenderQuad(SlimMath.Vector2.One * -1, SlimMath.Vector2.One);
       _directionalLightShader.Shader.EndPass();
       _directionalLightShader.Shader.End();
       DeviceContext9.Device.EndScene();
}

现在,当我用一些代码替换对 DrawDirectionalLight 的调用以将 _colorTexture、_normalTexture 和 _depthTexture 绘制到屏幕上时,一切看起来都很好,但是当我使用 DrawDirectionalLight 函数时,我看到了疯狂的闪烁。从 PIX 的输出看来,我的纹理没有正确传递给着色器:

pix_screenshot

按照教程,纹理参数和采样器定义如下:

float3 lightDirection;
float3 Color;
float3 cameraPosition;
float4x4 InvertViewProjection;
texture ColorMap;
texture NormalMap;
texture DepthMap;

sampler colorSampler = sampler_state{
Texture  = ColorMap;
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter= LINEAR;
MinFilter= LINEAR;
MipFilter= LINEAR;
};

sampler depthSampler = sampler_state{
Texture  = DepthMap;
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter= POINT;
MinFilter= POINT;
MipFilter= POINT;
};

sampler normalSampler = sampler_state{
Texture  = NormalMap;
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter= POINT;
MinFilter= POINT;
MipFilter= POINT;
};

现在我最大的问题是为什么?没有打印错误消息来调试输出。

编辑:

渲染目标/纹理是这样创建的:

_colorTexture = new Texture(DeviceContext9.Device,
            DeviceContext9.PresentParameters.BackBufferWidth,
            DeviceContext9.PresentParameters.BackBufferHeight,
            1,
            Usage.RenderTarget,
            Format.A8R8G8B8,
            Pool.Default);

        _colorSurface = _colorTexture.GetSurfaceLevel(0);

        _normalTexture = new Texture(DeviceContext9.Device,
            DeviceContext9.PresentParameters.BackBufferWidth,
            DeviceContext9.PresentParameters.BackBufferHeight,
            1,
            Usage.RenderTarget,
            Format.A8R8G8B8,
            Pool.Default);

        _normalSurface = _normalTexture.GetSurfaceLevel(0);

        _depthTexture = new Texture(DeviceContext9.Device,
            DeviceContext9.PresentParameters.BackBufferWidth,
            DeviceContext9.PresentParameters.BackBufferHeight,
            1,
            Usage.RenderTarget,
            Format.A8R8G8B8,
            Pool.Default);

        _depthSurface = _depthTexture.GetSurfaceLevel(0);

编辑2:

问题似乎在于 directionalLightShader 本身,因为传递其他常规纹理也不起作用。

4

1 回答 1

0

我的问题的答案很简单,因为问题很愚蠢。奇怪的行为是由 2 个不同的错误引起的:

  1. 我只是在查看 PIX 中的错误事件。我们正确传递给着色器的纹理但我没有看到它,因为它在 BeginPass 事件中“隐藏”(在“+”后面)。
  2. 我试图执行的像素着色器从未被调用,因为我用来渲染的全屏四边形的顶点是按顺时针顺序绘制的......我的 CullMode 也设置为顺时针......

感谢所有阅读此问题的人!

于 2011-08-30T10:59:31.833 回答