using System.Collections; using System.Collections.Generic; using UnityEngine; public class Ripple : MonoBehaviour { public Camera mainCamera; public RenderTexture InteractiveRT;//交互RT public RenderTexture PrevRT; //上一幀 public RenderTexture CurrentRT;//當前幀 public RenderTexture TempRT; //臨時RT public Shader DrawShader; //繪製Shader public Shader RippleShader;//漣漪計算Shader public Shader AddShader; private Material RippleMat; private Material DrawMat; private Material AddMat; [Range(0, 1.0f)] public float DrawRadius = 0.2f; public int TextureSize = 512; // Start is called before the first frame update void Start() { //TODO獲取相機 mainCamera = Camera.main.GetComponent(); CurrentRT = CreateRT(); PrevRT = CreateRT(); TempRT = CreateRT(); DrawMat = new Material(DrawShader); RippleMat = new Material(RippleShader); //AddMat = new Material(AddShader); GetComponent().material.mainTexture = CurrentRT; Application.targetFrameRate = 120; } public RenderTexture CreateRT() { RenderTexture rt = new RenderTexture(TextureSize, TextureSize, 0, RenderTextureFormat.RFloat); //rt.Create(); return rt; } /// /// 繪製 /// /// /// /// 半徑 private void DrawAt(float x, float y, float radius) { //原來的貼圖 DrawMat.SetTexture("_SourceTex", CurrentRT); //繪製的位置和大小 DrawMat.SetVector("_Pos", new Vector4(x, y, radius)); //提交 Graphics.Blit(null, TempRT, DrawMat); //進行交換 RenderTexture rt = TempRT; TempRT = CurrentRT; CurrentRT = rt; } private Vector3 lastPos; // Update is called once per frame void Update() { //TODO鼠標左鍵按下時射綫檢測 if (Input.GetMouseButton(0)) { Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition); RaycastHit hit;//射綫碰撞信息 if (Physics.Raycast(ray, out hit)) { if ((hit.point - lastPos).sqrMagnitude > 0.1f) { lastPos = hit.point; //TODO:繪製圖案 DrawAt(hit.textureCoord.x, hit.textureCoord.y, DrawRadius); } } } ////TODO:添加物体交互 //AddMat.SetTexture("_Tex1", InteractiveRT); //AddMat.SetTexture("_Tex2", CurrentRT); //Graphics.Blit(null, TempRT, AddMat); ////把结果交换到CurrentRT //RenderTexture rt0 = TempRT; //TempRT = CurrentRT; //CurrentRT = rt0; //TODO:計算漣漪 RippleMat.SetTexture("_PrevRT", PrevRT); RippleMat.SetTexture("_CurrentRT", CurrentRT); Graphics.Blit(null, TempRT, RippleMat); //TODO 交換到 CurrentRT上 Graphics.Blit(TempRT, PrevRT); //交換 RenderTexture rt = PrevRT; PrevRT = CurrentRT; CurrentRT = rt; } }