为什么有效的纹理不能到达着色器? (的Direct3D9)

时间:2011-08-28 12:17:46

标签: c# direct3d slimdx

大家好我正在尝试使用c#和SlimDX为我的图形引擎创建延迟渲染器。作为一种资源,我使用this教程非常有用,尽管它适用于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;
};

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

修改

rendertargets / textures的创建方式如下:

_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:

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

1 个答案:

答案 0 :(得分:0)

我的问题的答案就像问题是愚蠢一样简单。奇怪的行为是由两个不同的错误引起的:

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