VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > c#编程 >
  • Unity Shader实现3D翻页效果

本文实例为大家分享了Unity Shader实现3D翻页效果的具体代码,供大家参考,具体内容如下

 

效果图:

原理:Shader顶点动画

在顶点着色器进行对顶点Y值的偏移(使用了Sin函数模拟翻页时产生的弯曲),对顶点X值的偏移实现纸张在翻页时的收缩(一般是不用收缩),最后对顶点进行围绕Z轴旋转实现Plane翻页(Z轴是本例的旋转轴,请根据你具体情况修改,上面的两个偏移同理)。

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

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

Shader "Unlit/PaperTurnMilkShader"

{

 Properties

 {

  //正面图

  _MainTex ("Texture", 2D) = "white" {}

  //背面图

  _SrcTex("SrcTex", 2D) = "white"{}

  //旋转角度

  _Angle("Angle", Range(0,180)) = 0

  //弯曲程度

  _WeightY("Weight Y", Range(0,3)) = 0.2

  //收缩程度(值越大翻页时纸张越往内部靠拢)具体情况可测试

  _WeightX("Weight X", Range(0,1)) = 0

  //波长(值越大翻页时的弯曲次数越多)

  _WaveLength("WaveLength", Range(0,2)) = 0.4

 }

 SubShader

 {

  //关闭批处理(因为修改了顶点位置)

  Tags { "RenderType"="Opaque" "IgnoreProjector" = "True" "Queue" = "Geometry" "DisableBatching" = "True"}

  LOD 100

  //渲染正面

  Pass

  {

   Cull Back

   CGPROGRAM

   #pragma vertex vert

   #pragma fragment frag  

   

   #include "UnityCG.cginc"

 

   struct appdata

   {

    float4 vertex : POSITION;

    float2 uv : TEXCOORD0;

   };

 

   struct v2f

   {

    float2 uv : TEXCOORD0;   

    float4 vertex : SV_POSITION;

   };

 

   sampler2D _MainTex;

   float4 _MainTex_ST;

   float _Angle;

   float _WeightY;

   float _WeightX;

   float _WaveLength;

   

   v2f vert (appdata v)

   {

    v2f o;

    //对顶点进行往X正方向偏移5个单位是为了离开旋转中心点,不然翻页时的旋转点是会在纸张中心进行围绕Z轴旋转(Z轴是纸张垂直线)

    v.vertex += float4(5, 0, 0, 0);

    float s;

    float c;

    //使用sincos获取 sin(弧度), cos(弧度)  ,radians(角度)=弧度 ,_Angle前加负号是控制旋转方向,可根据DX是右手法则顺时针旋转,故应该逆向翻页要取负数

    sincos(radians(-_Angle), s, c);

    //围绕Z轴旋转变换矩阵

    float4x4 rotate = {

     c,s,0,0,

     -s,c,0,0,

     0,0,1,0,

     0,0,0,1

    };

    //weight:_Angle在[0,90]变换区间时,weight会从0变为1;_Angle在[90,180]变换区间时,weight会从1变为0.

    //weight可理解为是刚开始翻页(0°)到翻页到垂直时(90°)时,对其弯曲程度从小变大;(这个是对顶点Y值影响的结果)

    //同理,收缩程度也是一样道理

    float weight = 1 - abs(90 - _Angle) / 90;

    v.vertex.y += sin(v.vertex.x * _WaveLength) * weight * _WeightY;

    v.vertex.x -= v.vertex.x * weight * _WeightX;

    //在进行偏移之后,再对顶点进行围绕Z轴旋转_Angle角度

    v.vertex = mul(rotate, v.vertex);

 

    //之后要偏移回来,因为我们已经做完了上面的旋转操作了

    v.vertex -= float4(5, 0, 0, 0);

    o.vertex = UnityObjectToClipPos(v.vertex);

    o.uv = TRANSFORM_TEX(v.uv, _MainTex);   

    return o;

   }

   

   fixed4 frag (v2f i) : SV_Target

   {   

    fixed4 col = tex2D(_MainTex, i.uv);   

    return col;

   }

   ENDCG

  }

 

  //渲染背面(和上方渲染正面PASS唯一的差别是:片元着色器的采样纹理改为_SrcTex(背面图)

  Pass

  {

   Cull Front

   CGPROGRAM

   #pragma vertex vert

   #pragma fragment frag  

 

   #include "UnityCG.cginc"

 

   struct appdata

   {

    float4 vertex : POSITION;

    float2 uv : TEXCOORD0;

   };

 

   struct v2f

   {

    float2 uv : TEXCOORD0;

    float4 vertex : SV_POSITION;

   };

 

   sampler2D _SrcTex;

   float4 _MainTex_ST;

   float _Angle;

   float _WeightY;

   float _WeightX;

   float _WaveLength;

   v2f vert(appdata v)

   {

    v2f o;

    v.vertex += float4(5, 0, 0, 0);

    float s;

    float c;

    //使用sincos获取 sin(弧度), cos(弧度)  ,radians(角度)=弧度

    sincos(radians(-_Angle), s, c);

    //围绕Z轴旋转变换矩阵

    float4x4 rotate = {

     c,s,0,0,

     -s,c,0,0,

     0,0,1,0,

     0,0,0,1

    };

    float weight = 1 - abs(90 - _Angle) / 90;

    v.vertex.y += sin(v.vertex.x * _WaveLength) * weight * _WeightY;

    v.vertex.x -= v.vertex.x * weight * _WeightX;

    v.vertex = mul(rotate, v.vertex);

 

    v.vertex -= float4(5, 0, 0, 0);

 

    o.vertex = UnityObjectToClipPos(v.vertex);

    o.uv = TRANSFORM_TEX(v.uv, _MainTex);

    return o;

   }

 

   fixed4 frag(v2f i) : SV_Target

   {

    fixed4 col = tex2D(_SrcTex, i.uv);

    return col;

   }

   ENDCG

  }

 }

}

以上就是本文的全部内容



原文:
https://www.jb51.net/article/218224.htm

相关教程