-
Notifications
You must be signed in to change notification settings - Fork 4
/
Cubism.shader
151 lines (113 loc) · 4.31 KB
/
Cubism.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
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
Shader "Unlit/Cubism"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_VoronoiTiling ("Voronoi Tiling", Float) = 1
_SeedMaxOffset ("Voronoi max Offset", Range(0., 2.)) = 1.
_Seed ("Starting Seed", Int ) = 0
_RotationStren ("Cubism Rotation Strenght", Float ) = 1
_DispacementStren("Cubism Displacement Strenght", Float) = 1
}
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 vertex : SV_POSITION;
float3 color : TEXCOORD1;
float4 screenpos : TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _VoronoiTiling;
float _SeedMaxOffset;
float _RotationStren;
int _Seed;
float _DispacementStren;
inline float rand(float seed) {
return frac(sin((seed+ _Seed )*51.24) * 417.26);
}
inline float3 sgmentIDtoColor(float3 segmentID) {
return float3(rand(dot(segmentID, float3(12.26, 712.1, 7.215))),
rand(dot(segmentID, float3(362.26, 81.16, 2.2))),
rand(dot(segmentID, float3(32.26, 8.621, 521.2))));
}
inline float4x4 AdjustViewMatrixToCubism(float4x4 ViewMatrix, float3 segmentSeed) {
float3 camPosition = ViewMatrix._m03_m13_m23;
float3 randSeed = sgmentIDtoColor(segmentSeed) *_DispacementStren;
// Project the center of the closet seed on the forward of the camera and calculate its postion
// The rotationStrengh moves this point along the foward of the camera back and foward as a
// Balencing parameter
float3 segmentOnZ = max(4.,abs(dot(ViewMatrix._m02_m12_m22, segmentSeed - camPosition )))
* ViewMatrix._m02_m12_m22/ _RotationStren + camPosition;
camPosition = camPosition + randSeed;
// Point the camera so that it is facing this point which was
// Projected above.
float3 foward = normalize(segmentOnZ - camPosition);
float3 right = -cross(ViewMatrix._m01_m11_m21, foward );
float3 up = -cross(foward, right);
float4x4 toreturn = { right.x, up.x, foward.x, camPosition.x,
right.y, up.y, foward.y, camPosition.y,
right.z, up.z, foward.z, camPosition.z,
0., 0., 0., 1.};
return toreturn;
}
v2f vert (appdata v)
{
v2f o;
float4 vPosT = v.vertex;
vPosT = mul(unity_ObjectToWorld, vPosT);
float3 vPosF = frac(vPosT*_VoronoiTiling);
float3 vPosI = floor(vPosT*_VoronoiTiling);
float closestDis = 10000.;
float3 closestSeed = float3(0., 0., 0.);
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
for (int z = -1; z <= 1; z++) {
float3 neighbourPos = float3(float(x), float(y), float(z));
float3 randSeed = sgmentIDtoColor(vPosI + neighbourPos) * _SeedMaxOffset;
float3 vToNeighbour = randSeed + neighbourPos - vPosF;
float vToNeighbourD = length(vToNeighbour);
if (vToNeighbourD <= closestDis) {
closestDis = vToNeighbourD;
closestSeed = neighbourPos + vPosI + randSeed;
}
}
}
}
vPosT = mul(AdjustViewMatrixToCubism(UNITY_MATRIX_V, closestSeed), vPosT);
//vPosT = mul(UNITY_MATRIX_V, vPosT);
//vPosT.xyz += sgmentIDtoColor(closestSeed);
vPosT = mul(UNITY_MATRIX_P, vPosT);
o.screenpos = ComputeScreenPos(vPosT);
o.vertex = vPosT;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.color = sgmentIDtoColor(closestSeed);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
float2 screenPos = i.screenpos.xy / i.screenpos.w;
//if (screenPos.x < 0.5) col.xyz = i.color.xyz;
return col;
}
ENDCG
}
}
}