Example #1
0
    void Update()
    {
        if (planeManager == null)
        {
            // True during edit mode execution
            Awake();
        }

        // Send the text in the child 3D text object to the camera bound to the
        // plane, to be displayed in the screen when the cam becomes active.
        ////////////////////////////////////////////////////////////////////
        string cameraName    = transform.parent.parent.parent.name;
        string planeInfoText = transform.parent.GetChild(1).GetComponent <TextMesh>().text;

        camToBind.GetComponent <ShaderCamGUI>().SetInfoText(
            cameraName + ": " + planeInfoText);


        // Setup camera to follow the plane in the scene.
        // Also match the viewport size to the plane.
        ////////////////////////////////////////////////
        // Set to orthographic. We wish to capture the whole plane, nothing else.
        camToBind.orthographic = true;

        // Scale target plane to precisely fit the image
        ////////////////////////////////////////////////
        // Get texture image width / height ratio
        float sizeRatio =
            (float)planeManager.GetSourceWidth() / planeManager.GetSourceHeight();

        // Evaluates possibly to true due to script execution order issues,
        // that apparently can't be helped with [ExecuteInEditMode] scripts
        if (!System.Single.IsNaN(sizeRatio))
        {
            // Match camera aspect ratio with texture image
            camToBind.aspect = sizeRatio;
            // Set camera viewport size to match the plane size.
            // x member is the horizontal scaling, x / planeScaleRatio equals the width
            // of the plane in world units (for a default sized plane, 1 / 0.1 == 10).
            // Division by two matches the sizing to camera orthographic size setting,
            // that is, half of the viewport width, and finally division by sizeRatio scales
            // the width to height.
            camToBind.orthographicSize =
                transform.localScale.x / planeScaleRatio / 2 / sizeRatio;
        }
        // Set camera position in front of the plane.
        camToBind.transform.position = transform.position + transform.up;
        // Make the camera face the plane.
        camToBind.transform.LookAt(transform);
    }
    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        // Setup data for detection area cornerpoint
        // display to be sent to the shader;
        daDisplay.SetCornerpointDisplayData(material5_EdgeDetectionAreas);

        // Due to initial first network source image delay on playback start,
        // a dummy texture of arbitrary size has been created to provide
        // valid data to scripts that depend on a non-zero sized source
        // texture. Because the size of the network image, once it arrives,
        // may be different from initial texture size, the size info needs
        // to be resent to shaders and processing plane rendertextures
        // recreated in correct dimensions.

        // Pass source texture dimensions to materials whose shaders need the info
        foreach (Material m in needSourceSizeMaterials)
        {
            m.SetFloat("_tWidth", (float)planeManager.GetSourceWidth());
            m.SetFloat("_tHeight", (float)planeManager.GetSourceHeight());
        }

        // Create and assign temporary rendertextures.
        // Fortunately, there's little overhead.
        for (int iTex = 0; iTex < rTextures.Length; ++iTex)
        {
            rTextures[iTex] = RenderTexture.GetTemporary(
                planeManager.GetSourceWidth(),
                planeManager.GetSourceHeight());

            transform.parent.parent.GetChild(1).GetChild((iTex + 1) * 2 + 1).
            GetChild(0).GetComponent <Renderer>().material.mainTexture = rTextures[iTex];
        }

        // Shader pass 1
        // Luminance-Brightness-Contrast-Gamma blitting
        ////////////////////////////////////////////////
        Graphics.Blit(
            src,
            rTextures[0],
            material2_LuminanceBrightnessContrastGamma);

        // Shader pass 2
        // Gaussian blur blitting
        ////////////////////////////////////////////////
        Graphics.Blit(
            rTextures[0],
            rTextures[1],
            material3_GaussianBlur);

        // Shader pass 3
        // Sobel edge detection
        ////////////////////////////////////////////////
        Graphics.Blit(
            rTextures[1],
            rTextures[2],
            material4_SobelEdgeDetection);

        // Shader
        // Edge detection areas
        ////////////////////////////////////////////////
        Graphics.Blit(
            rTextures[2],
            rTextures[3],
            material5_EdgeDetectionAreas);

        // Temporary rendertexture cleanup
        foreach (RenderTexture rt in rTextures)
        {
            RenderTexture.ReleaseTemporary(rt);
        }

        // Must Blit to screen as well, or OnGUI content won't display
        Graphics.Blit(src, (RenderTexture)null);
    }
Example #3
0
    public void SetCornerpointDisplayData(Material shaderMaterial)
    {
        cpList    = new List <SlotData.Cornerpoint>();
        colorList = new List <Color>();

        if (displayEdgeDetectionAreas)
        {
            // Edge detection cornerpoints have been selected to show up in the inspector

            if (slotScript.slotData.numberOfRows == 0)
            {
                if (!hasWarningBeenIssued)
                {
                    Debug.LogWarning("No detection area rows defined for " +
                                     transform.parent.parent.name + ".");
                    // Limit warnings to one per each playback
                    hasWarningBeenIssued = true;
                }
                return;
            }

            // Get corner points for each area
            for (int iRow = 0; iRow < slotScript.slotData.numberOfRows; ++iRow)
            {
                SlotData.Row row = slotScript.slotData.rows[iRow];
                for (int iSlot = 0; iSlot < row.numberOfSlots; ++iSlot)
                {
                    if (row.slots[iSlot].IsUndefined())
                    {
                        // Unset slot coordinates => skip
                        continue;
                    }
                    cpList.AddRange(row.slots[iSlot].areaCornerpoints);
                }
            }

            // Use texture to pass corner point data to the shader
            //////////////////////////////////////////////////////

            // 4 corner points for each defined slot
            // Each pixel value in texture can hold data for two points,
            // (== half a slot), i.e., sizeof(RGBA) == 2 * sizeof(XY).
            // Therefore, each slot will consume two pixels.

            // Slot N (Tex line N)  Tex px N  Px cpnts  Slot cornerpoints
            // 0                    0         RG        (X, Y)
            // 0                    0         BA        (X, Y)
            // 0                    1         RG        (X, Y)
            // 0                    1         BA        (X, Y)
            // -----------------------------------------------
            // 1                    2         RG        (X, Y)
            // 1                    2         BA        (X, Y)
            // 1                    3         RG        (X, Y)
            // 1                    3         BA        (X, Y)
            // -----------------------------------------------

            // etc.

            // Total number of slots in all parking rows
            int numSlotsTotal = cpList.Count / 4;
            // Number of required texture pixels to represent
            // coordinate points for every slot detection area
            // (one RGBA covers 2 out of 4 cornerpoints for a slot)
            int texturePixelCount = numSlotsTotal * 2;

            // Create texture that can hold corner pixel location data
            tex = new Texture2D(texturePixelsPerLine, numSlotsTotal);
            Color color = new Color(0f, 0f, 0f, 0f);
            for (int iPixel = 0; iPixel < texturePixelCount; ++iPixel)
            {
                // Two cornerpoints fit in the RGBA structure
                for (int iCp = 0; iCp < 2; ++iCp)
                {
                    SlotData.Cornerpoint cp = cpList[iPixel * 2 + iCp];
                    // Swap Y coordinate and interpolate pixel values
                    imageSlotExtractor.SwapY(ref cp.y, transform.parent.parent.GetSiblingIndex());
                    Vector2 interpCp = new Vector2(
                        (float)cp.x / planeManager.GetSourceWidth(),
                        (float)cp.y / planeManager.GetSourceHeight());
                    // Store interpolated [0...1] values.
                    if (iCp % 2 == 0)
                    {
                        // First coordinate pair that populates RG of RGBA
                        color.r = interpCp.x;
                        color.g = interpCp.y;
                    }
                    else
                    {
                        // Second coordinate pair that populates BA of RGBA
                        color.b = interpCp.x;
                        color.a = interpCp.y;
                        colorList.Add(color);
                    }
                }
            }

            // Setting filter mode to Point is a MUST! With default setting,
            // there's a LOT of pixel averaging and/or blending. We want
            // pure blocky content!
            tex.filterMode = FilterMode.Point;
            // Apply color data to the texture
            tex.SetPixels(colorList.ToArray());
            tex.Apply();

            // Pass texture data to the shader
            ///////////////////////////////////
            // Texture
            shaderMaterial.SetTexture("_ColorTex", tex);
            // Texture dimensions
            shaderMaterial.SetInt("_ColorTexWidth", texturePixelsPerLine);
            shaderMaterial.SetInt("_ColorTexHeight", numSlotsTotal);
            // Alternating colors for adjacent sets of four cornerpoints
            shaderMaterial.SetColor("_CornerColor0", cornerPointColorA);
            shaderMaterial.SetColor("_CornerColor1", cornerPointColorB);
            // Source image aspect ratio
            shaderMaterial.SetFloat("_MainTexAspectRatio",
                                    (float)planeManager.GetSourceWidth() / planeManager.GetSourceHeight());
            // Radius of colored cornerpoint square in the screen
            shaderMaterial.SetFloat("_CornerpointRadius", edgeCornerPointDisplayRadius);
        }
        // Enable variable needs to be passed outside of conditional block to ensure once enabled
        // borders are erased during playback if the user unselects the option in the inspector
        shaderMaterial.SetFloat("_DisplayCornerpoints", displayEdgeDetectionAreas ? 1.0f : 0.0f);
    }