UnityShader学习10 纹理采样相关
//图像波浪效果
Shader "ShaderLearn/my_test_05" { Properties{ _MainTex("MainTex", 2D) = ""{} _F("F",range(1, 30)) = 10 _A ("A", range(0, 0.1)) = 0.01 _R ("R", range(0, 1)) = 0 } SubShader{ pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; float4 _MainTex_ST; float _F; float _A;//幅度 float _R;//影响半径 struct v2f{ float4 pos : POSITION; float2 uv :TEXCOORD0; }; v2f vert(appdata_full v){ v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord.xy * _MainTex_ST.xy/*缩放*/ + _MainTex_ST.zw/*偏移*/;//给主纹理的uv坐标赋值 return o; } fixed4 frag(v2f IN) : COLOR{ /* y=Asin(ωx+φ)+k φ表示函数的所有点平行移动|φ|个单位 A表示纵坐标的伸缩 ω表示横坐标的伸缩 */ float2 uv = IN.uv; uv += 0.005 * sin(IN.uv *3.14 * _F + _Time.y);//普通波浪 //圆形波浪,以(0.5,0.5)为中心开始向四周扩散 float dis = distance(uv, float2(0.5,0.5)); _A *= saturate(1 - dis / _R); float scale = _A * sin(-dis * 3.14 * _F + _Time.y); uv = uv + uv * scale; ////根据z值图像模糊 //float2 dsdx = ddx(IN.z) * 10; //float2 dsdy = ddy(IN.z) * 10; //float4 color = tex2D(_MainTex, uv, dsdx, dsdy); fixed4 color = tex2D(_MainTex, uv); return color; } ENDCG } } FallBack "Diffuse" }
2.鼠标点击形成水波
cs脚本:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class WaveTexture : MonoBehaviour { public int waveWidth; public int waveHeight; public int radius = 8; public float coutDownSpeed = 0.03f; float[,] waveA;// float[,] waveB;// Texture2D tex_uv; // Use this for initialization void Start() { waveA = new float[waveWidth, waveHeight]; waveB = new float[waveWidth, waveHeight]; tex_uv = new Texture2D(waveWidth, waveHeight); GetComponent<MeshRenderer>().material.SetTexture("_WaveTex", tex_uv); } // Update is called once per frame void Update() { if (Input.GetMouseButtonDown(0)) { RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit)) { Vector3 pos = hit.point; pos = transform.worldToLocalMatrix.MultiplyVector(pos); Debug.Log(pos); //因为立方体的uv范围是-0.5到0.5,所以这里要映射到0到1。 int w = (int)((-pos.x + 0.5f) * waveWidth); int h = (int)((-pos.y + 0.5f) * waveHeight); PutDrop(w, h); } } ComputeWave(); } private void PutDrop(int x, int y) { float dist; for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { if (((x + i > 0) && (x + i < waveWidth - 1)) && ((y + j >= 0) && (y + j < waveHeight - 1))) { dist = Mathf.Sqrt(i * i + j * j);//距离 if (dist < radius) { waveA[x + i, y + j] = Mathf.Cos(dist * Mathf.PI / radius); } } } } } //以某个点测试用 void Putpop() { waveA[waveWidth / 2, waveHeight / 2] = 1; waveA[waveWidth / 2 - 1, waveHeight / 2] = 1; waveA[waveWidth / 2 + 1, waveHeight / 2] = 1; waveA[waveWidth / 2, waveHeight / 2 - 1] = 1; waveA[waveWidth / 2, waveHeight / 2 + 1] = 1; waveA[waveWidth / 2 - 1, waveHeight / 2 + 1] = 1; waveA[waveWidth / 2 - 1, waveHeight / 2 - 1] = 1; waveA[waveWidth / 2 + 1, waveHeight / 2 + 1] = 1; waveA[waveWidth / 2 + 1, waveHeight / 2 - 1] = 1; } void ComputeWave() { for (int w = 1; w < waveWidth - 1; w++) { for (int h = 1; h < waveHeight - 1; h++) { waveB[w, h] = (waveA[w - 1, h] + waveA[w + 1, h] + waveA[w, h - 1] + waveA[w, h + 1] + waveA[w - 1, h - 1] + waveA[w + 1, h - 1] + waveA[w - 1, h + 1] + waveA[w + 1, h + 1]) / 4 - waveB[w, h]; //限定在-1到1范围 float value = waveB[w, h]; if (value > 1) { waveB[w, h] = 1; } if (value < -1) { waveB[w, h] = -1; } float offset_u = (waveB[w - 1, h] - waveB[w + 1, h]) / 2; float offset_v = (waveB[w, h - 1] - waveB[w, h + 1]) / 2; //颜色只有0到1,所以要映射到0到1 float r = offset_u / 2 + 0.5f; float g = offset_v / 2 + 0.5f; tex_uv.SetPixel(w, h, new Color(r, g, 0)); waveB[w, h] -= waveB[w, h] * coutDownSpeed;//衰减,每次减一个很小的数,一直到很接近0 } } tex_uv.Apply(); float[,] temp = waveA; waveA = waveB; waveB = temp; } }
shader脚本:
Shader "ShaderLearn/my_test_06" { Properties{ _MainTex("MainTex", 2D) = ""{} } SubShader{ pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; sampler2D _WaveTex; struct v2f{ float4 pos : POSITION; float2 uv :TEXCOORD0; }; v2f vert(appdata_full v){ v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord.xy; return o; } fixed4 frag(v2f IN) : COLOR{ float2 uv = tex2D(_WaveTex, IN.uv).xy;//对应脚本的rg分量 uv = uv * 2 - 1;//将0到1 还原到1到 -1; uv *= 0.05; IN.uv += uv; fixed4 color = tex2D(_MainTex, IN.uv); return color; } ENDCG } } FallBack "Diffuse" }
浙公网安备 33010602011771号