博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Cg入门27:Fragment shader – 程序纹理水波仿真
阅读量:2201 次
发布时间:2019-05-03

本文共 4355 字,大约阅读时间需要 14 分钟。

效果:
Quad和Cube 波纹起始点为啥不一样了,返回都是[-0.5,0.5],坐标中心为模型中心。
原因:估计模型网格数据的UV起始点是不一样的
优化方案说明:由1-3逐渐增加,1和2配套使用
优化方案1:开启单独线程,进行uv水波纹理计算
源代码:
Shader "Sbin/WaveAnimShader"{	Properties	{		_MainTex ("Texture", 2D) = "white" {}		_WaveTex ("Texture",2D) = "white"{}	}	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_base v)			{				v2f o;				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);				o.uv = v.texcoord.xy;				return o;			}			fixed4 frag (v2f v) : COLOR			{				float2 uv = tex2D(_WaveTex, v.uv);				uv = uv*2-1;//[-1,1]				uv *=0.25;								v.uv +=uv;				fixed4 col = tex2D(_MainTex, v.uv);				return col;			}			ENDCG		}	}}
using UnityEngine;using System.Collections;using System.Threading;public class WaveAnim : MonoBehaviour{    public int waveWidth = 128;    public int waveHeight = 128;    float[,] waveA;    float[,] waveB;    bool isRun = true;    float sleepTime;    Color[] colorBuffer;    Texture2D tex_uv;    void Start()    {        waveA = new float[waveWidth, waveHeight];        waveB = new float[waveWidth, waveHeight];        tex_uv = new Texture2D(waveWidth, waveHeight);        colorBuffer = new Color[waveWidth * waveHeight];        GetComponent
().material.SetTexture("_WaveTex", tex_uv); Thread th = new Thread(new ThreadStart(ComputeWave)); th.Start(); } void Update() { sleepTime = Time.deltaTime * 1000; tex_uv.SetPixels(colorBuffer); tex_uv.Apply(); if (Input.GetMouseButton(0)) { RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit)) { Vector3 pos = hit.point; //获取点击模型的本地坐标 pos = transform.worldToLocalMatrix.MultiplyPoint(pos); //将本地坐标转成UV坐标 int w = (int)((pos.x + 0.5) * waveWidth); int h = (int)((pos.y + 0.5) * waveHeight); PutPop(w, h); } } //ComputeWave(); } //放置起波点 private void PutPop(int x, int y) { int radius = 20; float dist; for (int i = -radius; i < radius; i++) { for (int j = -radius; j < radius; j++) { //控制在uv纹理范围内 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); } } } } } ///
/// 波纹的UV计算 /// private void ComputeWave() { while (isRun) { 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]; waveB[w, h] = waveB[w, h] > 1 ? 1 : waveB[w, h]; waveB[w, h] = waveB[w, h] < -1 ? -1 : waveB[w, h]; //控制范围[-1,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; float r = offset_v / 2 + 0.5f; float g = offset_u / 2 + 0.5f; //tex_uv.SetPixel(w, h, new Color(r, g, 0)); colorBuffer[w + waveWidth * h] = new Color(r, g, 0); //进行波纹能量衰减 waveB[w, h] -= waveB[w, h] * 0.025f; } } //tex_uv.Apply(); float[,] temp = waveA; waveA = waveB; waveB = temp; Thread.Sleep((int)sleepTime); } } void OnDestory() { isRun = false; }}
优化方案2:关闭垂直同步
打开:Edit->Project Setting->Quality,然后选择V Sysnc Count 为Don't Sync
优化方案3:compute Shader 利用GUP才进行计算,GUP计算特点:并行处理效果高
compute Shader  不了解
你可能感兴趣的文章
Oracle PL/SQL语言初级教程之游标
查看>>
Oracle PL/SQL语言初级教程之操作和控制语言
查看>>
Oracle PL/SQL语言初级教程之过程和函数
查看>>
Oracle PL/SQL语言初级教程之表和视图
查看>>
Oracle PL/SQL语言初级教程之完整性约束
查看>>
PL/SQL学习笔记
查看>>
如何分析SQL语句
查看>>
结构化查询语言(SQL)原理
查看>>
SQL教程之嵌套SELECT语句
查看>>
日本語の記号の読み方
查看>>
计算机英语编程中一些单词
查看>>
JavaScript 经典例子
查看>>
判断数据的JS代码
查看>>
js按键事件说明
查看>>
AJAX 初次体验!推荐刚学看这个满好的!
查看>>
AJAX 设计制作 在公司弄的 非得要做出这个养的 真晕!
查看>>
Linux 查看文件大小
查看>>
Java并发编程:线程池的使用
查看>>
redis单机及其集群的搭建
查看>>
Java多线程学习
查看>>