Изобразяването на линия в 1x1 RenderTarget2D не променя цвета на пиксела на целта

Това, което се опитвам да постигна, е следното: моят пропуск ще върне огромен масив с няколко уникални числа, повтарящи се отново и отново, които трябва да извлека и обработя на CPU.

Опитах се да изобразя в текстура 2000x1 и след това взех проби от процесора с RenderTarget2d.GetData‹>() и foreach цикъл. Стана ужасно бавно :). Така че заобиколих проблема си, идеята сега е да се изобрази на текстура 1x1 няколко пъти. Между преминаванията ще разширя масив от параметри в моя шейдър, за да включва вече върнатите числа. След това всеки пиксел ще направи запитване към масива и ще се изреже, ако съдържа число, което вече се е появило.

Проблемът сега е, че цветът на пикселите никога не се променя, независимо какво правя - винаги връща някои произволни числа. Когато добавих Game.GraphicsDevice.Clear(Color.Transparent); преди извикването за изтегляне, той започна да връща нули, въпреки че кодът на шейдъра трябва да върне 0.2f (или неговия еквивалент от 0 до 255). Може ли да е, защото изобразявам твърде малко съдържание в него (чертая линия на екрана и пробвам цвета на сцената по протежение на линията) и в даден момент то се изкривява?

C#/XNA код:

                            CollisionRT = new RenderTarget2D(Game.GraphicsDevice, 1, 1, false, SurfaceFormat.Color, DepthFormat.None);

...             
                Game.GraphicsDevice.BlendState = BlendState.AlphaBlend;
                Game.GraphicsDevice.SetRenderTarget(CollisionRT);
                Game.GraphicsDevice.Clear(Color.Transparent);
                Game.GraphicsDevice.DepthStencilState = DepthStencilState.None;

                foreach (ModelMesh mesh in PPCBulletInvis.Model.Meshes)
                    // PPCBulletInvis is a line that covers 1/18 of the screen (approx).
                {
                    foreach (Effect effect in mesh.Effects)
                    {
                        //effect.Parameters["Texture"].SetValue(vfTex);
                        effect.Parameters["halfPixel"].SetValue(halfPixel);
                        effect.Parameters["sceneMap"].SetValue(sceneRT);
                        effect.Parameters["World"].SetValue(testVWall.World);
                        effect.Parameters["View"].SetValue(camera.View);
                        effect.Parameters["Projection"].SetValue(camera.Projection);
                    }
                    mesh.Draw();
                }

                Game.GraphicsDevice.SetRenderTarget(null);

                Rectangle sourceRectangle =
                    new Rectangle(0, 0, 1, 1);

                Color[] retrievedColor = new Color[1];
                CollisionRT.GetData<Color>(retrievedColor);

                Console.WriteLine(retrievedColor[0].R); // Returns zeroes.

Код на шейдъра:

float4x4 World;
float4x4 View;
float4x4 Projection;

texture sceneMap;
sampler sceneSampler = sampler_state
{
    Texture = (sceneMap);
    AddressU = CLAMP;
    AddressV = CLAMP;
    MagFilter = POINT;
    MinFilter = POINT;
    Mipfilter = POINT;
};

float2 halfPixel;

struct VS_INPUT
{
    float4 Position     : POSITION0;
};
struct VS_OUTPUT
{
    float4 Position         : POSITION0;
    float4 ScreenPosition   : TEXCOORD2;
};


VS_OUTPUT VertexShaderFunction(VS_INPUT input)
{
    VS_OUTPUT output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);

    output.ScreenPosition = output.Position;
    return output;
}

float4 PixelShaderFunction(VS_OUTPUT input) : COLOR0
{
    input.ScreenPosition.xy /= input.ScreenPosition.w;

    float2 screenTexCoord = 0.5f * (float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 1);

    screenTexCoord -=halfPixel;

    return (0.2f,0.2f,0.2f,0.2f);//tex2D(sceneSampler, screenTexCoord);
}

technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_3_0 VertexShaderFunction();
        PixelShader = compile ps_3_0 PixelShaderFunction();
    }
}

person cubrman    schedule 26.07.2013    source източник
comment
Можете да опитате да изобразите вашата линия с XYZRHW, за да изобразите конкретни пиксели. Това трябва да избегне случая, в който вашата геометрия е изрязана. Коригирахте ли прозореца си за изглед?   -  person Gnietschow    schedule 27.07.2013
comment
Бихте ли разширили това, не мога да ви разбера ясно в две точки: какво е XYZRHW? Това, което се опитах да избегна изрязването, беше да напиша output.Position = (0,0,0,0); и изход.Позиция = (1,1,1,1); в шейдъра VERTEX, но не помогна - пикселът все още държи 0,0,0,0. Второ, моля, кажете ми какво имате предвид под коригиране на прозореца за изглед?   -  person cubrman    schedule 27.07.2013
comment
Мисля, че ако изобразявате към rendertarget с друго измерение като екран, трябва да коригирате размера в прозореца за изглед на графичното устройство: msdn.microsoft.com/en-us/library/. Бихте ли опитали да зададете output.Position = (0,0,0,1)? XYZRHW е тип vertexformat за задаване на позицията в екранното пространство, а не в световното пространство, по-лесно за рендиране, подравнено на екрана.   -  person Gnietschow    schedule 27.07.2013
comment
Уау, със сигурност ще опитам това!   -  person cubrman    schedule 27.07.2013
comment
Донякъде изобщо не работи. Дори когато задам прозореца си за изглед като 1 пиксел за цялата игра - той пак се изобразява на екрана. Viewport ColViewport = нов Viewport(); ColViewport.X = 0; ColViewport.Y = 0; ColViewport.Width = 1; ColViewport.Height = 1; Game.GraphicsDevice.Viewport = ColViewport;   -  person cubrman    schedule 28.07.2013
comment
btw позиция = (0,0,0,1) също не даде резултат   -  person cubrman    schedule 28.07.2013
comment
Опитах да изобразя до по-голяма текстура и забелязах, че пикселите просто се изкривяват (изкривяват) с останалите пиксели, когато се опитам да начертая много пиксели в малка цел за изобразяване. Предполагам, че истинският ми проблем е фактът, че трябва да предотвратя изкривяване на пикселите.   -  person cubrman    schedule 28.07.2013