1
\$\begingroup\$

I'm working on object cleaning in unity. This effect actually works.

enter image description here

What I still need is the progress, do you have any idea how can I count the progress of the cleaning?

(my code is below)

Thank you so much!

public class PaintWithMouse : MonoBehaviour
{
    [SerializeField] private Shader drawShader; 
    [SerializeField] [Range (1,500)] private float size;

    private RenderTexture _splatMap; 
    private Material _currentMaterial, _drawMaterial; 
    private RaycastHit _hit;
    private bool _paintMode;
    private bool _cleaning;

    private static readonly int SplatMap = Shader.PropertyToID("SplatMap");
    private static readonly int Coordinates = Shader.PropertyToID("_Coordinates");
    private static readonly int Size = Shader.PropertyToID("_Size");

    private void Start()
    {
        _drawMaterial = new Material(drawShader);

        _currentMaterial = GetComponent<MeshRenderer>().material;

        _splatMap = new RenderTexture(256, 256, 0, RenderTextureFormat.ARGBFloat);

        _currentMaterial.SetTexture(SplatMap, _splatMap);
    }

    private void Update()
    {
        if (!UnityEngine.Input.GetMouseButton(0)) return;
        
        if (!Physics.Raycast(Camera.main.ScreenPointToRay(UnityEngine.Input.mousePosition), out _hit)) return;
        
        _drawMaterial.SetVector(Coordinates, new Vector4(_hit.lightmapCoord.x, _hit.lightmapCoord.y, 0, 0));
        _drawMaterial.SetFloat(Size, size);
        
        var temp = RenderTexture.GetTemporary(_splatMap.width, _splatMap.height, 0, RenderTextureFormat.ARGBFloat);

        Graphics.Blit(_splatMap, temp);
        Graphics.Blit(temp, _splatMap, _drawMaterial);
        
        RenderTexture.ReleaseTemporary(temp);
    }
}

        struct appdata
        {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;
            UNITY_FOG_COORDS(1)
            float4 vertex : SV_POSITION;
        };

        sampler2D _MainTex;
        float4 _MainTex_ST;
        fixed4 _Coordinates;
        half _Size;
        
        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v. vertex);
            o.uv = TRANSFORM_TEX(v.uv, _MainTex);
            return o;
        }
        
        fixed4 frag (v2f i) : SV_Target
        {
            fixed4 col = tex2D(_MainTex, i.uv); 
            float draw =  pow(saturate (1- distance (i.uv, _Coordinates.xy)), 500/_Size);
            return saturate (col + draw);
        }

Update: The problem is that when I compare changes on all pixels in the render texture, I don't get the correct result. Probably because the UV map only occupies part of the surface in the render texture. When I clean the whole object, the result is about 70%.

(my code is below)

There is any way to check what part of the render texture takes the UV map?

private void SaveToArray()
{
    RenderTexture.active = _splatMap;

    var tex = new Texture2D(256, 256, TextureFormat.RGB24, false);

    tex.ReadPixels(new Rect(0, 0, _splatMap.width, _splatMap.height), 0, 0);

    tex.Apply();

    startColors = new Color[_splatMap.width, _splatMap.height];

    float pixelCount = 0;

    for (var i = 0; i < tex.width; i++)
    {
        for (var j = 0; j < tex.height; j++)
        {   
            startColors[i, j] = tex.GetPixel(i, j);
            pixelCount++;
        }
    }

    RenderTexture.active = null;
}

private void CompareArrays()
{
    var tex = new Texture2D(256, 256, TextureFormat.RGB24, false);
    
    RenderTexture.active = _splatMap;
    
    tex.ReadPixels(new Rect(0, 0, _splatMap.width, _splatMap.height), 0, 0);
    
    tex.Apply();

    float pixelCount = 0;
    float changedPixelCount = 0;

    for (var i = 0; i < tex.width; i++)
    {
        for (var j = 0; j < tex.height; j++)
        {
            pixelCount += 1;
            
            if (startColors[i, j] != tex.GetPixel(i, j))
            {
                changedPixelCount += 1;
            }
        }
    }

    float cleanPercent = changedPixelCount / pixelCount;
    
    Debug.Log(cleanPercent);

    RenderTexture.active = null;
}

enter image description here

\$\endgroup\$
2
  • 3
    \$\begingroup\$ Your cleaning effect is setting values in a 256 x 256 texture. So, a natural measure of progress is to count how many texels have the clean value out of the total, or sum the total difference between each texel's value and the clean value, if you want more analog gradation. I'd assume you considered making a CPU-side array (possibly of a lower resolution) to count which parts of the texture you've cleaned this way? Where did you run into difficulty with this? \$\endgroup\$ Commented Mar 10, 2022 at 11:30
  • \$\begingroup\$ Thank you for your answer, I updated the post. If you have any idea I would be grateful for your help. \$\endgroup\$ Commented Mar 10, 2022 at 13:59

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.