diff --git a/assets/resources/chunks.meta b/assets/resources/chunks.meta new file mode 100644 index 0000000..08ab55d --- /dev/null +++ b/assets/resources/chunks.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "b111b3ba-bc35-4e1b-a473-52d58150039c", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/resources/chunks/sdf2d.chunk b/assets/resources/chunks/sdf2d.chunk new file mode 100644 index 0000000..52d0d58 --- /dev/null +++ b/assets/resources/chunks/sdf2d.chunk @@ -0,0 +1,558 @@ +float sdCircle( vec2 p, float r ) +{ + return length(p) - r; +} + +float sdRoundedBox( in vec2 p, in vec2 b, in vec4 r ) +{ + r.xy = (p.x>0.0)?r.xy : r.zw; + r.x = (p.y>0.0)?r.x : r.y; + vec2 q = abs(p)-b+r.x; + return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r.x; +} + +float sdBox( in vec2 p, in vec2 b ) +{ + vec2 d = abs(p)-b; + return length(max(d,0.0)) + min(max(d.x,d.y),0.0); +} + +float sdOrientedBox( in vec2 p, in vec2 a, in vec2 b, float th ) +{ + float l = length(b-a); + vec2 d = (b-a)/l; + vec2 q = (p-(a+b)*0.5); + q = mat2(d.x,-d.y,d.y,d.x)*q; + q = abs(q)-vec2(l,th)*0.5; + return length(max(q,0.0)) + min(max(q.x,q.y),0.0); +} + +float sdSegment( in vec2 p, in vec2 a, in vec2 b ) +{ + vec2 pa = p-a, ba = b-a; + float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); + return length( pa - ba*h ); +} + +float ndot(vec2 a, vec2 b ) { return a.x*b.x - a.y*b.y; } +float sdRhombus( in vec2 p, in vec2 b ) +{ + p = abs(p); + float h = clamp( ndot(b-2.0*p,b)/dot(b,b), -1.0, 1.0 ); + float d = length( p-0.5*b*vec2(1.0-h,1.0+h) ); + return d * sign( p.x*b.y + p.y*b.x - b.x*b.y ); +} + +float sdTrapezoid( in vec2 p, in float r1, float r2, float he ) +{ + vec2 k1 = vec2(r2,he); + vec2 k2 = vec2(r2-r1,2.0*he); + p.x = abs(p.x); + vec2 ca = vec2(p.x-min(p.x,(p.y<0.0)?r1:r2), abs(p.y)-he); + vec2 cb = p - k1 + k2*clamp( dot(k1-p,k2)/dot2(k2), 0.0, 1.0 ); + float s = (cb.x<0.0 && ca.y<0.0) ? -1.0 : 1.0; + return s*sqrt( min(dot2(ca),dot2(cb)) ); +} + +float sdParallelogram( in vec2 p, float wi, float he, float sk ) +{ + vec2 e = vec2(sk,he); + p = (p.y<0.0)?-p:p; + vec2 w = p - e; w.x -= clamp(w.x,-wi,wi); + vec2 d = vec2(dot(w,w), -w.y); + float s = p.x*e.y - p.y*e.x; + p = (s<0.0)?-p:p; + vec2 v = p - vec2(wi,0); v -= e*clamp(dot(v,e)/dot(e,e),-1.0,1.0); + d = min( d, vec2(dot(v,v), wi*he-abs(s))); + return sqrt(d.x)*sign(-d.y); +} + +float sdEquilateralTriangle( in vec2 p, in float r ) +{ + const float k = sqrt(3.0); + p.x = abs(p.x) - r; + p.y = p.y + r/k; + if( p.x+k*p.y>0.0 ) p = vec2(p.x-k*p.y,-k*p.x-p.y)/2.0; + p.x -= clamp( p.x, -2.0*r, 0.0 ); + return -length(p)*sign(p.y); +} + +float sdTriangleIsosceles( in vec2 p, in vec2 q ) +{ + p.x = abs(p.x); + vec2 a = p - q*clamp( dot(p,q)/dot(q,q), 0.0, 1.0 ); + vec2 b = p - q*vec2( clamp( p.x/q.x, 0.0, 1.0 ), 1.0 ); + float s = -sign( q.y ); + vec2 d = min( vec2( dot(a,a), s*(p.x*q.y-p.y*q.x) ), + vec2( dot(b,b), s*(p.y-q.y) )); + return -sqrt(d.x)*sign(d.y); +} + +float sdTriangle( in vec2 p, in vec2 p0, in vec2 p1, in vec2 p2 ) +{ + vec2 e0 = p1-p0, e1 = p2-p1, e2 = p0-p2; + vec2 v0 = p -p0, v1 = p -p1, v2 = p -p2; + vec2 pq0 = v0 - e0*clamp( dot(v0,e0)/dot(e0,e0), 0.0, 1.0 ); + vec2 pq1 = v1 - e1*clamp( dot(v1,e1)/dot(e1,e1), 0.0, 1.0 ); + vec2 pq2 = v2 - e2*clamp( dot(v2,e2)/dot(e2,e2), 0.0, 1.0 ); + float s = sign( e0.x*e2.y - e0.y*e2.x ); + vec2 d = min(min(vec2(dot(pq0,pq0), s*(v0.x*e0.y-v0.y*e0.x)), + vec2(dot(pq1,pq1), s*(v1.x*e1.y-v1.y*e1.x))), + vec2(dot(pq2,pq2), s*(v2.x*e2.y-v2.y*e2.x))); + return -sqrt(d.x)*sign(d.y); +} + +float sdUnevenCapsule( vec2 p, float r1, float r2, float h ) +{ + p.x = abs(p.x); + float b = (r1-r2)/h; + float a = sqrt(1.0-b*b); + float k = dot(p,vec2(-b,a)); + if( k < 0.0 ) return length(p) - r1; + if( k > a*h ) return length(p-vec2(0.0,h)) - r2; + return dot(p, vec2(a,b) ) - r1; +} + +float sdPentagon( in vec2 p, in float r ) +{ + const vec3 k = vec3(0.809016994,0.587785252,0.726542528); + p.x = abs(p.x); + p -= 2.0*min(dot(vec2(-k.x,k.y),p),0.0)*vec2(-k.x,k.y); + p -= 2.0*min(dot(vec2( k.x,k.y),p),0.0)*vec2( k.x,k.y); + p -= vec2(clamp(p.x,-r*k.z,r*k.z),r); + return length(p)*sign(p.y); +} + +float sdHexagon( in vec2 p, in float r ) +{ + const vec3 k = vec3(-0.866025404,0.5,0.577350269); + p = abs(p); + p -= 2.0*min(dot(k.xy,p),0.0)*k.xy; + p -= vec2(clamp(p.x, -k.z*r, k.z*r), r); + return length(p)*sign(p.y); +} + +float sdOctogon( in vec2 p, in float r ) +{ + const vec3 k = vec3(-0.9238795325, 0.3826834323, 0.4142135623 ); + p = abs(p); + p -= 2.0*min(dot(vec2( k.x,k.y),p),0.0)*vec2( k.x,k.y); + p -= 2.0*min(dot(vec2(-k.x,k.y),p),0.0)*vec2(-k.x,k.y); + p -= vec2(clamp(p.x, -k.z*r, k.z*r), r); + return length(p)*sign(p.y); +} + +float sdHexagram( in vec2 p, in float r ) +{ + const vec4 k = vec4(-0.5,0.8660254038,0.5773502692,1.7320508076); + p = abs(p); + p -= 2.0*min(dot(k.xy,p),0.0)*k.xy; + p -= 2.0*min(dot(k.yx,p),0.0)*k.yx; + p -= vec2(clamp(p.x,r*k.z,r*k.w),r); + return length(p)*sign(p.y); +} + +float sdStar5(in vec2 p, in float r, in float rf) +{ + const vec2 k1 = vec2(0.809016994375, -0.587785252292); + const vec2 k2 = vec2(-k1.x,k1.y); + p.x = abs(p.x); + p -= 2.0*max(dot(k1,p),0.0)*k1; + p -= 2.0*max(dot(k2,p),0.0)*k2; + p.x = abs(p.x); + p.y -= r; + vec2 ba = rf*vec2(-k1.y,k1.x) - vec2(0,1); + float h = clamp( dot(p,ba)/dot(ba,ba), 0.0, r ); + return length(p-ba*h) * sign(p.y*ba.x-p.x*ba.y); +} + +float sdStar( in vec2 p, in float r, in int n, in float m) +{ + // next 4 lines can be precomputed for a given shape + float an = 3.141593/float(n); + float en = 3.141593/m; // m is between 2 and n + vec2 acs = vec2(cos(an),sin(an)); + vec2 ecs = vec2(cos(en),sin(en)); // ecs=vec2(0,1) for regular polygon + + float bn = mod(atan(p.x,p.y),2.0*an) - an; + p = length(p)*vec2(cos(bn),abs(sin(bn))); + p -= r*acs; + p += ecs*clamp( -dot(p,ecs), 0.0, r*acs.y/ecs.y); + return length(p)*sign(p.x); +} + +float sdPie( in vec2 p, in vec2 c, in float r ) +{ + p.x = abs(p.x); + float l = length(p) - r; + float m = length(p-c*clamp(dot(p,c),0.0,r)); // c=sin/cos of aperture + return max(l,m*sign(c.y*p.x-c.x*p.y)); +} + +float sdCutDisk( in vec2 p, in float r, in float h ) +{ + float w = sqrt(r*r-h*h); // constant for any given shape + p.x = abs(p.x); + float s = max( (h-r)*p.x*p.x+w*w*(h+r-2.0*p.y), h*p.x-w*p.y ); + return (s<0.0) ? length(p)-r : + (p.xsc.x*p.y) ? length(p-sc*ra) : + abs(length(p)-ra)) - rb; +} + +float sdRing( in vec2 p, in vec2 n, in float r, float th ) +{ + p.x = abs(p.x); + + p = mat2x2(n.x,n.y,-n.y,n.x)*p; + + return max( abs(length(p)-r)-th*0.5, + length(vec2(p.x,max(0.0,abs(r-p.y)-th*0.5)))*sign(p.x) ); +} + +float sdHorseshoe( in vec2 p, in vec2 c, in float r, in vec2 w ) +{ + p.x = abs(p.x); + float l = length(p); + p = mat2(-c.x, c.y, c.y, c.x)*p; + p = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), + (p.x>0.0)?p.y:l ); + p = vec2(p.x,abs(p.y-r))-w; + return length(max(p,0.0)) + min(0.0,max(p.x,p.y)); +} + +float sdVesica(vec2 p, float r, float d) +{ + p = abs(p); + float b = sqrt(r*r-d*d); + return ((p.y-b)*d>p.x*b) ? length(p-vec2(0.0,b)) + : length(p-vec2(-d,0.0))-r; +} + +float sdOrientedVesica( vec2 p, vec2 a, vec2 b, float w ) +{ + float r = 0.5*length(b-a); + float d = 0.5*(r*r-w*w)/w; + vec2 v = (b-a)/r; + vec2 c = (b+a)*0.5; + vec2 q = 0.5*abs(mat2(v.y,v.x,-v.x,v.y)*(p-c)); + vec3 h = (r*q.x d*d*max(b-p.y,0.0) ) + return length(p-vec2(a,b)); + return max( (length(p )-ra), + -(length(p-vec2(d,0))-rb)); +} + +float sdRoundedCross( in vec2 p, in float h ) +{ + float k = 0.5*(h+1.0/h); + p = abs(p); + return ( p.x<1.0 && p.y1.0 ) + return sqrt(dot2(p-vec2(0.25,0.75))) - sqrt(2.0)/4.0; + return sqrt(min(dot2(p-vec2(0.00,1.00)), + dot2(p-0.5*max(p.x+p.y,0.0)))) * sign(p.x-p.y); +} + +float sdCross( in vec2 p, in vec2 b, float r ) +{ + p = abs(p); p = (p.y>p.x) ? p.yx : p.xy; + vec2 q = p - b; + float k = max(q.y,q.x); + vec2 w = (k>0.0) ? q : vec2(b.y-p.x,-k); + return sign(k)*length(max(w,0.0)) + r; +} + +float sdRoundedX( in vec2 p, in float w, in float r ) +{ + p = abs(p); + return length(p-min(p.x+p.y,w)*0.5) - r; +} + +float sdPolygon( in vec2[N] v, in vec2 p ) +{ + float d = dot(p-v[0],p-v[0]); + float s = 1.0; + for( int i=0, j=N-1; i=v[i].y,p.ye.y*w.x); + if( all(c) || all(not(c)) ) s*=-1.0; + } + return s*sqrt(d); +} + +float sdEllipse( in vec2 p, in vec2 ab ) +{ + p = abs(p); if( p.x > p.y ) {p=p.yx;ab=ab.yx;} + float l = ab.y*ab.y - ab.x*ab.x; + float m = ab.x*p.x/l; float m2 = m*m; + float n = ab.y*p.y/l; float n2 = n*n; + float c = (m2+n2-1.0)/3.0; float c3 = c*c*c; + float q = c3 + m2*n2*2.0; + float d = c3 + m2*n2; + float g = m + m*n2; + float co; + if( d<0.0 ) + { + float h = acos(q/c3)/3.0; + float s = cos(h); + float t = sin(h)*sqrt(3.0); + float rx = sqrt( -c*(s + t + 2.0) + m2 ); + float ry = sqrt( -c*(s - t + 2.0) + m2 ); + co = (ry+sign(l)*rx+abs(g)/(rx*ry)- m)/2.0; + } + else + { + float h = 2.0*m*n*sqrt( d ); + float s = sign(q+h)*pow(abs(q+h), 1.0/3.0); + float u = sign(q-h)*pow(abs(q-h), 1.0/3.0); + float rx = -s - u - c*4.0 + 2.0*m2; + float ry = (s - u)*sqrt(3.0); + float rm = sqrt( rx*rx + ry*ry ); + co = (ry/sqrt(rm-rx)+2.0*g/rm-m)/2.0; + } + vec2 r = ab * vec2(co, sqrt(1.0-co*co)); + return length(r-p) * sign(p.y-r.y); +} + +float sdParabola( in vec2 pos, in float k ) +{ + pos.x = abs(pos.x); + float ik = 1.0/k; + float p = ik*(pos.y - 0.5*ik)/3.0; + float q = 0.25*ik*ik*pos.x; + float h = q*q - p*p*p; + float r = sqrt(abs(h)); + float x = (h>0.0) ? + pow(q+r,1.0/3.0) - pow(abs(q-r),1.0/3.0)*sign(r-q) : + 2.0*cos(atan(r,q)/3.0)*sqrt(p); + return length(pos-vec2(x,k*x*x)) * sign(pos.x-x); +} + +float sdParabola( in vec2 pos, in float wi, in float he ) +{ + pos.x = abs(pos.x); + float ik = wi*wi/he; + float p = ik*(he-pos.y-0.5*ik)/3.0; + float q = pos.x*ik*ik*0.25; + float h = q*q - p*p*p; + float r = sqrt(abs(h)); + float x = (h>0.0) ? + pow(q+r,1.0/3.0) - pow(abs(q-r),1.0/3.0)*sign(r-q) : + 2.0*cos(atan(r/q)/3.0)*sqrt(p); + x = min(x,wi); + return length(pos-vec2(x,he-x*x/ik)) * + sign(ik*(pos.y-he)+pos.x*pos.x); +} + +float sdBezier( in vec2 pos, in vec2 A, in vec2 B, in vec2 C ) +{ + vec2 a = B - A; + vec2 b = A - 2.0*B + C; + vec2 c = a * 2.0; + vec2 d = A - pos; + float kk = 1.0/dot(b,b); + float kx = kk * dot(a,b); + float ky = kk * (2.0*dot(a,a)+dot(d,b)) / 3.0; + float kz = kk * dot(d,a); + float res = 0.0; + float p = ky - kx*kx; + float p3 = p*p*p; + float q = kx*(2.0*kx*kx-3.0*ky) + kz; + float h = q*q + 4.0*p3; + if( h >= 0.0) + { + h = sqrt(h); + vec2 x = (vec2(h,-h)-q)/2.0; + vec2 uv = sign(x)*pow(abs(x), vec2(1.0/3.0)); + float t = clamp( uv.x+uv.y-kx, 0.0, 1.0 ); + res = dot2(d + (c + b*t)*t); + } + else + { + float z = sqrt(-p); + float v = acos( q/(p*z*2.0) ) / 3.0; + float m = cos(v); + float n = sin(v)*1.732050808; + vec3 t = clamp(vec3(m+m,-n-m,n-m)*z-kx,0.0,1.0); + res = min( dot2(d+(c+b*t.x)*t.x), + dot2(d+(c+b*t.y)*t.y) ); + // the third root cannot be the closest + // res = min(res,dot2(d+(c+b*t.z)*t.z)); + } + return sqrt( res ); +} + +float sdBlobbyCross( in vec2 pos, float he ) +{ + pos = abs(pos); + pos = vec2(abs(pos.x-pos.y),1.0-pos.x-pos.y)/sqrt(2.0); + + float p = (he-pos.y-0.25/he)/(6.0*he); + float q = pos.x/(he*he*16.0); + float h = q*q - p*p*p; + + float x; + if( h>0.0 ) { float r = sqrt(h); x = pow(q+r,1.0/3.0)-pow(abs(q-r),1.0/3.0)*sign(r-q); } + else { float r = sqrt(p); x = 2.0*r*cos(acos(q/(p*r))/3.0); } + x = min(x,sqrt(2.0)/2.0); + + vec2 z = vec2(x,he*(1.0-2.0*x*x)) - pos; + return length(z) * sign(z.y); +} + +float sdTunnel( in vec2 p, in vec2 wh ) +{ + p.x = abs(p.x); p.y = -p.y; + vec2 q = p - wh; + + float d1 = dot2(vec2(max(q.x,0.0),q.y)); + q.x = (p.y>0.0) ? q.x : length(p)-wh.x; + float d2 = dot2(vec2(q.x,max(q.y,0.0))); + float d = sqrt( min(d1,d2) ); + + return (max(q.x,q.y)<0.0) ? -d : d; +} + +float sdStairs( in vec2 p, in vec2 wh, in float n ) +{ + vec2 ba = wh*n; + float d = min(dot2(p-vec2(clamp(p.x,0.0,ba.x),0.0)), + dot2(p-vec2(ba.x,clamp(p.y,0.0,ba.y))) ); + float s = sign(max(-p.y,p.x-ba.x) ); + + float dia = length(wh); + p = mat2(wh.x,-wh.y, wh.y,wh.x)*p/dia; + float id = clamp(round(p.x/dia),0.0,n-1.0); + p.x = p.x - id*dia; + p = mat2(wh.x, wh.y,-wh.y,wh.x)*p/dia; + + float hh = wh.y/2.0; + p.y -= hh; + if( p.y>hh*sign(p.x) ) s=1.0; + p = (id<0.5 || p.x>0.0) ? p : -p; + d = min( d, dot2(p-vec2(0.0,clamp(p.y,-hh,hh))) ); + d = min( d, dot2(p-vec2(clamp(p.x,0.0,wh.x),hh)) ); + + return sqrt(d)*s; +} + +float sdQuadraticCircle( in vec2 p ) +{ + p = abs(p); if( p.y>p.x ) p=p.yx; + + float a = p.x-p.y; + float b = p.x+p.y; + float c = (2.0*b-1.0)/3.0; + float h = a*a + c*c*c; + float t; + if( h>=0.0 ) + { + h = sqrt(h); + t = sign(h-a)*pow(abs(h-a),1.0/3.0) - pow(h+a,1.0/3.0); + } + else + { + float z = sqrt(-c); + float v = acos(a/(c*z))/3.0; + t = -z*(cos(v)+sin(v)*1.732050808); + } + t *= 0.5; + vec2 w = vec2(-t,t) + 0.75 - t*t - p; + return length(w) * sign( a*a*0.5+b-1.5 ); +} + +float sdHyberbola( in vec2 p, in float k, in float he ) // k in (0,inf) +{ + p = abs(p); + p = vec2(p.x-p.y,p.x+p.y)/sqrt(2.0); + + float x2 = p.x*p.x/16.0; + float y2 = p.y*p.y/16.0; + float r = k*(4.0*k - p.x*p.y)/12.0; + float q = (x2 - y2)*k*k; + float h = q*q + r*r*r; + float u; + if( h<0.0 ) + { + float m = sqrt(-r); + u = m*cos( acos(q/(r*m))/3.0 ); + } + else + { + float m = pow(sqrt(h)-q,1.0/3.0); + u = (m - r/m)/2.0; + } + float w = sqrt( u + x2 ); + float b = k*p.y - x2*p.x*2.0; + float t = p.x/4.0 - w + sqrt( 2.0*x2 - u + b/w/4.0 ); + t = max(t,sqrt(he*he*0.5+k)-he/sqrt(2.0)); + float d = length( p-vec2(t,k/t) ); + return p.x*p.y < k ? d : -d; +} + +float sdfCoolS( in vec2 p ) +{ + float six = (p.y<0.0) ? -p.x : p.x; + p.x = abs(p.x); + p.y = abs(p.y) - 0.2; + float rex = p.x - min(round(p.x/0.4),0.4); + float aby = abs(p.y-0.2)-0.6; + + float d = dot2(vec2(six,-p.y)-clamp(0.5*(six-p.y),0.0,0.2)); + d = min(d,dot2(vec2(p.x,-aby)-clamp(0.5*(p.x-aby),0.0,0.4))); + d = min(d,dot2(vec2(rex,p.y -clamp(p.y ,0.0,0.4)))); + + float s = 2.0*p.x + aby + abs(aby+0.4) - 0.4; + return sqrt(d) * sign(s); +} + +float sdCircleWave( in vec2 p, in float tb, in float ra ) +{ + tb = 3.1415927*5.0/6.0*max(tb,0.0001); + vec2 co = ra*vec2(sin(tb),cos(tb)); + p.x = abs(mod(p.x,co.x*4.0)-co.x*2.0); + vec2 p1 = p; + vec2 p2 = vec2(abs(p.x-2.0*co.x),-p.y+2.0*co.y); + float d1 = ((co.y*p1.x>co.x*p1.y) ? length(p1-co) : abs(length(p1)-ra)); + float d2 = ((co.y*p2.x>co.x*p2.y) ? length(p2-co) : abs(length(p2)-ra)); + return min(d1, d2); +} \ No newline at end of file diff --git a/assets/resources/chunks/sdf2d.chunk.meta b/assets/resources/chunks/sdf2d.chunk.meta new file mode 100644 index 0000000..1d3b3eb --- /dev/null +++ b/assets/resources/chunks/sdf2d.chunk.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.0.7", + "importer": "effect-header", + "imported": true, + "uuid": "cd5b10df-3814-4634-a1ec-4f1b03c1984b", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/resources/effects/color_sdf2d_circle.effect b/assets/resources/effects/color_sdf2d_circle.effect new file mode 100644 index 0000000..77b0544 --- /dev/null +++ b/assets/resources/effects/color_sdf2d_circle.effect @@ -0,0 +1,94 @@ +// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. +CCEffect %{ + techniques: + - passes: + - vert: sprite-vs:vert + frag: sprite-fs:frag + depthStencilState: + depthTest: false + depthWrite: false + blendState: + targets: + - blend: true + blendSrc: src_alpha + blendDst: one_minus_src_alpha + blendDstAlpha: one_minus_src_alpha + rasterizerState: + cullMode: none + properties: + alphaThreshold: { value: 0.5 } +}% + +CCProgram sprite-vs %{ + precision highp float; + #include + #if USE_LOCAL + #include + #endif + #if SAMPLE_FROM_RT + #include + #endif + in vec3 a_position; + in vec2 a_texCoord; + in vec4 a_color; + + out vec4 color; + out vec2 uv0; + + vec4 vert () { + vec4 pos = vec4(a_position, 1); + + #if USE_LOCAL + pos = cc_matWorld * pos; + #endif + + #if USE_PIXEL_ALIGNMENT + pos = cc_matView * pos; + pos.xyz = floor(pos.xyz); + pos = cc_matProj * pos; + #else + pos = cc_matViewProj * pos; + #endif + + uv0 = a_texCoord; + #if SAMPLE_FROM_RT + CC_HANDLE_RT_SAMPLE_FLIP(uv0); + #endif + color = a_color; + + return pos; + } +}% + +CCProgram sprite-fs %{ + precision highp float; + #include + #include + #include "../chunks/sdf2d" + in vec4 color; + + #if USE_TEXTURE + in vec2 uv0; + #pragma builtin(local) + layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture; + #endif + + vec4 frag () { + vec4 o = vec4(1, 1, 1, 1); + + #if USE_TEXTURE + o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0); + #if IS_GRAY + float gray = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b; + o.r = o.g = o.b = gray; + #endif + #endif + + vec2 uv = (uv0 - color.xy) / color.zw; + float d = sdCircle(uv - 0.5, 0.5); + float c = smoothstep(0.01, -0.01, d); + o.a *= c; + ALPHA_TEST(o); + return o; + } +}% diff --git a/assets/resources/effects/color_sdf2d_circle.effect.meta b/assets/resources/effects/color_sdf2d_circle.effect.meta new file mode 100644 index 0000000..ee8bc66 --- /dev/null +++ b/assets/resources/effects/color_sdf2d_circle.effect.meta @@ -0,0 +1,11 @@ +{ + "ver": "1.7.1", + "importer": "effect", + "imported": true, + "uuid": "53b86133-01bd-45ed-8cf8-94234cba4494", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": {} +} diff --git a/assets/resources/materials/color_sdf2d_circle.mtl b/assets/resources/materials/color_sdf2d_circle.mtl new file mode 100644 index 0000000..0a4dcab --- /dev/null +++ b/assets/resources/materials/color_sdf2d_circle.mtl @@ -0,0 +1,31 @@ +{ + "__type__": "cc.Material", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "_effectAsset": { + "__uuid__": "53b86133-01bd-45ed-8cf8-94234cba4494", + "__expectedType__": "cc.EffectAsset" + }, + "_techIdx": 0, + "_defines": [ + { + "USE_TEXTURE": true + } + ], + "_states": [ + { + "rasterizerState": {}, + "depthStencilState": {}, + "blendState": { + "targets": [ + {} + ] + } + } + ], + "_props": [ + {} + ] +} \ No newline at end of file diff --git a/assets/resources/materials/color_sdf2d_circle.mtl.meta b/assets/resources/materials/color_sdf2d_circle.mtl.meta new file mode 100644 index 0000000..550bdaf --- /dev/null +++ b/assets/resources/materials/color_sdf2d_circle.mtl.meta @@ -0,0 +1,11 @@ +{ + "ver": "1.0.21", + "importer": "material", + "imported": true, + "uuid": "4ba0fcca-0f92-4795-af0a-f2076bcc63b5", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": {} +} diff --git a/assets/resources/scenes/sdf2d.scene b/assets/resources/scenes/sdf2d.scene new file mode 100644 index 0000000..5d216bf --- /dev/null +++ b/assets/resources/scenes/sdf2d.scene @@ -0,0 +1,1386 @@ +[ + { + "__type__": "cc.SceneAsset", + "_name": "sdf2d", + "_objFlags": 0, + "__editorExtras__": {}, + "_native": "", + "scene": { + "__id__": 1 + } + }, + { + "__type__": "cc.Scene", + "_name": "sdf2d", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": null, + "_children": [ + { + "__id__": 2 + }, + { + "__id__": 5 + }, + { + "__id__": 7 + } + ], + "_active": true, + "_components": [], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "autoReleaseAssets": false, + "_globals": { + "__id__": 34 + }, + "_id": "2d052f05-f3ae-4ade-a629-7dc0680a169b" + }, + { + "__type__": "cc.Node", + "_name": "Main Light", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 3 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": -0.06397656665577071, + "y": -0.44608233363525845, + "z": -0.8239028751062036, + "w": -0.3436591377065261 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": -117.894, + "y": -194.909, + "z": 38.562 + }, + "_id": "c0y6F5f+pAvI805TdmxIjx" + }, + { + "__type__": "cc.DirectionalLight", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 2 + }, + "_enabled": true, + "__prefab": null, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 250, + "b": 240, + "a": 255 + }, + "_useColorTemperature": false, + "_colorTemperature": 6550, + "_staticSettings": { + "__id__": 4 + }, + "_visibility": -325058561, + "_illuminanceHDR": 65000, + "_illuminance": 65000, + "_illuminanceLDR": 1.6927083333333335, + "_shadowEnabled": false, + "_shadowPcf": 0, + "_shadowBias": 0.00001, + "_shadowNormalBias": 0, + "_shadowSaturation": 1, + "_shadowDistance": 50, + "_shadowInvisibleOcclusionRange": 200, + "_csmLevel": 4, + "_csmLayerLambda": 0.75, + "_csmOptimizationMode": 2, + "_csmAdvancedOptions": false, + "_csmLayersTransition": false, + "_csmTransitionRange": 0.05, + "_shadowFixedArea": false, + "_shadowNear": 0.1, + "_shadowFar": 10, + "_shadowOrthoSize": 5, + "_id": "597uMYCbhEtJQc0ffJlcgA" + }, + { + "__type__": "cc.StaticLightSettings", + "_baked": false, + "_editorOnly": false, + "_castShadow": false + }, + { + "__type__": "cc.Node", + "_name": "Main Camera", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 6 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": -10, + "y": 10, + "z": 10 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": -0.27781593346944056, + "y": -0.36497167621709875, + "z": -0.11507512748638377, + "w": 0.8811195706053617 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": -35, + "y": -45, + "z": 0 + }, + "_id": "c9DMICJLFO5IeO07EPon7U" + }, + { + "__type__": "cc.Camera", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 5 + }, + "_enabled": true, + "__prefab": null, + "_projection": 1, + "_priority": 0, + "_fov": 45, + "_fovAxis": 0, + "_orthoHeight": 10, + "_near": 1, + "_far": 1000, + "_color": { + "__type__": "cc.Color", + "r": 51, + "g": 51, + "b": 51, + "a": 255 + }, + "_depth": 1, + "_stencil": 0, + "_clearFlags": 14, + "_rect": { + "__type__": "cc.Rect", + "x": 0, + "y": 0, + "width": 1, + "height": 1 + }, + "_aperture": 19, + "_shutter": 7, + "_iso": 0, + "_screenScale": 1, + "_visibility": 1822425087, + "_targetTexture": null, + "_postProcess": null, + "_usePostProcess": false, + "_cameraType": -1, + "_trackingType": 0, + "_id": "7dWQTpwS5LrIHnc1zAPUtf" + }, + { + "__type__": "cc.Node", + "_name": "Canvas", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 8 + }, + { + "__id__": 10 + }, + { + "__id__": 13 + }, + { + "__id__": 16 + }, + { + "__id__": 19 + }, + { + "__id__": 22 + }, + { + "__id__": 25 + }, + { + "__id__": 28 + } + ], + "_active": true, + "_components": [ + { + "__id__": 31 + }, + { + "__id__": 32 + }, + { + "__id__": 33 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 640, + "y": 360, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "ea3TZXdAtPhJ1+BzX5RknQ" + }, + { + "__type__": "cc.Node", + "_name": "Camera", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 7 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 9 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 1000 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 1073741824, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "9aC5Dlg8BC8q1P5tc8bo/c" + }, + { + "__type__": "cc.Camera", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 8 + }, + "_enabled": true, + "__prefab": null, + "_projection": 0, + "_priority": 1073741824, + "_fov": 45, + "_fovAxis": 0, + "_orthoHeight": 513.8028169014085, + "_near": 1, + "_far": 2000, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_depth": 1, + "_stencil": 0, + "_clearFlags": 6, + "_rect": { + "__type__": "cc.Rect", + "x": 0, + "y": 0, + "width": 1, + "height": 1 + }, + "_aperture": 19, + "_shutter": 7, + "_iso": 0, + "_screenScale": 1, + "_visibility": 41943040, + "_targetTexture": null, + "_postProcess": null, + "_usePostProcess": false, + "_cameraType": -1, + "_trackingType": 0, + "_id": "76YOvG7BxNkq3d511Y/lsV" + }, + { + "__type__": "cc.Node", + "_name": "Sprite", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 7 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 11 + }, + { + "__id__": 12 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 429.649, + "y": 49.546, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "cdvHCabYRDU5eqoyx4sldw" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "64qwVXPXRNcJmqx2IER2T8" + }, + { + "__type__": "6845d+/NTJDrKyRKBO2mDiC", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 10 + }, + "_enabled": true, + "__prefab": null, + "_customMaterial": { + "__uuid__": "4ba0fcca-0f92-4795-af0a-f2076bcc63b5", + "__expectedType__": "cc.Material" + }, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 255, + "a": 255 + }, + "_sizeMode": 0, + "_atlas": null, + "_spriteFrame": { + "__uuid__": "bddc449e-6a35-46d7-9291-273646837fc2@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_id": "95xHA0UV5L9KSHxXGt/Cxv" + }, + { + "__type__": "cc.Node", + "_name": "Sprite", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 7 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 14 + }, + { + "__id__": 15 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 235.297, + "y": -229.264, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "a0Lp8vE/hFur+hy+rzrSX0" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 13 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "96wxCEKIhAs7WFxUdt5L78" + }, + { + "__type__": "6845d+/NTJDrKyRKBO2mDiC", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 13 + }, + "_enabled": true, + "__prefab": null, + "_customMaterial": { + "__uuid__": "4ba0fcca-0f92-4795-af0a-f2076bcc63b5", + "__expectedType__": "cc.Material" + }, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 255, + "a": 255 + }, + "_sizeMode": 0, + "_atlas": null, + "_spriteFrame": { + "__uuid__": "1d73d268-60d8-4712-8012-d023bbc1cc94@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_id": "d5jeNNz0NAPICuJkf0ORiG" + }, + { + "__type__": "cc.Node", + "_name": "Sprite-001", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 7 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 17 + }, + { + "__id__": 18 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": -27.15, + "y": -159.882, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "f9CcAHeUJFeo4jWMNonkf9" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 16 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "179NSf6eJNKrXUgnlxtQ/W" + }, + { + "__type__": "6845d+/NTJDrKyRKBO2mDiC", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 16 + }, + "_enabled": true, + "__prefab": null, + "_customMaterial": { + "__uuid__": "4ba0fcca-0f92-4795-af0a-f2076bcc63b5", + "__expectedType__": "cc.Material" + }, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 255, + "a": 255 + }, + "_sizeMode": 0, + "_atlas": null, + "_spriteFrame": { + "__uuid__": "de85f305-c99e-46fc-9079-93d1db81c7b4@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_id": "cbrutxVoNLxpDRIByP34kZ" + }, + { + "__type__": "cc.Node", + "_name": "Sprite-002", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 7 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 20 + }, + { + "__id__": 21 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": -3.017, + "y": 241.331, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "f4/JIAzO1K/K5ZVIU5Cflt" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 19 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "842fKZyi5KPKkzTZtNpRSV" + }, + { + "__type__": "6845d+/NTJDrKyRKBO2mDiC", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 19 + }, + "_enabled": true, + "__prefab": null, + "_customMaterial": { + "__uuid__": "4ba0fcca-0f92-4795-af0a-f2076bcc63b5", + "__expectedType__": "cc.Material" + }, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 255, + "a": 255 + }, + "_sizeMode": 0, + "_atlas": null, + "_spriteFrame": { + "__uuid__": "d92e2d44-c554-4264-b30c-3c5a535e960b@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_id": "4ajo5FG2BGFpb9cYzw83cg" + }, + { + "__type__": "cc.Node", + "_name": "Sprite-003", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 7 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 23 + }, + { + "__id__": 24 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": -431.379, + "y": 159.882, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "e2RFd1qsVJmaEWRDNp1LKZ" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 22 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "1cFHYwqR5MLa0Bz/4EkqXW" + }, + { + "__type__": "6845d+/NTJDrKyRKBO2mDiC", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 22 + }, + "_enabled": true, + "__prefab": null, + "_customMaterial": { + "__uuid__": "4ba0fcca-0f92-4795-af0a-f2076bcc63b5", + "__expectedType__": "cc.Material" + }, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 255, + "a": 255 + }, + "_sizeMode": 0, + "_atlas": null, + "_spriteFrame": { + "__uuid__": "2833a55b-f13f-4692-92f1-d8a8213855c6@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_id": "dfir0HY8BMQaurQTHB/Bl4" + }, + { + "__type__": "cc.Node", + "_name": "Sprite-004", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 7 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 26 + }, + { + "__id__": 27 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": -232.281, + "y": 135.749, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "baFzjsZp1EYLH7/Teqe2vu" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 25 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 140, + "height": 140 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "1chW6b+aZMqq2xjj36w3mg" + }, + { + "__type__": "6845d+/NTJDrKyRKBO2mDiC", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 25 + }, + "_enabled": true, + "__prefab": null, + "_customMaterial": { + "__uuid__": "4ba0fcca-0f92-4795-af0a-f2076bcc63b5", + "__expectedType__": "cc.Material" + }, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 255, + "a": 255 + }, + "_sizeMode": 1, + "_atlas": null, + "_spriteFrame": { + "__uuid__": "890f043a-8cad-46e4-b5b1-584554c0cad1@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_id": "3b5tkeLwlFea1Ltig4iGFr" + }, + { + "__type__": "cc.Node", + "_name": "Label", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 7 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 29 + }, + { + "__id__": 30 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_mobility": 0, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "fdaYMch/NCsKNTTMH1NOt/" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 28 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 702.275390625, + "height": 50.4 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "81WyTdS2xLK5HH23JFa2UE" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 28 + }, + "_enabled": true, + "__prefab": null, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_string": "使用shader进行圆形裁切,使用颜色值来传递变化后的uv数据。不受合批影响。", + "_horizontalAlign": 1, + "_verticalAlign": 1, + "_actualFontSize": 20, + "_fontSize": 20, + "_fontFamily": "Arial", + "_lineHeight": 40, + "_overflow": 0, + "_enableWrapText": true, + "_font": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_isItalic": false, + "_isBold": false, + "_isUnderline": false, + "_underlineHeight": 2, + "_cacheMode": 0, + "_id": "4aGTRjMNxCoqiUuq4OFYUi" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 7 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 1280, + "height": 720 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "50mxIY/WFLFq3nQWWrSJYh" + }, + { + "__type__": "cc.Canvas", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 7 + }, + "_enabled": true, + "__prefab": null, + "_cameraComponent": { + "__id__": 9 + }, + "_alignCanvasWithScreen": true, + "_id": "19/CnwIVlPVpT/ZMr01dwz" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 7 + }, + "_enabled": true, + "__prefab": null, + "_alignFlags": 45, + "_target": null, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_horizontalCenter": 0, + "_verticalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 0, + "_originalHeight": 0, + "_alignMode": 2, + "_lockFlags": 0, + "_id": "37PdnGzVlL2Z6PcVfhlR/4" + }, + { + "__type__": "cc.SceneGlobals", + "ambient": { + "__id__": 35 + }, + "shadows": { + "__id__": 36 + }, + "_skybox": { + "__id__": 37 + }, + "fog": { + "__id__": 38 + }, + "octree": { + "__id__": 39 + }, + "skin": { + "__id__": 40 + }, + "lightProbeInfo": { + "__id__": 41 + }, + "postSettings": { + "__id__": 42 + }, + "bakedWithStationaryMainLight": false, + "bakedWithHighpLightmap": false + }, + { + "__type__": "cc.AmbientInfo", + "_skyColorHDR": { + "__type__": "cc.Vec4", + "x": 0.2, + "y": 0.5, + "z": 0.8, + "w": 0.520833125 + }, + "_skyColor": { + "__type__": "cc.Vec4", + "x": 0.2, + "y": 0.5, + "z": 0.8, + "w": 0.520833125 + }, + "_skyIllumHDR": 20000, + "_skyIllum": 20000, + "_groundAlbedoHDR": { + "__type__": "cc.Vec4", + "x": 0.2, + "y": 0.2, + "z": 0.2, + "w": 1 + }, + "_groundAlbedo": { + "__type__": "cc.Vec4", + "x": 0.2, + "y": 0.2, + "z": 0.2, + "w": 1 + }, + "_skyColorLDR": { + "__type__": "cc.Vec4", + "x": 0.452588, + "y": 0.607642, + "z": 0.755699, + "w": 0 + }, + "_skyIllumLDR": 0.8, + "_groundAlbedoLDR": { + "__type__": "cc.Vec4", + "x": 0.618555, + "y": 0.577848, + "z": 0.544564, + "w": 0 + } + }, + { + "__type__": "cc.ShadowsInfo", + "_enabled": false, + "_type": 0, + "_normal": { + "__type__": "cc.Vec3", + "x": 0, + "y": 1, + "z": 0 + }, + "_distance": 0, + "_shadowColor": { + "__type__": "cc.Color", + "r": 76, + "g": 76, + "b": 76, + "a": 255 + }, + "_maxReceived": 4, + "_size": { + "__type__": "cc.Vec2", + "x": 1024, + "y": 1024 + } + }, + { + "__type__": "cc.SkyboxInfo", + "_envLightingType": 0, + "_envmapHDR": { + "__uuid__": "d032ac98-05e1-4090-88bb-eb640dcb5fc1@b47c0", + "__expectedType__": "cc.TextureCube" + }, + "_envmap": { + "__uuid__": "d032ac98-05e1-4090-88bb-eb640dcb5fc1@b47c0", + "__expectedType__": "cc.TextureCube" + }, + "_envmapLDR": { + "__uuid__": "6f01cf7f-81bf-4a7e-bd5d-0afc19696480@b47c0", + "__expectedType__": "cc.TextureCube" + }, + "_diffuseMapHDR": null, + "_diffuseMapLDR": null, + "_enabled": true, + "_useHDR": true, + "_editableMaterial": null, + "_reflectionHDR": null, + "_reflectionLDR": null, + "_rotationAngle": 0 + }, + { + "__type__": "cc.FogInfo", + "_type": 0, + "_fogColor": { + "__type__": "cc.Color", + "r": 200, + "g": 200, + "b": 200, + "a": 255 + }, + "_enabled": false, + "_fogDensity": 0.3, + "_fogStart": 0.5, + "_fogEnd": 300, + "_fogAtten": 5, + "_fogTop": 1.5, + "_fogRange": 1.2, + "_accurate": false + }, + { + "__type__": "cc.OctreeInfo", + "_enabled": false, + "_minPos": { + "__type__": "cc.Vec3", + "x": -1024, + "y": -1024, + "z": -1024 + }, + "_maxPos": { + "__type__": "cc.Vec3", + "x": 1024, + "y": 1024, + "z": 1024 + }, + "_depth": 8 + }, + { + "__type__": "cc.SkinInfo", + "_enabled": true, + "_blurRadius": 0.01, + "_sssIntensity": 3 + }, + { + "__type__": "cc.LightProbeInfo", + "_giScale": 1, + "_giSamples": 1024, + "_bounces": 2, + "_reduceRinging": 0, + "_showProbe": true, + "_showWireframe": true, + "_showConvex": false, + "_data": null, + "_lightProbeSphereVolume": 1 + }, + { + "__type__": "cc.PostSettingsInfo", + "_toneMappingType": 0 + } +] \ No newline at end of file diff --git a/assets/resources/scenes/sdf2d.scene.meta b/assets/resources/scenes/sdf2d.scene.meta new file mode 100644 index 0000000..2573dce --- /dev/null +++ b/assets/resources/scenes/sdf2d.scene.meta @@ -0,0 +1,11 @@ +{ + "ver": "1.1.49", + "importer": "scene", + "imported": true, + "uuid": "2d052f05-f3ae-4ade-a629-7dc0680a169b", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": {} +} diff --git a/assets/resources/ui/atlas.meta b/assets/resources/ui/atlas.meta new file mode 100644 index 0000000..bdf7e6f --- /dev/null +++ b/assets/resources/ui/atlas.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "95913e5b-473a-47bf-b9f4-6cd710dff9f2", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/resources/ui/icons/abstractTile_26.png b/assets/resources/ui/icons/abstractTile_26.png new file mode 100644 index 0000000..4b1b84a Binary files /dev/null and b/assets/resources/ui/icons/abstractTile_26.png differ diff --git a/assets/resources/ui/icons/abstractTile_26.png.meta b/assets/resources/ui/icons/abstractTile_26.png.meta new file mode 100644 index 0000000..c74d4a2 --- /dev/null +++ b/assets/resources/ui/icons/abstractTile_26.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.26", + "importer": "image", + "imported": true, + "uuid": "bddc449e-6a35-46d7-9291-273646837fc2", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "bddc449e-6a35-46d7-9291-273646837fc2@6c48a", + "displayName": "abstractTile_26", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "repeat", + "wrapModeT": "repeat", + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0, + "isUuid": true, + "imageUuidOrDatabaseUri": "bddc449e-6a35-46d7-9291-273646837fc2", + "visible": false + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "bddc449e-6a35-46d7-9291-273646837fc2@f9941", + "displayName": "abstractTile_26", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 92, + "height": 80, + "rawWidth": 92, + "rawHeight": 80, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -46, + -40, + 0, + 46, + -40, + 0, + -46, + 40, + 0, + 46, + 40, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 80, + 92, + 80, + 0, + 0, + 92, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -46, + -40, + 0 + ], + "maxPos": [ + 46, + 40, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "bddc449e-6a35-46d7-9291-273646837fc2@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "hasAlpha": true, + "type": "sprite-frame", + "fixAlphaTransparencyArtifacts": true, + "redirect": "bddc449e-6a35-46d7-9291-273646837fc2@f9941" + } +} diff --git a/assets/resources/ui/icons/abstractTile_27.png b/assets/resources/ui/icons/abstractTile_27.png new file mode 100644 index 0000000..0b1d63f Binary files /dev/null and b/assets/resources/ui/icons/abstractTile_27.png differ diff --git a/assets/resources/ui/icons/abstractTile_27.png.meta b/assets/resources/ui/icons/abstractTile_27.png.meta new file mode 100644 index 0000000..ea16d1f --- /dev/null +++ b/assets/resources/ui/icons/abstractTile_27.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.26", + "importer": "image", + "imported": true, + "uuid": "d92e2d44-c554-4264-b30c-3c5a535e960b", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "d92e2d44-c554-4264-b30c-3c5a535e960b@6c48a", + "displayName": "abstractTile_27", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "repeat", + "wrapModeT": "repeat", + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0, + "isUuid": true, + "imageUuidOrDatabaseUri": "d92e2d44-c554-4264-b30c-3c5a535e960b", + "visible": false + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "d92e2d44-c554-4264-b30c-3c5a535e960b@f9941", + "displayName": "abstractTile_27", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 92, + "height": 80, + "rawWidth": 92, + "rawHeight": 80, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -46, + -40, + 0, + 46, + -40, + 0, + -46, + 40, + 0, + 46, + 40, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 80, + 92, + 80, + 0, + 0, + 92, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -46, + -40, + 0 + ], + "maxPos": [ + 46, + 40, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "d92e2d44-c554-4264-b30c-3c5a535e960b@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "hasAlpha": true, + "type": "sprite-frame", + "fixAlphaTransparencyArtifacts": true, + "redirect": "d92e2d44-c554-4264-b30c-3c5a535e960b@f9941" + } +} diff --git a/assets/resources/ui/icons/abstractTile_28.png b/assets/resources/ui/icons/abstractTile_28.png new file mode 100644 index 0000000..533fcf2 Binary files /dev/null and b/assets/resources/ui/icons/abstractTile_28.png differ diff --git a/assets/resources/ui/icons/abstractTile_28.png.meta b/assets/resources/ui/icons/abstractTile_28.png.meta new file mode 100644 index 0000000..1a27f74 --- /dev/null +++ b/assets/resources/ui/icons/abstractTile_28.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.26", + "importer": "image", + "imported": true, + "uuid": "de85f305-c99e-46fc-9079-93d1db81c7b4", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "de85f305-c99e-46fc-9079-93d1db81c7b4@6c48a", + "displayName": "abstractTile_28", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "repeat", + "wrapModeT": "repeat", + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0, + "isUuid": true, + "imageUuidOrDatabaseUri": "de85f305-c99e-46fc-9079-93d1db81c7b4", + "visible": false + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "de85f305-c99e-46fc-9079-93d1db81c7b4@f9941", + "displayName": "abstractTile_28", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 92, + "height": 80, + "rawWidth": 92, + "rawHeight": 80, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -46, + -40, + 0, + 46, + -40, + 0, + -46, + 40, + 0, + 46, + 40, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 80, + 92, + 80, + 0, + 0, + 92, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -46, + -40, + 0 + ], + "maxPos": [ + 46, + 40, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "de85f305-c99e-46fc-9079-93d1db81c7b4@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "hasAlpha": true, + "type": "sprite-frame", + "fixAlphaTransparencyArtifacts": true, + "redirect": "de85f305-c99e-46fc-9079-93d1db81c7b4@f9941" + } +} diff --git a/assets/resources/ui/icons/abstractTile_29.png b/assets/resources/ui/icons/abstractTile_29.png new file mode 100644 index 0000000..eba94a1 Binary files /dev/null and b/assets/resources/ui/icons/abstractTile_29.png differ diff --git a/assets/resources/ui/icons/abstractTile_29.png.meta b/assets/resources/ui/icons/abstractTile_29.png.meta new file mode 100644 index 0000000..1427e38 --- /dev/null +++ b/assets/resources/ui/icons/abstractTile_29.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.26", + "importer": "image", + "imported": true, + "uuid": "2833a55b-f13f-4692-92f1-d8a8213855c6", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "2833a55b-f13f-4692-92f1-d8a8213855c6@6c48a", + "displayName": "abstractTile_29", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "repeat", + "wrapModeT": "repeat", + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0, + "isUuid": true, + "imageUuidOrDatabaseUri": "2833a55b-f13f-4692-92f1-d8a8213855c6", + "visible": false + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "2833a55b-f13f-4692-92f1-d8a8213855c6@f9941", + "displayName": "abstractTile_29", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 92, + "height": 80, + "rawWidth": 92, + "rawHeight": 80, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -46, + -40, + 0, + 46, + -40, + 0, + -46, + 40, + 0, + 46, + 40, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 80, + 92, + 80, + 0, + 0, + 92, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -46, + -40, + 0 + ], + "maxPos": [ + 46, + 40, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "2833a55b-f13f-4692-92f1-d8a8213855c6@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "hasAlpha": true, + "type": "sprite-frame", + "fixAlphaTransparencyArtifacts": true, + "redirect": "2833a55b-f13f-4692-92f1-d8a8213855c6@f9941" + } +} diff --git a/assets/resources/ui/icons/abstractTile_30.png b/assets/resources/ui/icons/abstractTile_30.png new file mode 100644 index 0000000..8935664 Binary files /dev/null and b/assets/resources/ui/icons/abstractTile_30.png differ diff --git a/assets/resources/ui/icons/abstractTile_30.png.meta b/assets/resources/ui/icons/abstractTile_30.png.meta new file mode 100644 index 0000000..a674cdb --- /dev/null +++ b/assets/resources/ui/icons/abstractTile_30.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.26", + "importer": "image", + "imported": true, + "uuid": "1d73d268-60d8-4712-8012-d023bbc1cc94", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "1d73d268-60d8-4712-8012-d023bbc1cc94@6c48a", + "displayName": "abstractTile_30", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "repeat", + "wrapModeT": "repeat", + "minfilter": "linear", + "magfilter": "linear", + "mipfilter": "none", + "anisotropy": 0, + "isUuid": true, + "imageUuidOrDatabaseUri": "1d73d268-60d8-4712-8012-d023bbc1cc94", + "visible": false + }, + "ver": "1.0.22", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + }, + "f9941": { + "importer": "sprite-frame", + "uuid": "1d73d268-60d8-4712-8012-d023bbc1cc94@f9941", + "displayName": "abstractTile_30", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimType": "auto", + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 92, + "height": 80, + "rawWidth": 92, + "rawHeight": 80, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -46, + -40, + 0, + 46, + -40, + 0, + -46, + 40, + 0, + 46, + 40, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 80, + 92, + 80, + 0, + 0, + 92, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -46, + -40, + 0 + ], + "maxPos": [ + 46, + 40, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "1d73d268-60d8-4712-8012-d023bbc1cc94@6c48a", + "atlasUuid": "" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "hasAlpha": true, + "type": "sprite-frame", + "fixAlphaTransparencyArtifacts": true, + "redirect": "1d73d268-60d8-4712-8012-d023bbc1cc94@f9941" + } +} diff --git a/assets/scripts/components/ColorSDFAssembler.ts b/assets/scripts/components/ColorSDFAssembler.ts new file mode 100644 index 0000000..1c623d5 --- /dev/null +++ b/assets/scripts/components/ColorSDFAssembler.ts @@ -0,0 +1,173 @@ +import { Color, IAssembler, IRenderData, RenderData, dynamicAtlasManager } from "cc"; +import { GPSpriteSDF } from "./GPSpriteSDF"; +const QUAD_INDICES = Uint16Array.from([0, 1, 2, 1, 3, 2]); + +export const ColorSDFAssembler: IAssembler = { + createData (sprite: GPSpriteSDF) { + const renderData = sprite.requestRenderData(); + renderData.dataLength = 4; + renderData.resize(4, 6); + renderData.chunk.setIndexBuffer(QUAD_INDICES); + return renderData; + }, + + updateRenderData (sprite: GPSpriteSDF) { + const frame = sprite.spriteFrame; + + dynamicAtlasManager.packToDynamicAtlas(sprite, frame); + this.updateUVs(sprite);// dirty need + //this.updateColor(sprite);// dirty need + + const renderData = sprite.renderData; + if (renderData && frame) { + if (renderData.vertDirty) { + this.updateVertexData(sprite); + } + renderData.updateRenderData(sprite, frame); + } + }, + + updateWorldVerts (sprite: GPSpriteSDF, chunk: { vb: any; }) { + const renderData = sprite.renderData!; + const vData = chunk.vb; + + const dataList: IRenderData[] = renderData.data; + const node = sprite.node; + const m = node.worldMatrix; + + const stride = renderData.floatStride; + let offset = 0; + const length = dataList.length; + for (let i = 0; i < length; i++) { + const curData = dataList[i]; + const x = curData.x; + const y = curData.y; + let rhw = m.m03 * x + m.m07 * y + m.m15; + rhw = rhw ? 1 / rhw : 1; + + offset = i * stride; + vData[offset + 0] = (m.m00 * x + m.m04 * y + m.m12) * rhw; + vData[offset + 1] = (m.m01 * x + m.m05 * y + m.m13) * rhw; + vData[offset + 2] = (m.m02 * x + m.m06 * y + m.m14) * rhw; + } + }, + + fillBuffers (sprite: GPSpriteSDF) { + if (sprite === null) { + return; + } + + const renderData = sprite.renderData!; + const chunk = renderData.chunk; + if (sprite["_flagChangedVersion"] !== sprite.node["_flagChangedVersion"] || renderData.vertDirty) { + // const vb = chunk.vertexAccessor.getVertexBuffer(chunk.bufferId); + this.updateWorldVerts(sprite, chunk); + renderData.vertDirty = false; + sprite["_flagChangedVersion"] = sprite.node["_flagChangedVersion"]; + } + + // quick version + const vidOrigin = chunk.vertexOffset; + const meshBuffer = chunk.meshBuffer; + const ib = chunk.meshBuffer.iData; + let indexOffset = meshBuffer.indexOffset; + + const vid = vidOrigin; + + // left bottom + ib[indexOffset++] = vid; + // right bottom + ib[indexOffset++] = vid + 1; + // left top + ib[indexOffset++] = vid + 2; + + // right bottom + ib[indexOffset++] = vid + 1; + // right top + ib[indexOffset++] = vid + 3; + // left top + ib[indexOffset++] = vid + 2; + + // IndexOffset should add 6 when vertices of a rect are visited. + meshBuffer.indexOffset += 6; + // slow version + // renderer.switchBufferAccessor().appendIndices(chunk); + }, + + updateVertexData (sprite: GPSpriteSDF) { + const renderData: RenderData | null = sprite.renderData; + if (!renderData) { + return; + } + + const uiTrans = sprite.node._uiProps.uiTransformComp!; + const dataList: IRenderData[] = renderData.data; + const cw = uiTrans.width; + const ch = uiTrans.height; + const appX = uiTrans.anchorX * cw; + const appY = uiTrans.anchorY * ch; + let l = 0; + let b = 0; + let r = 0; + let t = 0; + + const frame = sprite.spriteFrame!; + const originSize = frame.originalSize; + const ow = originSize.width; + const oh = originSize.height; + const scaleX = cw / ow; + const scaleY = ch / oh; + const trimmedBorder = frame.trimmedBorder; + l = trimmedBorder.x * scaleX - appX; + b = trimmedBorder.z * scaleY - appY; + r = cw + trimmedBorder.y * scaleX - appX; + t = ch + trimmedBorder.w * scaleY - appY; + + + dataList[0].x = l; + dataList[0].y = b; + + dataList[1].x = r; + dataList[1].y = b; + + dataList[2].x = l; + dataList[2].y = t; + + dataList[3].x = r; + dataList[3].y = t; + + renderData.vertDirty = true; + }, + + updateUVs (sprite: GPSpriteSDF) { + if (!sprite.spriteFrame) return; + const renderData = sprite.renderData!; + const vData = renderData.chunk.vb; + const uv = sprite.spriteFrame.uv; + vData[3] = uv[0]; + vData[4] = uv[1]; + vData[12] = uv[2]; + vData[13] = uv[3]; + vData[21] = uv[4]; + vData[22] = uv[5]; + vData[30] = uv[6]; + vData[31] = uv[7]; + ColorSDFAssembler.updateColor(sprite); + }, + + updateColor (sprite: GPSpriteSDF) { + const renderData = sprite.renderData!; + const vData = renderData.chunk.vb; + const uv = sprite.spriteFrame.uv; + + let colorOffset = 5; + sprite.color = new Color(uv[4] * 255, uv[5] * 255, (uv[2] - uv[4]) * 255, (uv[3] - uv[5]) * 255); + + for (let i = 0; i < 4; i++, colorOffset += renderData.floatStride) { + vData[colorOffset] = uv[4]; + vData[colorOffset + 1] = uv[5]; + vData[colorOffset + 2] = uv[2] - uv[4]; + vData[colorOffset + 3] = uv[3] - uv[5]; + } + }, +}; \ No newline at end of file diff --git a/assets/scripts/components/ColorSDFAssembler.ts.meta b/assets/scripts/components/ColorSDFAssembler.ts.meta new file mode 100644 index 0000000..147f0e7 --- /dev/null +++ b/assets/scripts/components/ColorSDFAssembler.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "734f46af-342f-4e45-9f43-f79a31c566e2", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/scripts/components/ColorSDFSprite.ts b/assets/scripts/components/ColorSDFSprite.ts new file mode 100644 index 0000000..a2b9198 --- /dev/null +++ b/assets/scripts/components/ColorSDFSprite.ts @@ -0,0 +1,273 @@ +import { _decorator, cclegacy, Component, InstanceMaterialType, Material, Node, NodeEventType, RenderTexture, Sprite, SpriteAtlas, SpriteFrame, UIRenderer } from 'cc'; +import { BUILD, EDITOR } from 'cc/env'; +import { ColorSDFAssembler } from './ColorSDFAssembler'; +const { ccclass, property ,type} = _decorator; +enum EventType { + SPRITE_FRAME_CHANGED = 'spriteframe-changed', +} +@ccclass('ColorSDFSprite') +export class ColorSDFSprite extends UIRenderer { + // 尺寸模式,可以看枚举原本定义的地方有注释说明 + @property({serializable:true}) + protected _sizeMode = Sprite.SizeMode.TRIMMED; + @type(Sprite.SizeMode) + get sizeMode () { + return this._sizeMode; + } + set sizeMode (value) { + if (this._sizeMode === value) { + return; + } + + this._sizeMode = value; + if (value !== Sprite.SizeMode.CUSTOM) { + this._applySpriteSize(); + } + } + // 图集 + @property({serializable:true}) + protected _atlas: SpriteAtlas | null = null; + @type(SpriteAtlas) + get spriteAtlas () { + return this._atlas; + } + set spriteAtlas (value) { + if (this._atlas === value) { + return; + } + this._atlas = value; + } + + @property({serializable:true}) + protected _spriteFrame: SpriteFrame | null = null; + @type(SpriteFrame) + get spriteFrame () { + return this._spriteFrame; + } + set spriteFrame (value) { + if (this._spriteFrame === value) { + return; + } + + const lastSprite = this._spriteFrame; + this._spriteFrame = value; + this.markForUpdateRenderData(); + this._applySpriteFrame(lastSprite); + if (EDITOR) { + this.node.emit(EventType.SPRITE_FRAME_CHANGED, this); + } + } + + onLoad(): void { + this._flushAssembler(); + } + + public __preload () { + this.changeMaterialForDefine(); + super.__preload(); + + if (EDITOR) { + this._resized(); + this.node.on(NodeEventType.SIZE_CHANGED, this._resized, this); + } + } + + public onEnable () { + super.onEnable(); + + // Force update uv, material define, active material, etc + this._activateMaterial(); + const spriteFrame = this._spriteFrame; + if (spriteFrame) { + this._updateUVs(); + } + } + + public onDestroy () { + if (EDITOR) { + this.node.off(NodeEventType.SIZE_CHANGED, this._resized, this); + } + super.onDestroy(); + } + + /** + * @en + * Quickly switch to other sprite frame in the sprite atlas. + * If there is no atlas, the switch fails. + * + * @zh + * 选取使用精灵图集中的其他精灵。 + * @param name @en Name of the spriteFrame to switch. @zh 要切换的 spriteFrame 名字。 + */ + public changeSpriteFrameFromAtlas (name: string) { + if (!this._atlas) { + console.warn('SpriteAtlas is null.'); + return; + } + const sprite = this._atlas.getSpriteFrame(name); + this.spriteFrame = sprite; + } + + /** + * @deprecated Since v3.7.0, this is an engine private interface that will be removed in the future. + */ + public changeMaterialForDefine () { + let texture; + const lastInstanceMaterialType = this._instanceMaterialType; + if (this._spriteFrame) { + texture = this._spriteFrame.texture; + } + let value = false; + if (texture instanceof cclegacy.TextureBase) { + const format = texture.getPixelFormat(); + value = (format === cclegacy.TextureBase.PixelFormat.RGBA_ETC1 || format === cclegacy.TextureBase.PixelFormat.RGB_A_PVRTC_4BPPV1 || format === cclegacy.TextureBase.PixelFormat.RGB_A_PVRTC_2BPPV1); + } + + if (value) { + this._instanceMaterialType = InstanceMaterialType.USE_ALPHA_SEPARATED; + } else { + this._instanceMaterialType = InstanceMaterialType.ADD_COLOR_AND_TEXTURE; + } + if (lastInstanceMaterialType !== this._instanceMaterialType) { + // this.updateMaterial(); + // d.ts里没有注上这个函数,直接调用会表红。 + this["updateMaterial"](); + } + } + + protected _updateBuiltinMaterial () { + let mat = super._updateBuiltinMaterial(); + if (this.spriteFrame && this.spriteFrame.texture instanceof RenderTexture) { + const defines = { SAMPLE_FROM_RT: true, ...mat.passes[0].defines }; + const renderMat = new Material(); + renderMat.initialize({ + effectAsset: mat.effectAsset, + defines, + }); + mat = renderMat; + } + return mat; + } + + protected _render (render) { + render.commitComp(this, this.renderData, this._spriteFrame, this._assembler, null); + } + + protected _canRender () { + if (!super._canRender()) { + return false; + } + + const spriteFrame = this._spriteFrame; + if (!spriteFrame || !spriteFrame.texture) { + return false; + } + + return true; + } + + protected resetAssembler() { + this._assembler = null; + this._flushAssembler(); + } + protected _flushAssembler () { + const assembler = ColorSDFAssembler; + + if (this._assembler !== assembler) { + this.destroyRenderData(); + this._assembler = assembler; + } + + + if (!this._renderData) { + if (this._assembler && this._assembler.createData) { + this._renderData = this._assembler.createData(this); + this._renderData!.material = this.getRenderMaterial(0); + this.markForUpdateRenderData(); + if (this.spriteFrame) { + this._assembler.updateRenderData(this); + } + this._updateColor(); + } + } + } + + private _applySpriteSize () { + if (this._spriteFrame) { + if (BUILD || !this._spriteFrame.isDefault) { + if (Sprite.SizeMode.RAW === this._sizeMode) { + const size = this._spriteFrame.originalSize; + this.node._uiProps.uiTransformComp!.setContentSize(size); + } else if (Sprite.SizeMode.TRIMMED === this._sizeMode) { + const rect = this._spriteFrame.rect; + this.node._uiProps.uiTransformComp!.setContentSize(rect.width, rect.height); + } + } + this.markForUpdateRenderData(true) + this._assembler.updateRenderData(this); + } + } + + private _resized () { + if (!EDITOR) { + return; + } + + if (this._spriteFrame) { + const actualSize = this.node._uiProps.uiTransformComp!.contentSize; + let expectedW = actualSize.width; + let expectedH = actualSize.height; + if (this._sizeMode === Sprite.SizeMode.RAW) { + const size = this._spriteFrame.originalSize; + expectedW = size.width; + expectedH = size.height; + } else if (this._sizeMode === Sprite.SizeMode.TRIMMED) { + const rect = this._spriteFrame.rect; + expectedW = rect.width; + expectedH = rect.height; + } + + if (expectedW !== actualSize.width || expectedH !== actualSize.height) { + this._sizeMode = Sprite.SizeMode.CUSTOM; + } + } + } + + private _activateMaterial () { + const spriteFrame = this._spriteFrame; + const material = this.getRenderMaterial(0); + if (spriteFrame) { + if (material) { + this.markForUpdateRenderData(); + } + } + + if (this.renderData) { + this.renderData.material = material; + } + } + + private _updateUVs () { + if (this._assembler) { + this._assembler.updateUVs(this); + } + } + + private _applySpriteFrame (oldFrame: SpriteFrame | null) { + const spriteFrame = this._spriteFrame; + + let textureChanged = false; + if (spriteFrame) { + if (!oldFrame || oldFrame.texture !== spriteFrame.texture) { + textureChanged = true; + } + if (textureChanged) { + if (this.renderData) this.renderData.textureDirty = true; + this.changeMaterialForDefine(); + } + this._applySpriteSize(); + } + } +} + + diff --git a/assets/scripts/components/ColorSDFSprite.ts.meta b/assets/scripts/components/ColorSDFSprite.ts.meta new file mode 100644 index 0000000..cb7fc2f --- /dev/null +++ b/assets/scripts/components/ColorSDFSprite.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "6845dfbf-3532-43ac-ac91-2813b6983882", + "files": [], + "subMetas": {}, + "userData": {} +}