1
\$\begingroup\$

I have a relatively big Texture, and I try to find a certain color pixels pattern: eg. White, Black, White, Green . They are lying next to each other,

If I use Texture2d.Getpixels() on every pixel every frame its possible, but way too slow.

Is there a "real good" way to do this? For example a shader way?

The "big idea" is to make a game which is "remote-playable". For example through Twitch or of a streamed youtube video. The user should not be connected to the server in any way, Instead he is sending messages or not.

For this I have to find a health bar. This health bar has the left-upper corner in black-> white -> black -> green pixels lying next to each other.

In the shader I CAN find these colors, but I dont really know the coordinates. Also I think there "should" be a solution with a ... compute shader? I dont really want to render new stuff. Just check pixel colors. I just want to know where these pixel colors are.

I imagined something like this:

If PixelColorIsWhite(x,y) { If PixelColorIsBlack(x+1,y) { If PixelColorIsWhite(x+2,y) { If PixelColorIsGreen(x+3,y) { return x+20,y+100 //because the player is 20 pixels right and 100 pixels below }}}}

In a shader i guess i can access the current coordinate, but I cant access the other pixels. Its paralell processing... right? So its impossible to access the "entire thing" in one go , right?

I think it must work somehow with... getting the big "chunk" of texture data, a very long array of pixels, giving it to a compute shader, and letting the CS find it.

I hope I could clarify the problem now :)

_-----------------------------------

Update:

I found out it (at least) should work with a compute shader.

I feel like im so close to the solution, yet im getting errors. :-(

So...

This is my C# Code:

public ComputeShader shader;
public Material thisMat;

public RenderTexture ScreenTex;


public int x;
public int y;

public const string INPUTTEX = "InputTexture";

private void Update()
{
    RunShader();
}

public void RunShader()
{
    RenderTexture tex = new RenderTexture(1024, 786, 24);
    tex.enableRandomWrite = true;
    tex.Create();

    shader.SetTexture(0, INPUTTEX, ScreenTex);
    shader.SetFloat("_ScreenWidth", Camera.main.pixelWidth);
    shader.SetFloat("_ScreenHeight", Camera.main.pixelHeight);

    int[] data = new int[2];
    ComputeBuffer buffer = new ComputeBuffer(data.Length, sizeof(int)*2);
    buffer.SetData(data);
    shader.SetBuffer(0, "readWriteIntBuffer", buffer);

    thisMat.mainTexture = tex;
    int kernelHandle = shader.FindKernel("CSMain");

    shader.SetTexture(kernelHandle, "Result", tex);
    shader.Dispatch(kernelHandle, 1024 / 8, 786 / 8, 1);

    buffer.GetData(data);

    x = data[0];
    y = data[1];
    buffer.Release();}

And this is my ComputeShader Code:

    -------------------
    #pragma kernel CSMain

RWTexture2D<float4> Result;

RWStructuredBuffer<int> readWriteIntBuffer;
Texture2D<float4> InputTexture;
float _ScreenWidth;
float _ScreenHeight;


[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
    if (id.x >= (uint)(_ScreenWidth*_ScreenHeight))
    {
        return;
    }

    int y = id.x / int(_ScreenWidth);
    int x = id.x % int(_ScreenWidth);
    readWriteIntBuffer[0] = 999; //some debug-testnumbers that show me that there were no colors found
    readWriteIntBuffer[1] = 998;

    if (InputTexture[float2(x,y)].r == 1.0f && InputTexture[float2(x, y)].g == 0.0f && InputTexture[float2(x, y)].b == 0.0f)
{
    float2 coordinates = float2((float)id.x / (float)_ScreenWidth, (float)id.y / (float)_ScreenHeight);


    readWriteIntBuffer[0] = coordinates.x;
    readWriteIntBuffer[1] = coordinates.y;

}
}

This Computeshader checks if a single pixel in a texture is red and writs it in a buffer. The buffer gets read by C# with getdata. -- it seems we're almost getting there! But "something" seems to be wrong, since I dont seem to get the colors i want. But the compute shader seems to work, since i also get the triange-pattern in my material.

\$\endgroup\$
8
  • 2
    \$\begingroup\$ Can you clarify for us what feature this is helping to power? What do these specific patterns of pixels mean? What causes these patterns of pixels to appear? What consequence needs to follow when a pattern like this is found? These details can help us identify potential efficiencies or better solutions. \$\endgroup\$
    – DMGregory
    Nov 7, 2018 at 22:59
  • \$\begingroup\$ Yes, tell us what you're trying to do rather than how you're trying to do it. \$\endgroup\$ Nov 8, 2018 at 3:54
  • \$\begingroup\$ thank you, I updated my question to be a bit more clearly \$\endgroup\$
    – OC_RaizW
    Nov 8, 2018 at 9:39
  • \$\begingroup\$ What do you do with these positions once you've identified them? How does having the position change what message you send or not send? \$\endgroup\$
    – DMGregory
    Nov 8, 2018 at 12:11
  • \$\begingroup\$ The position I get is the player character's position, relative to the "camera". I need them so I can calculate a simulated mouseclick position relative to the camera. The messages are dependand on the current player position. Clicking right-top of the player should do something else than clicking left-bottom of the player. \$\endgroup\$
    – OC_RaizW
    Nov 8, 2018 at 12:57

0

You must log in to answer this question.

Browse other questions tagged .