සැකසීම
යාවත්කාලීන කරන්න!පින්තූර 4096x4096!
වැඩසටහන් දෙක එකට එකතු කිරීමෙන් මම මගේ දෙවන පෝස්ටය මෙයට ඒකාබද්ධ කළෙමි.
තෝරාගත් පින්තූරවල සම්පූර්ණ එකතුවක් ඩ්රොප්බොක්ස් හි සොයාගත හැකිය .(සටහන: ඩ්රොප්බොක්ස් 4096x4096 පින්තූර සඳහා පෙරදසුන් ජනනය කළ නොහැක; ඒවා ක්ලික් කර "බාගන්න" ක්ලික් කරන්න).
ඔබ මේ දෙස එක බැල්මක් පමණක් බැලුවහොත් (ටයිල් කළ හැකි)! මෙන්න එය පරිමාණය කර ඇත (සහ තවත් බොහෝ පහතින්), මුල් 2048x1024:
මෙම වැඩසටහන ක්රියාත්මක වන්නේ වර්ණ කියුබයේ අහඹු ලෙස තෝරාගත් ස්ථාන වලින් ගමන් කිරීමෙන් පසුව රූපයේ අහඹු ලෙස තෝරාගත් මාර්ගවලට ඒවා ඇද ගැනීමෙනි. හැකියාවන් ගොඩක් තිබේ. වින්යාසගත කළ හැකි විකල්ප:
- වර්ණ කියුබ් මාර්ගයේ උපරිම දිග.
- වර්ණ කියුබ් හරහා ගත යුතු උපරිම පියවර (විශාල අගයන් විශාල විචල්යතාවයක් ඇති කරයි, නමුත් දේවල් තද වන විට අවසානය දක්වා කුඩා මාර්ග ගණන අවම කරන්න).
- රූපය ටයිල් කිරීම.
- දැනට රූප මාර්ග ආකාර දෙකක් ඇත:
- ප්රකාරය 1 (මෙම මුල් පෝස්ටයේ මාදිලිය): රූපයේ භාවිතයට නොගත් පික්සෙල් සමූහයක් සොයාගෙන එම කොටස වෙත යොමු කරයි. බ්ලොක් අහඹු ලෙස ස්ථානගත කළ හැකිය, නැතහොත් වමේ සිට දකුණට ඇණවුම් කළ හැකිය.
- ප්රකාරය 2 (මගේ දෙවන පෝස්ටයේ මා මෙයට ඒකාබද්ධ කළ ආකාරය): රූපයේ අහඹු ආරම්භක ලක්ෂ්යයක් තෝරාගෙන භාවිතයට නොගත් පික්සෙල් හරහා ගමන් කරයි; පාවිච්චි කළ පික්සෙල් වටා ගමන් කළ හැකිය. මෙම මාදිලිය සඳහා විකල්ප:
- ඇවිදීමට අවශ්ය දිශාවන් (විකලාංග, විකර්ණ හෝ දෙකම).
- එක් එක් පියවරෙන් පසු දිශාව වෙනස් කළ යුතුද නැද්ද යන්න (දැනට ඔරලෝසුවක නමුත් කේතය නම්යශීලී වේ), නැතහොත් වාඩිලා ගත් පික්සෙල් හමු වූ විට පමණක් දිශාව වෙනස් කිරීම ..
- දිශාව වෙනස් කිරීමේ අනුපිළිවෙල මාරු කිරීමේ විකල්පය (ඔරලෝසුව වෙනුවට).
එය 4096x4096 දක්වා සියලුම ප්රමාණ සඳහා ක්රියා කරයි.
සම්පූර්ණ සැකසුම් සටහන මෙහි සොයාගත හැකිය: Tracer.zip
අවකාශය ඉතිරි කර ගැනීම සඳහා මම සියලුම ලිපිගොනු එකම කේත බ්ලොක් එකක අලවා ඇත (සියල්ලම එක් ගොනුවක වුවද එය තවමත් වලංගු සටහනකි). ඔබට පෙරසිටර වලින් එකක් භාවිතා කිරීමට අවශ්ය නම්, gPreset
පැවරුමේ දර්ශකය වෙනස් කරන්න . ඔබ මෙය සැකසුම් තුළ r
ක්රියාත්මක කරන්නේ නම් එය නව රූපයක් ජනනය කිරීම සඳහා ක්රියාත්මක වන අතරතුර ඔබන්න .
- යාවත්කාලීන 1: පළමු භාවිතයට නොගත් වර්ණය / පික්සෙල් නිරීක්ෂණය කිරීමට ප්රශස්ත කේතය සහ දන්නා පාවිච්චි කළ පික්සෙල් හරහා සෙවීම නොවේ; 2048x1024 පරම්පරාවේ කාලය මිනිත්තු 10-30 සිට තත්පර 15 දක්වා අඩු කළ අතර 4096x4096 පැය 1-3 සිට මිනිත්තු 1 දක්වා අඩු විය. පහත දැක්වෙන බොක්ස් ප්රභවය සහ ප්රභවය යාවත්කාලීන කරන්න.
- යාවත්කාලීන 2: පින්තූර 4096x4096 ජනනය වීම වළක්වන ස්ථාවර දෝෂයකි.
final int BITS = 5; // Set to 5, 6, 7, or 8!
// Preset (String name, int colorBits, int maxCubePath, int maxCubeStep, int imageMode, int imageOpts)
final Preset[] PRESETS = new Preset[] {
// 0
new Preset("flowers", BITS, 8*32*32, 2, ImageRect.MODE2, ImageRect.ALL_CW | ImageRect.CHANGE_DIRS),
new Preset("diamonds", BITS, 2*32*32, 2, ImageRect.MODE2, ImageRect.ORTHO_CW | ImageRect.CHANGE_DIRS),
new Preset("diamondtile", BITS, 2*32*32, 2, ImageRect.MODE2, ImageRect.ORTHO_CW | ImageRect.CHANGE_DIRS | ImageRect.WRAP),
new Preset("shards", BITS, 2*32*32, 2, ImageRect.MODE2, ImageRect.ALL_CW | ImageRect.CHANGE_DIRS | ImageRect.SHUFFLE_DIRS),
new Preset("bigdiamonds", BITS, 100000, 6, ImageRect.MODE2, ImageRect.ORTHO_CW | ImageRect.CHANGE_DIRS),
// 5
new Preset("bigtile", BITS, 100000, 6, ImageRect.MODE2, ImageRect.ORTHO_CW | ImageRect.CHANGE_DIRS | ImageRect.WRAP),
new Preset("boxes", BITS, 32*32, 2, ImageRect.MODE2, ImageRect.ORTHO_CW),
new Preset("giftwrap", BITS, 32*32, 2, ImageRect.MODE2, ImageRect.ORTHO_CW | ImageRect.WRAP),
new Preset("diagover", BITS, 32*32, 2, ImageRect.MODE2, ImageRect.DIAG_CW),
new Preset("boxfade", BITS, 32*32, 2, ImageRect.MODE2, ImageRect.DIAG_CW | ImageRect.CHANGE_DIRS),
// 10
new Preset("randlimit", BITS, 512, 2, ImageRect.MODE1, ImageRect.RANDOM_BLOCKS),
new Preset("ordlimit", BITS, 64, 2, ImageRect.MODE1, 0),
new Preset("randtile", BITS, 2048, 3, ImageRect.MODE1, ImageRect.RANDOM_BLOCKS | ImageRect.WRAP),
new Preset("randnolimit", BITS, 1000000, 1, ImageRect.MODE1, ImageRect.RANDOM_BLOCKS),
new Preset("ordnolimit", BITS, 1000000, 1, ImageRect.MODE1, 0)
};
PGraphics gFrameBuffer;
Preset gPreset = PRESETS[2];
void generate () {
ColorCube cube = gPreset.createCube();
ImageRect image = gPreset.createImage();
gFrameBuffer = createGraphics(gPreset.getWidth(), gPreset.getHeight(), JAVA2D);
gFrameBuffer.noSmooth();
gFrameBuffer.beginDraw();
while (!cube.isExhausted())
image.drawPath(cube.nextPath(), gFrameBuffer);
gFrameBuffer.endDraw();
if (gPreset.getName() != null)
gFrameBuffer.save(gPreset.getName() + "_" + gPreset.getCubeSize() + ".png");
//image.verifyExhausted();
//cube.verifyExhausted();
}
void setup () {
size(gPreset.getDisplayWidth(), gPreset.getDisplayHeight());
noSmooth();
generate();
}
void keyPressed () {
if (key == 'r' || key == 'R')
generate();
}
boolean autogen = false;
int autop = 0;
int autob = 5;
void draw () {
if (autogen) {
gPreset = new Preset(PRESETS[autop], autob);
generate();
if ((++ autop) >= PRESETS.length) {
autop = 0;
if ((++ autob) > 8)
autogen = false;
}
}
if (gPreset.isWrapped()) {
int hw = width/2;
int hh = height/2;
image(gFrameBuffer, 0, 0, hw, hh);
image(gFrameBuffer, hw, 0, hw, hh);
image(gFrameBuffer, 0, hh, hw, hh);
image(gFrameBuffer, hw, hh, hw, hh);
} else {
image(gFrameBuffer, 0, 0, width, height);
}
}
static class ColorStep {
final int r, g, b;
ColorStep (int rr, int gg, int bb) { r=rr; g=gg; b=bb; }
}
class ColorCube {
final boolean[] used;
final int size;
final int maxPathLength;
final ArrayList<ColorStep> allowedSteps = new ArrayList<ColorStep>();
int remaining;
int pathr = -1, pathg, pathb;
int firstUnused = 0;
ColorCube (int size, int maxPathLength, int maxStep) {
this.used = new boolean[size*size*size];
this.remaining = size * size * size;
this.size = size;
this.maxPathLength = maxPathLength;
for (int r = -maxStep; r <= maxStep; ++ r)
for (int g = -maxStep; g <= maxStep; ++ g)
for (int b = -maxStep; b <= maxStep; ++ b)
if (r != 0 && g != 0 && b != 0)
allowedSteps.add(new ColorStep(r, g, b));
}
boolean isExhausted () {
println(remaining);
return remaining <= 0;
}
boolean isUsed (int r, int g, int b) {
if (r < 0 || r >= size || g < 0 || g >= size || b < 0 || b >= size)
return true;
else
return used[(r*size+g)*size+b];
}
void setUsed (int r, int g, int b) {
used[(r*size+g)*size+b] = true;
}
int nextColor () {
if (pathr == -1) { // Need to start a new path.
// Limit to 50 attempts at random picks; things get tight near end.
for (int n = 0; n < 50 && pathr == -1; ++ n) {
int r = (int)random(size);
int g = (int)random(size);
int b = (int)random(size);
if (!isUsed(r, g, b)) {
pathr = r;
pathg = g;
pathb = b;
}
}
// If we didn't find one randomly, just search for one.
if (pathr == -1) {
final int sizesq = size*size;
final int sizemask = size - 1;
for (int rgb = firstUnused; rgb < size*size*size; ++ rgb) {
pathr = (rgb/sizesq)&sizemask;//(rgb >> 10) & 31;
pathg = (rgb/size)&sizemask;//(rgb >> 5) & 31;
pathb = rgb&sizemask;//rgb & 31;
if (!used[rgb]) {
firstUnused = rgb;
break;
}
}
}
assert(pathr != -1);
} else { // Continue moving on existing path.
// Find valid next path steps.
ArrayList<ColorStep> possibleSteps = new ArrayList<ColorStep>();
for (ColorStep step:allowedSteps)
if (!isUsed(pathr+step.r, pathg+step.g, pathb+step.b))
possibleSteps.add(step);
// If there are none end this path.
if (possibleSteps.isEmpty()) {
pathr = -1;
return -1;
}
// Otherwise pick a random step and move there.
ColorStep s = possibleSteps.get((int)random(possibleSteps.size()));
pathr += s.r;
pathg += s.g;
pathb += s.b;
}
setUsed(pathr, pathg, pathb);
return 0x00FFFFFF & color(pathr * (256/size), pathg * (256/size), pathb * (256/size));
}
ArrayList<Integer> nextPath () {
ArrayList<Integer> path = new ArrayList<Integer>();
int rgb;
while ((rgb = nextColor()) != -1) {
path.add(0xFF000000 | rgb);
if (path.size() >= maxPathLength) {
pathr = -1;
break;
}
}
remaining -= path.size();
//assert(!path.isEmpty());
if (path.isEmpty()) {
println("ERROR: empty path.");
verifyExhausted();
}
return path;
}
void verifyExhausted () {
final int sizesq = size*size;
final int sizemask = size - 1;
for (int rgb = 0; rgb < size*size*size; ++ rgb) {
if (!used[rgb]) {
int r = (rgb/sizesq)&sizemask;
int g = (rgb/size)&sizemask;
int b = rgb&sizemask;
println("UNUSED COLOR: " + r + " " + g + " " + b);
}
}
if (remaining != 0)
println("REMAINING COLOR COUNT IS OFF: " + remaining);
}
}
static class ImageStep {
final int x;
final int y;
ImageStep (int xx, int yy) { x=xx; y=yy; }
}
static int nmod (int a, int b) {
return (a % b + b) % b;
}
class ImageRect {
// for mode 1:
// one of ORTHO_CW, DIAG_CW, ALL_CW
// or'd with flags CHANGE_DIRS
static final int ORTHO_CW = 0;
static final int DIAG_CW = 1;
static final int ALL_CW = 2;
static final int DIR_MASK = 0x03;
static final int CHANGE_DIRS = (1<<5);
static final int SHUFFLE_DIRS = (1<<6);
// for mode 2:
static final int RANDOM_BLOCKS = (1<<0);
// for both modes:
static final int WRAP = (1<<16);
static final int MODE1 = 0;
static final int MODE2 = 1;
final boolean[] used;
final int width;
final int height;
final boolean changeDir;
final int drawMode;
final boolean randomBlocks;
final boolean wrap;
final ArrayList<ImageStep> allowedSteps = new ArrayList<ImageStep>();
// X/Y are tracked instead of index to preserve original unoptimized mode 1 behavior
// which does column-major searches instead of row-major.
int firstUnusedX = 0;
int firstUnusedY = 0;
ImageRect (int width, int height, int drawMode, int drawOpts) {
boolean myRandomBlocks = false, myChangeDir = false;
this.used = new boolean[width*height];
this.width = width;
this.height = height;
this.drawMode = drawMode;
this.wrap = (drawOpts & WRAP) != 0;
if (drawMode == MODE1) {
myRandomBlocks = (drawOpts & RANDOM_BLOCKS) != 0;
} else if (drawMode == MODE2) {
myChangeDir = (drawOpts & CHANGE_DIRS) != 0;
switch (drawOpts & DIR_MASK) {
case ORTHO_CW:
allowedSteps.add(new ImageStep(1, 0));
allowedSteps.add(new ImageStep(0, -1));
allowedSteps.add(new ImageStep(-1, 0));
allowedSteps.add(new ImageStep(0, 1));
break;
case DIAG_CW:
allowedSteps.add(new ImageStep(1, -1));
allowedSteps.add(new ImageStep(-1, -1));
allowedSteps.add(new ImageStep(-1, 1));
allowedSteps.add(new ImageStep(1, 1));
break;
case ALL_CW:
allowedSteps.add(new ImageStep(1, 0));
allowedSteps.add(new ImageStep(1, -1));
allowedSteps.add(new ImageStep(0, -1));
allowedSteps.add(new ImageStep(-1, -1));
allowedSteps.add(new ImageStep(-1, 0));
allowedSteps.add(new ImageStep(-1, 1));
allowedSteps.add(new ImageStep(0, 1));
allowedSteps.add(new ImageStep(1, 1));
break;
}
if ((drawOpts & SHUFFLE_DIRS) != 0)
java.util.Collections.shuffle(allowedSteps);
}
this.randomBlocks = myRandomBlocks;
this.changeDir = myChangeDir;
}
boolean isUsed (int x, int y) {
if (wrap) {
x = nmod(x, width);
y = nmod(y, height);
}
if (x < 0 || x >= width || y < 0 || y >= height)
return true;
else
return used[y*width+x];
}
boolean isUsed (int x, int y, ImageStep d) {
return isUsed(x + d.x, y + d.y);
}
void setUsed (int x, int y) {
if (wrap) {
x = nmod(x, width);
y = nmod(y, height);
}
used[y*width+x] = true;
}
boolean isBlockFree (int x, int y, int w, int h) {
for (int yy = y; yy < y + h; ++ yy)
for (int xx = x; xx < x + w; ++ xx)
if (isUsed(xx, yy))
return false;
return true;
}
void drawPath (ArrayList<Integer> path, PGraphics buffer) {
if (drawMode == MODE1)
drawPath1(path, buffer);
else if (drawMode == MODE2)
drawPath2(path, buffer);
}
void drawPath1 (ArrayList<Integer> path, PGraphics buffer) {
int w = (int)(sqrt(path.size()) + 0.5);
if (w < 1) w = 1; else if (w > width) w = width;
int h = (path.size() + w - 1) / w;
int x = -1, y = -1;
int woff = wrap ? 0 : (1 - w);
int hoff = wrap ? 0 : (1 - h);
// Try up to 50 times to find a random location for block.
if (randomBlocks) {
for (int n = 0; n < 50 && x == -1; ++ n) {
int xx = (int)random(width + woff);
int yy = (int)random(height + hoff);
if (isBlockFree(xx, yy, w, h)) {
x = xx;
y = yy;
}
}
}
// If random choice failed just search for one.
int starty = firstUnusedY;
for (int xx = firstUnusedX; xx < width + woff && x == -1; ++ xx) {
for (int yy = starty; yy < height + hoff && x == -1; ++ yy) {
if (isBlockFree(xx, yy, w, h)) {
firstUnusedX = x = xx;
firstUnusedY = y = yy;
}
}
starty = 0;
}
if (x != -1) {
for (int xx = x, pathn = 0; xx < x + w && pathn < path.size(); ++ xx)
for (int yy = y; yy < y + h && pathn < path.size(); ++ yy, ++ pathn) {
buffer.set(nmod(xx, width), nmod(yy, height), path.get(pathn));
setUsed(xx, yy);
}
} else {
for (int yy = 0, pathn = 0; yy < height && pathn < path.size(); ++ yy)
for (int xx = 0; xx < width && pathn < path.size(); ++ xx)
if (!isUsed(xx, yy)) {
buffer.set(nmod(xx, width), nmod(yy, height), path.get(pathn));
setUsed(xx, yy);
++ pathn;
}
}
}
void drawPath2 (ArrayList<Integer> path, PGraphics buffer) {
int pathn = 0;
while (pathn < path.size()) {
int x = -1, y = -1;
// pick a random location in the image (try up to 100 times before falling back on search)
for (int n = 0; n < 100 && x == -1; ++ n) {
int xx = (int)random(width);
int yy = (int)random(height);
if (!isUsed(xx, yy)) {
x = xx;
y = yy;
}
}
// original:
//for (int yy = 0; yy < height && x == -1; ++ yy)
// for (int xx = 0; xx < width && x == -1; ++ xx)
// if (!isUsed(xx, yy)) {
// x = xx;
// y = yy;
// }
// optimized:
if (x == -1) {
for (int n = firstUnusedY * width + firstUnusedX; n < used.length; ++ n) {
if (!used[n]) {
firstUnusedX = x = (n % width);
firstUnusedY = y = (n / width);
break;
}
}
}
// start drawing
int dir = 0;
while (pathn < path.size()) {
buffer.set(nmod(x, width), nmod(y, height), path.get(pathn ++));
setUsed(x, y);
int diro;
for (diro = 0; diro < allowedSteps.size(); ++ diro) {
int diri = (dir + diro) % allowedSteps.size();
ImageStep step = allowedSteps.get(diri);
if (!isUsed(x, y, step)) {
dir = diri;
x += step.x;
y += step.y;
break;
}
}
if (diro == allowedSteps.size())
break;
if (changeDir)
++ dir;
}
}
}
void verifyExhausted () {
for (int n = 0; n < used.length; ++ n)
if (!used[n])
println("UNUSED IMAGE PIXEL: " + (n%width) + " " + (n/width));
}
}
class Preset {
final String name;
final int cubeSize;
final int maxCubePath;
final int maxCubeStep;
final int imageWidth;
final int imageHeight;
final int imageMode;
final int imageOpts;
final int displayScale;
Preset (Preset p, int colorBits) {
this(p.name, colorBits, p.maxCubePath, p.maxCubeStep, p.imageMode, p.imageOpts);
}
Preset (String name, int colorBits, int maxCubePath, int maxCubeStep, int imageMode, int imageOpts) {
final int csize[] = new int[]{ 32, 64, 128, 256 };
final int iwidth[] = new int[]{ 256, 512, 2048, 4096 };
final int iheight[] = new int[]{ 128, 512, 1024, 4096 };
final int dscale[] = new int[]{ 2, 1, 1, 1 };
this.name = name;
this.cubeSize = csize[colorBits - 5];
this.maxCubePath = maxCubePath;
this.maxCubeStep = maxCubeStep;
this.imageWidth = iwidth[colorBits - 5];
this.imageHeight = iheight[colorBits - 5];
this.imageMode = imageMode;
this.imageOpts = imageOpts;
this.displayScale = dscale[colorBits - 5];
}
ColorCube createCube () {
return new ColorCube(cubeSize, maxCubePath, maxCubeStep);
}
ImageRect createImage () {
return new ImageRect(imageWidth, imageHeight, imageMode, imageOpts);
}
int getWidth () {
return imageWidth;
}
int getHeight () {
return imageHeight;
}
int getDisplayWidth () {
return imageWidth * displayScale * (isWrapped() ? 2 : 1);
}
int getDisplayHeight () {
return imageHeight * displayScale * (isWrapped() ? 2 : 1);
}
String getName () {
return name;
}
int getCubeSize () {
return cubeSize;
}
boolean isWrapped () {
return (imageOpts & ImageRect.WRAP) != 0;
}
}
මෙන්න මම කැමති පින්තූර 256x128 සම්පූර්ණ කට්ටලයක්:
ප්රකාරය 1:
මුල් කට්ටලයෙන් මගේ ප්රියතමය (max_path_length = 512, path_step = 2, අහඹු, දර්ශනය වූ 2x, සබැඳිය 256x128 ):
අනෙක් ඒවා (වම් දෙක ඇණවුම් කර ඇත, දකුණට අහඹු දෙකක්, ඉහළ මාර්ග දෙකේ සීමිත, පහළ දෙක අසීමිත):
මෙය ටයිල් කළ හැකිය:
මාතය 2:
මේවා ටයිල් කළ හැකිය:
512x512 වරණයන්:
ටයිල් කළ හැකි දියමන්ති, මාදිලි 2 සිට මගේ ප්රියතම; පවතින වස්තූන් වටා මාර්ග ගමන් කරන ආකාරය ඔබට මෙයින් දැක ගත හැකිය:
ටයිල් කළ හැකි විශාල මාර්ග පියවර සහ උපරිම මාර්ග දිග:
සසම්භාවී මාදිලිය 1, ටයිල් කළ හැකි:
තවත් තේරීම්:
512x512 විදැහුම් සියල්ලම ඩ්රොප්බොක්ස් ෆෝල්ඩරයේ (* _64.png) සොයාගත හැකිය.
2048x1024 සහ 4096x4096:
මේවා කාවැද්දීමට තරම් විශාල වන අතර මා සොයාගත් සියලුම රූප ධාරක ඒවා 1600x1200 දක්වා පහත වැටේ. මම දැනට පින්තූර 4096x4096 කට්ටලයක් ඉදිරිපත් කරමින් සිටිමි, එබැවින් තවත් ඉක්මනින් ලබා ගත හැක. මෙහි ඇති සියලුම සබැඳි ඇතුළත් කරනවා වෙනුවට, ඒවා ඩ්රොප්බොක්ස් ෆෝල්ඩරයේ පරීක්ෂා කර බලන්න (* _128.png සහ * _256.png, සටහන: 4096x4096 ඒවා ඩ්රොප්බොක්ස් පෙරදසුනට වඩා විශාලයි, "බාගන්න" ක්ලික් කරන්න). මෙන්න මගේ ප්රියතමයන් කිහිපයක්:
2048x1024 විශාල ටයිල් කළ හැකි දියමන්ති (මෙම ලිපිය ආරම්භයේදී මා සම්බන්ධ කළ එකම)
2048x1024 දියමන්ති (මම මේකට කැමතියි!), පරිමාණය:
4096x4096 විශාල ටයිල් කළ හැකි දියමන්ති (අවසාන වශයෙන්, ඩ්රොප්බොක්ස් සබැඳියේ 'බාගත කරන්න' ක්ලික් කරන්න; එය ඔවුන්ගේ පෙරදසුනට වඩා විශාලය), පරිමාණයෙන් පහළට:
4096x4096 අහඹු මාදිලිය 1 :
4096x4096 තවත් සිසිල් එකක්
යාවත්කාලීන කිරීම: 2048x1024 පෙර සැකසුම් රූප කට්ටලය අවසන් කර ඇති අතර එය ඩ්රොප්බොක්ස් තුළ ඇත. 4096x4096 කට්ටලය පැයක් ඇතුළත කළ යුතුය.
හොඳ ඒවා ටොන් ගණනක් ඇත, කුමන ඒවා පළ කළ යුතුද යන්න තෝරා ගැනීමට මට ඉතා අපහසු වේ, එබැවින් කරුණාකර ෆෝල්ඩරයේ සබැඳිය බලන්න!