锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

交互涟漪(水波)

时间:2022-12-31 14:00:00 紫外线油浸式uv电容器

原地址:【Unity可实时交互的涟漪效果_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

简单实现思路

点击物体的UV,传入shader,获得一张,根据点生生成的小圆球

传播图片shader,神奇的公式

 float3 offset = float3(_SourceTex_TexelSize.xy,0);  float col12 = tex2D(_SourceTex,i.uv   offset.zy ).x;  float col10 = tex2D(_SourceTex,i.uv - offset.zy ).x;  float col01 = tex2D(_SourceTex,i.uv - offset.xz ).x;  float col21 = tex2D(_SourceTex,i.uv   offset.xz ).x;  float col11 = tex2D(_PrevTex,i.uv).x;  float finel = (col10   col12   col01   col21)*0.5 - col11;  finel = finel*0.99;  return float4(finel,0,0,1);

将生成的高度场地地图传输到

法线贴图按高度生成

C#代码

using System.Collections; using System.Collections.Generic; using UnityEngine;  public class MeshUVRipple : MonoBehaviour {     public Camera camera;     public float radius;     private Shader _generateRippleHight;     private RenderTexture _tempTexture;     private RenderTexture _currentTexture;     private RenderTexture _prevTexture;     private Material _hightRipple;     private Material _point_material;     private Material material;     private void Awake()     {         if (null == camera)         {             camera = Camera.main;         }         _currentTexture = CreatRT();         _tempTexture = CreatRT();         _prevTexture = CreatRT();          _point_material = new Material(Shader.Find("Custom/GenerateRippleHight"));         _hightRipple = new Material(Shader.Find("Custom/HightRipple"));          material = GetComponent().material;     }     private RenderTexture CreatRT()     {         var rt = new RenderTexture(1024, 1024, 0, RenderTextureFormat.RFloat);         rt.Create();         return rt;     }     private Vector2 lastTexCoord;     private void Update()     {         if (Input.GetMouseButton(0))         {             RaycastHit hit;             if (Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), out hit))             {                 if (Vector2.Distance(hit.textureCoord, lastTexCoord) >0.01f)                 {                     lastTexCoord = hit.textureCoord;                     DrawPoint(hit);                 }             }         }         DrawRipple();         material.SetTexture("_RippleHightTex", _currentTexture);     }     private void DrawPoint(RaycastHit hit)     {           _point_material.SetFloat("_Radius", radius);         _point_material.SetVector("_HitPos", hit.textureCoord);         _point_material.SetTexture("_SourceTex", _currentTexture);         Graphics.Blit(null, _tempTexture, _point_material);          RenderTexture rt = _currentTexture;         _currentTexture = _tempTexture;         _tempTexture = rt;     }      private void DrawRipple()     {          _hightRipple.SetTexture("_SourceTex", _currentTexture);         _hightRipple.SetTexture("_PrevTex", _prevTexture);         Graphics.Blit(null, _tempTexture, _hightRipple);         Graphics.Blit(_tempTexture, _prevTexture);          RenderTexture rt = _prevTexture;         _prevTexture = _currentTexture;         _currentTexture = rt;     }    }  

初始涟漪生成shader

Shader "Custom/GenerateRippleHight" {     Properties     {         _MainTex ("Texture", 2D) = "white" {}     }     SubShader     {         Tags { "RenderType"="Opaque" }         LOD 100          Pass         {             CGPROGRAM             #pragma vertex vert             #pragma fragment frag              #include "UnityCG.cginc"              struct appdata             {                 float4 vertex : POSITION;                 float2 uv : TEXCOORD0;             };              struct v2f             {                 float2 uv : TEXCOORD0;                 float4 pos : SV_POSITION;             };              sampler2D _SourceTex;             float4 _SourceTex_ST;             float2 _HitPos;             floa _Radius;

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _SourceTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_SourceTex, i.uv);
                float factor =max(0,_Radius-length(i.uv-_HitPos)/_Radius);
                col.r += min( factor,1);
                return col;
            }
            ENDCG
        }
    }
}

 涟漪扩散shader

Shader "Custom/HightRipple"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
            };


            sampler2D _SourceTex;
            sampler2D _PrevTex;
            float4 _SourceTex_ST;
            float4 _SourceTex_TexelSize;

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float3 offset = float3(_SourceTex_TexelSize.xy,0);
                float col12 = tex2D(_SourceTex,i.uv + offset.zy ).x;
                float col10 = tex2D(_SourceTex,i.uv - offset.zy ).x;
                float col01 = tex2D(_SourceTex,i.uv - offset.xz ).x;
                float col21 = tex2D(_SourceTex,i.uv + offset.xz ).x;
                float col11 = tex2D(_PrevTex,i.uv).x;
                float finel = (col10 + col12 + col01 + col21)*0.5 - col11;
                finel = finel*0.99;
                return float4(finel,0,0,1);
            }
            ENDCG
        }
    }
}

最终应用shader,简单的用了Blinn-Phong光照模型

Shader "Unlit/MeshRipple"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Specular ("_Specular", Color) = (1,1,1,1)
        _Diffuse ("_Diffuse", Color) = (1,1,1,1)
        
        _heigth2normalFactor ("_heigth2normalFactor", Range(0.01,100)) = 0.1
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque"  "Queue" = "Transparent" }
        LOD 100
         Blend SrcAlpha OneMinusSrcAlpha
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                float4 worldPos : TEXCOORD1;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _RippleHightTex;
            float4 _RippleHightTex_TexelSize;
            float4 _Specular;
            float4 _Diffuse;
            float _heigth2normalFactor;

            float3 HigthToNormal(sampler2D heigthTex ,float2 heigth_TexelSize , float2 uv)
            {
                float3 offset = float3(heigth_TexelSize.xy,0);
                float factor = _heigth2normalFactor;
                float3 S = float3(1,0, (tex2D(heigthTex,uv + offset.xz).x - tex2D(heigthTex,uv - offset.xz).x)*factor);
                float3 T = float3(0,1, (tex2D(heigthTex,uv + offset.zy).x - tex2D(heigthTex,uv - offset.zy).x)*factor);
                float3 d =  cross(S,T)+float3(0.5,0.5,1);
                return d;
            }

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld,v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            float4 frag (v2f i) : SV_Target
            {
                float4 col = tex2D(_MainTex, i.uv)*_Diffuse;
 
                float3 normal = HigthToNormal(_RippleHightTex,_RippleHightTex_TexelSize.xy, i.uv);
                normal = normalize(normal);

                float3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
                float3 view = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
				float3 halfDir = normalize(worldLight + view);
				float3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(normal, halfDir)), 4);


                col.rgb += specular;
                return col;
            }
            ENDCG
        }
    }
}

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章