Skip to content
This repository was archived by the owner on Apr 29, 2021. It is now read-only.

Commit bc62d13

Browse files
committed
compute buffer setup - shadow shader
1 parent cdfbbec commit bc62d13

File tree

8 files changed

+244
-6
lines changed

8 files changed

+244
-6
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
Shader "UIWidgets/ShadowBox_cb"
2+
{
3+
//originally from http://madebyevan.com/shaders/fast-rounded-rectangle-shadows/
4+
Properties
5+
{
6+
_SrcBlend("_SrcBlend", Int) = 1 // One
7+
_DstBlend("_DstBlend", Int) = 10 // OneMinusSrcAlpha
8+
_StencilComp("_StencilComp", Float) = 8 // - Equal, 8 - Always
9+
}
10+
SubShader
11+
{
12+
ZTest Always
13+
ZWrite Off
14+
Blend [_SrcBlend] [_DstBlend]
15+
16+
Stencil {
17+
Ref 128
18+
Comp [_StencilComp]
19+
}
20+
21+
Pass {
22+
CGPROGRAM
23+
24+
float4 _sb_box;
25+
float4 _viewport;
26+
float _sb_sigma;
27+
float4 _sb_color;
28+
float _mat[9];
29+
30+
struct vdata
31+
{
32+
float2 vertex;
33+
float2 uv;
34+
};
35+
36+
StructuredBuffer<vdata> databuffer;
37+
StructuredBuffer<int> indexbuffer;
38+
int _startVertex;
39+
40+
struct v2f
41+
{
42+
float4 vertex : SV_POSITION;
43+
float2 coord : TEXCOORD0;
44+
};
45+
46+
float4 erf(float4 x)
47+
{
48+
float4 s = sign(x);
49+
float4 a = abs(x);
50+
x = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a;
51+
x = x * x;
52+
return s - s / (x * x);
53+
return s;
54+
}
55+
56+
float boxShadow(float2 lower, float2 upper, float2 pnt, float sigma)
57+
{
58+
float4 query = float4(pnt - lower, pnt - upper);
59+
float4 integral = 0.5 + 0.5 * erf(query * (sqrt(0.5) / sigma));
60+
return (integral.z - integral.x) * (integral.w - integral.y);
61+
}
62+
63+
v2f vert(uint vertex_id: SV_VertexID, uint instance_id: SV_InstanceID){
64+
v2f o;
65+
vdata v = databuffer[indexbuffer[_startVertex + vertex_id]];
66+
float padding = 3.0 * _sb_sigma;
67+
o.coord = lerp(_sb_box.xy - padding, _sb_box.zw + padding, v.vertex.xy);
68+
float3x3 mat = float3x3(_mat[0], _mat[1], _mat[2], _mat[3], _mat[4], _mat[5], 0, 0, 1);
69+
float2 p = mul(mat, float3(o.coord.xy, 1.0)).xy - _viewport.xy;
70+
71+
#if UNITY_UV_STARTS_AT_TOP
72+
o.vertex = float4(2.0 * p.x / _viewport.z - 1.0, 2.0 * p.y / _viewport.w - 1.0, 0, 1);
73+
#else
74+
o.vertex = float4(2.0 * p.x / _viewport.z - 1.0, 1.0 - 2.0 * p.y / _viewport.w, 0, 1);
75+
#endif
76+
return o;
77+
}
78+
79+
float4 frag(v2f i) : SV_TARGET {
80+
float4 fragColor = _sb_color;
81+
fragColor.a = fragColor.a * boxShadow(_sb_box.xy, _sb_box.zw, i.coord, _sb_sigma);
82+
return fragColor;
83+
}
84+
85+
#pragma vertex vert
86+
#pragma fragment frag
87+
88+
ENDCG
89+
}
90+
}
91+
}

Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowBox_cb.shader.meta

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
Shader "UIWidgets/ShadowRBox_cb"
2+
{
3+
//originally from http://madebyevan.com/shaders/fast-rounded-rectangle-shadows/
4+
Properties
5+
{
6+
_SrcBlend("_SrcBlend", Int) = 1 // One
7+
_DstBlend("_DstBlend", Int) = 10 // OneMinusSrcAlpha
8+
_StencilComp("_StencilComp", Float) = 8 // - Equal, 8 - Always
9+
}
10+
SubShader
11+
{
12+
ZTest Always
13+
ZWrite Off
14+
Blend [_SrcBlend] [_DstBlend]
15+
16+
Stencil {
17+
Ref 128
18+
Comp [_StencilComp]
19+
}
20+
21+
Pass {
22+
CGPROGRAM
23+
24+
float4 _sb_box;
25+
float4 _viewport;
26+
float _sb_sigma;
27+
float4 _sb_color;
28+
float _sb_corner;
29+
float _mat[9];
30+
31+
struct vdata
32+
{
33+
float2 vertex;
34+
float2 uv;
35+
};
36+
37+
StructuredBuffer<vdata> databuffer;
38+
StructuredBuffer<int> indexbuffer;
39+
int _startVertex;
40+
41+
struct v2f
42+
{
43+
float4 vertex : SV_POSITION;
44+
float2 coord : TEXCOORD0;
45+
};
46+
47+
float gaussian(float x, float sigma)
48+
{
49+
float pi = 3.141592653589793;
50+
return exp(-(x*x) / (2.0 * sigma * sigma)) / (sqrt(2.0 * pi) * sigma);
51+
}
52+
53+
float2 erf(float2 x)
54+
{
55+
float2 s = sign(x);
56+
float2 a = abs(x);
57+
x = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a;
58+
x = x * x;
59+
return s - s / (x * x);
60+
return s;
61+
}
62+
63+
float roundedBoxShadowX(float x, float y, float sigma, float corner, float2 halfSize)
64+
{
65+
float delta = min(halfSize.y - corner - abs(y), 0.0);
66+
float curved = halfSize.x - corner + sqrt(max(0.0, corner * corner - delta * delta));
67+
float2 integral = 0.5 + 0.5 * erf((x + float2(-curved, curved)) * (sqrt(0.5)/sigma));
68+
return integral.y - integral.x;
69+
}
70+
71+
float roundedBoxShadow(float2 lower, float2 upper, float2 pnt, float sigma, float corner)
72+
{
73+
float2 center = (lower + upper) * 0.5;
74+
float2 halfSize = (upper - lower) * 0.5;
75+
pnt -= center;
76+
77+
float low = pnt.y - halfSize.y;
78+
float high = pnt.y + halfSize.y;
79+
float start = clamp(-3.0 * sigma, low, high);
80+
float end = clamp(3.0 * sigma, low, high);
81+
82+
float step = (end - start) / 4.0;
83+
float y = start + step * 0.5;
84+
float value = 0.0;
85+
86+
for(int i=0; i<4;i++)
87+
{
88+
value += roundedBoxShadowX(pnt.x, pnt.y - y, sigma, corner, halfSize) * gaussian(y, sigma) * step;
89+
y += step;
90+
}
91+
92+
return value;
93+
}
94+
95+
v2f vert(uint vertex_id: SV_VertexID, uint instance_id: SV_InstanceID){
96+
v2f o;
97+
vdata v = databuffer[indexbuffer[_startVertex + vertex_id]];
98+
float padding = 3.0 * _sb_sigma;
99+
o.coord = lerp(_sb_box.xy - padding, _sb_box.zw + padding, v.vertex.xy);
100+
float3x3 mat = float3x3(_mat[0], _mat[1], _mat[2], _mat[3], _mat[4], _mat[5], 0, 0, 1);
101+
float2 p = mul(mat, float3(o.coord.xy, 1.0)).xy - _viewport.xy;
102+
103+
#if UNITY_UV_STARTS_AT_TOP
104+
o.vertex = float4(2.0 * p.x / _viewport.z - 1.0, 2.0 * p.y / _viewport.w - 1.0, 0, 1);
105+
#else
106+
o.vertex = float4(2.0 * p.x / _viewport.z - 1.0, 1.0 - 2.0 * p.y / _viewport.w, 0, 1);
107+
#endif
108+
return o;
109+
}
110+
111+
float4 frag(v2f i) : SV_TARGET {
112+
float4 fragColor = _sb_color;
113+
fragColor.a = fragColor.a * roundedBoxShadow(_sb_box.xy, _sb_box.zw, i.coord, _sb_sigma, _sb_corner);
114+
return fragColor;
115+
}
116+
117+
#pragma vertex vert
118+
#pragma fragment frag
119+
120+
ENDCG
121+
}
122+
}
123+
}

Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowRBox_cb.shader.meta

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_computebuffer_utils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct uiVertex
2323
bool supportComputeBuffer;
2424

2525
void setupComputeBuffer() {
26-
this.supportComputeBuffer = this._isMainCanvas && CanvasShader.supportComputeBuffer && false;
26+
this.supportComputeBuffer = this._isMainCanvas && CanvasShader.supportComputeBuffer;
2727
}
2828

2929
void initComputeBuffer() {

Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_impl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,7 @@ void _drawLayer(RenderLayer layer, CommandBuffer cmdBuf) {
11661166
}
11671167

11681168
D.assert(mesh.vertices.Count > 0);
1169-
if (this.supportComputeBuffer && CanvasShader.rshadowShader != cmd.material.shader && CanvasShader.rrshadowShader != cmd.material.shader) {
1169+
if (this.supportComputeBuffer) {
11701170
this.addMeshToComputeBuffer(mesh.vertices?.data, mesh.uv?.data, mesh.triangles?.data);
11711171
cmd.properties.SetBuffer(CmdDraw.vertexBufferId, this.computeBuffer);
11721172
cmd.properties.SetBuffer(CmdDraw.indexBufferId, this.indexBuffer);

Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ static class CanvasShader {
165165
static readonly Material _stencilMat_cb;
166166
static readonly Material _filterMat_cb;
167167
static readonly MaterialByBlendModeStencilComp _strokeAlphaMat_cb;
168+
static readonly Material _shadowBox_cb;
169+
static readonly Material _shadowRBox_cb;
168170

169171
static Shader GetShader(string shaderName) {
170172
var shader = Shader.Find(shaderName);
@@ -201,6 +203,8 @@ static CanvasShader() {
201203
var texShaderCompute = GetShader("UIWidgets/canvas_tex_cb");
202204
var stencilShaderCompute = GetShader("UIWidgets/canvas_stencil_cb");
203205
var filterShaderCompute = GetShader("UIWidgets/canvas_filter_cb");
206+
var shadowBoxShaderCompute = GetShader("UIWidgets/ShadowBox_cb");
207+
var shadowRBoxShaderCompute = GetShader("UIWidgets/ShadowRBox_cb");
204208
var strokeAlphaShaderCompute = GetShader("UIWidgets/canvas_strokeAlpha_cb");
205209

206210
rshadowShader = shadowBoxShader;
@@ -227,6 +231,8 @@ static CanvasShader() {
227231
_texMat_cb = new MaterialByBlendModeStencilComp(texShaderCompute);
228232
_stencilMat_cb = new Material(stencilShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
229233
_filterMat_cb = new Material(filterShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
234+
_shadowBox_cb = new Material(shadowBoxShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
235+
_shadowRBox_cb = new Material(shadowRBoxShaderCompute) {hideFlags = HideFlags.HideAndDontSave};
230236

231237
supportComputeBuffer = convexFillShaderCompute.isSupported;
232238
}
@@ -572,11 +578,11 @@ public static PictureFlusher.CmdDraw maskFilter(PictureFlusher.RenderLayer layer
572578
}
573579

574580
public static PictureFlusher.CmdDraw fastShadow(PictureFlusher.RenderLayer layer, uiMeshMesh mesh, float sigma,
575-
bool isRect, bool isCircle, float corner, Vector4 bound, uiColor color) {
581+
bool isRect, bool isCircle, float corner, Vector4 bound, uiColor color, bool supportComputeBuffer) {
576582
Vector4 viewport = layer.viewport;
577-
var mat = _shadowBox;
583+
var mat = supportComputeBuffer ? _shadowBox_cb : _shadowBox;
578584
if (!isRect) {
579-
mat = _shadowRBox;
585+
mat = supportComputeBuffer ? _shadowRBox_cb : _shadowRBox;
580586
}
581587

582588
var props = ObjectPool<MaterialPropertyBlockWrapper>.alloc();

Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shadow_utils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void _drawRRectShadow(uiPath path, uiPaint paint) {
6767
ObjectPool<uiMeshMesh>.release(meshBounds);
6868
ObjectPool<uiMeshMesh>.release(blurMesh);
6969
var mesh = uiMeshMesh.create(state.matrix, vertices, _triangles);
70-
layer.draws.Add(CanvasShader.fastShadow(layer, mesh, sigma, path.isRect, path.isCircle, path.rRectCorner, new Vector4(bound.left, bound.top, bound.right, bound.bottom), paint.color));
70+
layer.draws.Add(CanvasShader.fastShadow(layer, mesh, sigma, path.isRect, path.isCircle, path.rRectCorner, new Vector4(bound.left, bound.top, bound.right, bound.bottom), paint.color, this.supportComputeBuffer));
7171
}
7272

7373
}

0 commit comments

Comments
 (0)