В качестве прототипа, нужно было сделать рисование на песке. От первоначальной идеи отказались, но наработка немного необычная.
Есть plane/quad на ней простой материал с поддержкой прозрачности, текстура песка с включенным read/write. Когда мы нажимаем ЛКМ на текстуре в зоне луча от мыши накладывается прозрачность по шаблону кисти 1. Когда нажимаем ПКМ рисунок восстанавливается по шаблону кисти 2. Действия происходят при помощи методов GetPixels / SetPixels.
Кисть 1, Кисть 2
PS: Плохокод, собрано за несколько часов, но авось пригодиться.
using UnityEngine; public class DrawSand : MonoBehaviour { public Collider myCollider; public Renderer myRenderer; public Texture2D eraser; public Texture2D painter; private Texture2D org; private Texture2D tex; void Start() { org = myRenderer.material.mainTexture as Texture2D; tex = new Texture2D(org.width, org.height); tex.SetPixels(0, 0, org.width, org.height, org.GetPixels(0, 0, org.width, org.height)); tex.Apply(); myRenderer.material.mainTexture = tex; } void Update() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Input.GetMouseButton(0) || Input.GetMouseButton(1)) { if (Physics.Raycast(ray, out hit, Mathf.Infinity)) { Color[] tcls = new Color[eraser.width * eraser.height]; Color[] ocls = new Color[eraser.width * eraser.height]; Color[] acls = eraser.GetPixels(); Color[] pcls = painter.GetPixels(); // Find the u,v coordinate of the Texture Vector2 uv; uv.x = (hit.point.x - hit.collider.bounds.min.x) / hit.collider.bounds.size.x; uv.y = (hit.point.y - hit.collider.bounds.min.y) / hit.collider.bounds.size.y; // Paint it tcls = tex.GetPixels((int)(uv.x * tex.width), (int)(uv.y * tex.height), eraser.width, eraser.height); ocls = org.GetPixels((int)(uv.x * tex.width), (int)(uv.y * tex.height), eraser.width, eraser.height); for (int i = 0; i < tcls.Length; i++) { if (Input.GetMouseButton(0)) tcls[i].a = Mathf.Min(tcls[i].a, acls[i].a); if (Input.GetMouseButton(1)) tcls[i].a = Mathf.Max(tcls[i].a, pcls[i].a); } tex.SetPixels((int)(uv.x * tex.width), (int)(uv.y * tex.height), eraser.width, eraser.height, tcls); tex.Apply(); } } } }
Комментарии
Отправить комментарий