服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - Unity3D Shader实现贴图切换效果

Unity3D Shader实现贴图切换效果

2022-07-08 09:31星空不语 C#

这篇文章主要为大家详细介绍了Unity3D Shader实现贴图切换效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了shader实现基于世界坐标的贴图置换效果。

效果如下:

Unity3D Shader实现贴图切换效果

设置面板如下:

Unity3D Shader实现贴图切换效果

可在面板上设置切换方向,与切换对象,及其切换速度。

shader实现如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
Shader "XM/Effect/SwapTexture" {
 Properties {
 _Color ("Color", Color) = (1,1,1,1)
 _MainTex ("Albedo (RGB)", 2D) = "white" {}
 _TargetTex ("Target Tex", 2D) = "white" {}//目标贴图
 [KeywordEnum(Up, Down, Left, Right, Forward, Back)] _mode ("Mode", Int) = 0//切换方向
 _SwapBlend ("Blend", Range(0,1)) = 0//0-1混合值
 _SwapMin("Min Value", Float) = 0//最小世界坐标
 _SwapMax("Max Value", Float) = 0//最大世界坐标
 _Glossiness ("Smoothness", Range(0,1)) = 0.5
 _Metallic ("Metallic", Range(0,1)) = 0.0
 }
 SubShader {
 Tags { "RenderType"="Opaque" }
 LOD 200
 
 CGPROGRAM
 // Physically based Standard lighting model, and enable shadows on all light types
 #pragma surface surf Standard fullforwardshadows vertex:vert
 
 // Use shader model 3.0 target, to get nicer looking lighting
 #pragma target 3.0
 
 sampler2D _MainTex;
 sampler2D _TargetTex;
 
 struct Input {
  float2 uv_MainTex;
  float3 worldPos;
 };
 
 half _mode;
 half _SwapBlend;
 float _SwapMin;
 float _SwapMax;
 half _Glossiness;
 half _Metallic;
 fixed4 _Color;
 
 void vert (inout appdata_full v, out Input o) {
  UNITY_INITIALIZE_OUTPUT(Input,o);
 }
 
 void surf (Input IN, inout SurfaceOutputStandard o) {
  half useTarget = 0;
  float targetValue = 0;
  switch(_mode)//模式选择
  {
  case 0://up
   targetValue = (_SwapMax - _SwapMin) * _SwapBlend + _SwapMin;
   useTarget = IN.worldPos.y > targetValue?0:1;
   break;
  case 1://down
   targetValue = (_SwapMax - _SwapMin) * (1 - _SwapBlend) + _SwapMin;
   useTarget = IN.worldPos.y < targetValue?0:1;
   break;
  case 2://left
   targetValue = (_SwapMax - _SwapMin) * (1 - _SwapBlend) + _SwapMin;
   useTarget = IN.worldPos.x < targetValue?0:1;
   break;
  case 3://right
   targetValue = (_SwapMax - _SwapMin) * _SwapBlend + _SwapMin;
   useTarget = IN.worldPos.x > targetValue?0:1;
   break;
  case 4://forward
   targetValue = (_SwapMax - _SwapMin) * _SwapBlend + _SwapMin;
   useTarget = IN.worldPos.z > targetValue?0:1;
   break;
  case 5://back
   targetValue = (_SwapMax - _SwapMin) * (1 - _SwapBlend) + _SwapMin;
   useTarget = IN.worldPos.z < targetValue?0:1;
   break;
  }
 
  // Albedo comes from a texture tinted by color
  fixed4 c;
  if(useTarget == 1)
  {
  c = tex2D (_TargetTex, IN.uv_MainTex);
  }
  else
  {
  c = tex2D (_MainTex, IN.uv_MainTex);
  }
 
 
  c *= _Color;
  o.Albedo = c.rgb;
  // Metallic and smoothness come from slider variables
  o.Metallic = _Metallic;
  o.Smoothness = _Glossiness;
  o.Alpha = c.a;
 }
 ENDCG
 }
 FallBack "Diffuse"
}

配合使用的脚本如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.Collections;
using UnityEngine;
 
namespace XM.Effect
{
 public class SwapTexture : MonoBehaviour
 {
  public enum SwapDirection
  {
   Up,
   Down,
   Left,
   Right,
   Forward,
   Back
  }
 
  public Shader _shader;//"XM/Effect/SwapTexture” shader
  public SwapDirection _swapDir;//切换方向
  public Renderer _target;//目标对象
  [Range(0, 1)]
  public float _speed;//速度
 
  private Material _matOld;
  private Material _matNew;
 
  public void Swap(Texture tex, Action<bool> onComplete)
  {
   if (_matOld != null)
   {
    StopAllCoroutines();
    if (null != onComplete)
    {
     onComplete(false);
    }
 
    _target.material = _matOld;
   }
 
   _matOld = _target.material;
 
   _matNew = new Material(_shader);
   _matNew.SetTexture("_MainTex", _target.material.GetTexture("_MainTex"));
   _matNew.SetTexture("_TargetTex", tex);
   _matNew.SetInt("_mode", (int)_swapDir);
   _matNew.SetFloat("_SwapBlend", 0);
 
   StartCoroutine("_StartChange", onComplete);
  }
 
  private IEnumerator _StartChange(Action<bool> onComplete)
  {
   float deltaVal = 0;
 
   _target.material = _matNew;
 
   Vector3 vtMin;
   Vector3 vtMax;
   float minVal = 0;
   float maxVal = 0;
 
   while (deltaVal != 1)
   {
    vtMin = _target.bounds.min;
    vtMax = _target.bounds.max;
 
    switch (_swapDir)
    {
     case SwapDirection.Up:
     case SwapDirection.Down:
      minVal = vtMin.y;
      maxVal = vtMax.y;
      break;
     case SwapDirection.Left:
     case SwapDirection.Right:
      minVal = vtMin.x;
      maxVal = vtMax.x;
      break;
     case SwapDirection.Forward:
     case SwapDirection.Back:
      minVal = vtMin.z;
      maxVal = vtMax.z;
      break;
    }
 
    minVal -= 0.01f;
    maxVal += 0.01f;
 
    _matNew.SetFloat("_SwapMin", minVal);
    _matNew.SetFloat("_SwapMax", maxVal);
 
    deltaVal = Mathf.Clamp01(deltaVal + _speed * Time.deltaTime);
    _matNew.SetFloat("_SwapBlend", deltaVal);
    yield return null;
   }
 
   _matOld.SetTexture("_MainTex", _matNew.GetTexture("_TargetTex"));
   _target.material = _matOld;
 
   _matNew = null;
   _matOld = null;
 
   if (null != onComplete)
   {
    onComplete(true);
   }
  }
 
  public void OnDrawGizmos()
  {
   if (_target != null)
   {
    Gizmos.DrawWireCube(_target.bounds.center, _target.bounds.size);
    Gizmos.DrawWireSphere(_target.bounds.min, 0.1f);
    Gizmos.DrawWireSphere(_target.bounds.max, 0.1f);
   }
  }
 
  //test
  public Texture testTex;
  private void OnGUI()
  {
   if (GUILayout.Button("SwapTexture"))
   {
    Swap(testTex, (t) =>
    {
     Debug.Log("Swap>" + t);
    });
   }
  }
  //
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/u012741077/article/details/53948802

延伸 · 阅读

精彩推荐
  • C#C#实现的简单链表类实例

    C#实现的简单链表类实例

    这篇文章主要介绍了C#实现的简单链表类,涉及C#针对链表的定义、实现及链表节点的增加、删除与修改技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    北风其凉6852021-10-19
  • C#C#中WPF ListView绑定数据的实例详解

    C#中WPF ListView绑定数据的实例详解

    这篇文章主要介绍了C#中WPF ListView绑定数据的实例详解的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下...

    晨曦8885862022-01-24
  • C#C#如何添加PPT背景

    C#如何添加PPT背景

    这篇文章主要为大家详细介绍了C#如何添加PPT背景,添加纯色背景、渐变色背景、图片背景等,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    E-iceblue12072022-02-27
  • C#c#实现从字符串数组中把数字的元素找出来

    c#实现从字符串数组中把数字的元素找出来

    下面小编就为大家分享一篇c#实现从字符串数组中把数字的元素找出来的方法,希望对大家有所帮助。一起跟随小编过来看看吧...

    杨明波(Leo Yang)6092022-02-15
  • C#C#双向链表LinkedList排序实现方法

    C#双向链表LinkedList排序实现方法

    这篇文章主要介绍了C#双向链表LinkedList排序实现方法,涉及C#双向链表的定义与排序技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    北风其凉12152021-10-11
  • C#C#获取路由器外网IP,MAC地址的实现代码

    C#获取路由器外网IP,MAC地址的实现代码

    这篇文章主要介绍了C#获取路由器外网IP,MAC地址的实现代码,需要的朋友可以参考下...

    C#教程网10542021-12-10
  • C#C#发送HttpPost请求来调用WebService的方法

    C#发送HttpPost请求来调用WebService的方法

    在C#中发送HttpPost请求来调用WebService中的MyAction方法,代码如下:需要的朋友可以参考一下...

    C#教程网10012020-12-18
  • C#MVC设定默认路由为指定的Area下的某个action

    MVC设定默认路由为指定的Area下的某个action

    今天小编就为大家分享一篇关于MVC设定默认路由为指定的Area下的某个action,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一...

    chenqiangdage7082022-03-08