Почему действительная текстура не достигает шейдера? (Direct3D9)
Привет всем, в настоящее время я пытаюсь создать отложенный рендер для моего графического движка, используя 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 похоже, что мои текстуры не передаются в шейдер правильно:
Следуя инструкциям, параметры текстуры и сэмплеры определяются следующим образом:
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 itselft, так как прохождение других обычных текстур также не работает.
1 ответ
Ответ на мою проблему так же прост, как проблема была глупой. Странное поведение было вызвано двумя разными ошибками:
- Я просто смотрел на неправильные события в PIX. Текстуры, которые мы правильно передали шейдеру, но я не видел, потому что он был "скрыт" в событии BeginPass (за "+").
- Пиксельный шейдер, который я пытался выполнить, так и не был вызван, потому что вершины полноэкранного четырехугольника, который я использовал для рендеринга, были нарисованы по часовой стрелке... мой CullMode также был установлен по часовой стрелке...
Спасибо всем, кто прочитал этот вопрос!