احتواء السماء المرصعة بالنجوم على WebGL في 1009 بايت من JavaScript

هناك شيئان يملأان الروح دائمًا بمفاجأة وتوقير جديدان أقوى من أي وقت مضى ، وكلما فكرنا في الأمر أكثر فأكثر - هذه هي السماء المرصعة بالنجوم فوقي والقانون الأخلاقي في نفسي. عمانوئيل كانت

JS1k هي مسابقة سنوية حيث تحتاج إلى استيعاب عرض توضيحي أو لعبة أو أي شيء ، في 1024 حرفًا في JavaScript. هذا العام ، احتل العرض التجريبي بلدي المركز الرابع (حتى الثالث لم يكن هناك ما يكفي من نقطتين). يمكنك مشاهدة العرض التوضيحي على موقع JS1k . من الذي لا يفتح أو لا يعمل ، يجب أن يبدو هكذا:



شفرة المصدر المصغرة والكاملة تقع على جيثب . وتحت القصاصة ، يوجد تحليل لكيفية إجراء جافا سكريبت في هذه المسابقات.


Diskalaymer


الجمال الرئيسي للعرض التجريبي هو تظليل جزء من بابلو رومان أندريولي. بابلو هو فنان يعمل مع صور النمطي هندسي متكرر ، وفي منتدى فركتومال فورومفوراتس يعطي بعض تفاصيل الحسابات. كانت مهمتي هي حزمة تظليل و WebGL رمز 1024 بايت.


تهيئة WebGL


يوفر مجمّع JS1k في بداية العرض التوضيحي سياق WebGL في المتغير العام g . على الرغم من ذلك ، فإن العمل مع WebGL أمر مطول للغاية. على سبيل المثال ، لإضافة تظليل رأس إلى برنامج ، هناك حاجة إلى 159 حرفًا:


// Define a new program p=g.createProgram(); // Basic vertex shader s=g.createShader(VERTEX_SHADER); g.shaderSource(s,"attribute vec2 p;void main(){gl_Position=vec4(p,0,1);}"); // Compile and attach it to the program g.compileShader(s); g.attachShader(p,s); 

لحل هذه المشكلة ، تستخدم جميع حلول JS1k في السنوات القليلة الماضية خدعة مع مرادفات الوظائف:


 for(i in g){ g[i[0] + i[6]] = g[i]; } 

تضيف الحلقة مرادفًا لكل وظيفة (ولأي عضو) في سياق WebGL ، والذي يتكون من أول و 7 أحرف. على سبيل المثال ، يصبح c reate P rogram cP ، s hader S ource - sS ، إلخ. بالإضافة إلى ذلك ، عند تأطير كل الشفرة with(g) البنية with(g) (والتي لا يمكن استخدامها في هذه المشاريع) ، نحصل على:


 with(g){ p=cP(); sS(s=cS(35633),'attribute vec2 p;void main(){gl_Position=vec4(p,1,1);}'); ce(s); aS(p,s); } 

تصغير شادر


يأخذ التظليل الأصلي 1100 حرفًا. الاختصارات الرئيسية: إزالة المتغيرات غير الضرورية ، والجمع بين الأجزاء المتشابهة. بعد كل شيء ، مررت الرمز من خلال minifier عبر الإنترنت . نتيجة لذلك ، بقي أكثر من 500 بايت من التظليل.


JSCrush


JSCrush هو المعيار الفعلي لضغط الرمز في مثل هذه المسابقات. الأداة المساعدة تحول التعليمات البرمجية إلى التسلسل التالي تقريبًا:


_ = '(i a.style = ...
 _='(i a.style="widMj%;hEjvh;:left",g)g[i[0]+i[6]]=g[i];wiMO.u=g.G1f,x=y=k=g)p=cP(35633"tribute 2 p gl_Posit=4?FN"precis mediump ;G Zt,a,x,y Uf`ord.rg/64!-.f.=a;Zc=+xz,v=+yz;m2 m$cc-cc)s$vv-vv)fJf#Ur`Q,,r+`t*2.,t,-2.rJr#Zg=.1,b=Q;Ui`!Kl=Rl<2Rl++){Uo=r+f*;oQ)-mod(o,2.))Ze,n=e=!;Kd=Rd<2Rd++)oo)/dot(o,o)-3,n+o)-ee=oif(l>6)Q-max(!,.3-i+=b+g,g,g)*n*5*b;.73;g+=.1;}i=mix(i)i,.85lor=4(i*.01.lo?ug?bfO=34962,cB()eV(0vA(2,5120bDO,Tw Int8Array([|,|]35044o=,(Lt@-oa@TrHE/TrWidMx@xy@ydr(6,3requestAnimFrame(L)})(down=upk^=1},movek&&(xX,yY)};),3=funct(e){uOf?,"flo}@ce(saS?,slengM(onmouse ;void ma(){Tw De/1e5);incos(for=abs(gl_FragCo,1g*(sS(s=cS(n*n*.001at.5vecionb*=s(=e.page0,!0.#.r=s;$=m2(?(p@"EeightGunimJ.rm;K(t MthO(gQ1.R0;TneU Z `=j:100z/50!|-3';for(Y in $='|zj`ZUTRQOMKJGE@?$#! ')with(_.split($[Y]))_=join(pop());eval(_) 

يمكن عرض مبدأ JSCrush بصريًا في أداة تحويل الرمز العكسي . أو اقرأ بالتفصيل في المقال . بشكل عام ، يتم ترميز هذا باستخدام قاموس:


  1. نجد حرفًا غير مستخدم في الكود
  2. نجد الأجزاء المكررة في الشفرة التي نستبدلها بالحرف من الفقرة الأولى
  3. استبدال السلسلة بحرف
  4. كرر 1-3 حتى تصبح النتيجة أصغر من الكود المصدري.

الأمثل


بعد كل العمليات ، لا يزال أمامي حوالي 30 حرفًا ، والتي يمكن استخدامها لتحسين الأداء. عند تحميل العرض التوضيحي ، يمكنك تحديد حجم اللوحة القماشية: ملء الشاشة أو الحجم الثابت. يعد التشغيل في وضع ملء الشاشة جميلًا ، ولكن يتم استدعاء تظليل الجزء لكل بكسل ويعمل ببطء. كان الحل هو طلب حجم ثابت من قماش JS1k (اخترت 640 × 640) ، ثم زيادته إلى وضع ملء الشاشة في الكود:


 a.style='width:100%;height:100vh;float:left'; 

بعد ذلك ، تشغل الصورة الشاشة بأكملها ، لكن يتم تنفيذ التظليل فقط لكل بكسل بحجم اللوحة الأصلية.

Source: https://habr.com/ru/post/ar462115/


All Articles