I'm working on object cleaning in unity. This effect actually works.
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;
}

