मेरा पेरलिन शोर "अवरुद्ध" क्यों दिखता है?


21

मैंने सिर्फ थ्योरी (निम्नलिखित flafla2.github.io/2014/08/09/perlinnoise.html) का उपयोग करके खुद के द्वारा पेरलिन शोर को लागू करने की कोशिश की । दुर्भाग्य से मैं "मूल" पेरलिन शोर के रूप को प्राप्त करने में असमर्थ था।

नीचे दिए गए कोड पेरलिन शोर के एक अवरुद्ध संस्करण का क्या कारण है?

मुझे कोड में क्या सुधार / परिवर्तन करना चाहिए ताकि यह कलाकृतियों के बिना पेर्लिन शोर का प्रतिपादन करे?

मुझे संदेह है कि जिस तरह से मैं प्रक्षेपित करता हूं या gradsवेक्टर में समस्या होती है। gradsसभी 4 पास के जाली अंक के लिए - वेक्टर (जाली बिंदु के लिए यादृच्छिक वेक्टर) और (आकार वेक्टर) के डॉट उत्पाद शामिल हैं। (यादृच्छिक और आकार वाले वैक्टर बहुत पहले लिंक में वर्णित हैं।)

GLSL सैंडबॉक्स: http://glslsandbox.com/e#32663.0

शोर में कलाकृतियाँ

float fade(float t) { return t * t * t * (t * (t * 6. - 15.) + 10.); }
vec2 smooth(vec2 x) { return vec2(fade(x.x), fade(x.y)); }

vec2 hash(vec2 co) {
    return fract (vec2(.5654654, -.65465) * dot (vec2(.654, 57.4), co));
}

float perlinNoise(vec2 uv) {
    vec2 PT  = floor(uv);
    vec2 pt  = fract(uv);
    vec2 mmpt= smooth(pt);

    vec4 grads = vec4(
        dot(hash(PT + vec2(.0, 1.)), pt-vec2(.0, 1.)),   dot(hash(PT + vec2(1., 1.)), pt-vec2(1., 1.)),
        dot(hash(PT + vec2(.0, .0)), pt-vec2(.0, .0)),   dot(hash(PT + vec2(1., .0)), pt-vec2(1., 0.))
    );

    return 5.*mix (mix (grads.z, grads.w, mmpt.x), mix (grads.x, grads.y, mmpt.x), mmpt.y);
}

float fbm(vec2 uv) {
    float finalNoise = 0.;
    finalNoise += .50000*perlinNoise(2.*uv);
    finalNoise += .25000*perlinNoise(4.*uv);
    finalNoise += .12500*perlinNoise(8.*uv);
    finalNoise += .06250*perlinNoise(16.*uv);
    finalNoise += .03125*perlinNoise(32.*uv);

    return finalNoise;
}

void main() {
    vec2 position = gl_FragCoord.xy / resolution.y;
    gl_FragColor = vec4( vec3( fbm(3.*position) ), 1.0 );
}

जवाबों:


24

प्रक्षेप ठीक दिखता है। यहाँ मुख्य समस्या यह है कि आप जिस हैश फ़ंक्शन का उपयोग कर रहे हैं वह बहुत अच्छा नहीं है। अगर मैं सिर्फ एक सप्तक को देखता हूं, और आउटपुट के द्वारा हैश परिणाम की कल्पना करता hash(PT).xहूं, तो मुझे कुछ ऐसा मिलता है:

खराब हैश फ़ंक्शन

यह ग्रिड ग्रिड के अनुसार पूरी तरह से यादृच्छिक माना जाता है, लेकिन आप देख सकते हैं कि इसमें बहुत अधिक विकर्ण लाइन पैटर्न हैं (यह लगभग एक चेकरबोर्ड की तरह दिखता है), इसलिए यह बहुत यादृच्छिक हैश नहीं है, और उन पैटर्न में दिखाई देगा इसके द्वारा उत्पादित शोर।

दूसरी समस्या यह है कि आपके हैश केवल ग्रेडिएंट वैक्टर को [0, 1] में लौटाते हैं, जबकि उन्हें सभी दिशाओं में ग्रेडिएंट प्राप्त करने के लिए [to1, 1] में होना चाहिए। उस भाग को रीमैप करके ठीक करना आसान है।

उन समस्याओं को ठीक करने के लिए, मैंने इस हैश फ़ंक्शन का उपयोग करने के लिए कोड को स्विच किया (जो मैंने मिकेल गोज़ेल से सीखा है, और संभवतः WJJ रे द्वारा एक पेपर के कारण है ):

vec2 hash(vec2 co) {
    float m = dot(co, vec2(12.9898, 78.233));
    return fract(vec2(sin(m),cos(m))* 43758.5453) * 2. - 1.;
}

ध्यान दें कि ट्रिगर फ़ंक्शन के कारण यह आपके संस्करण की तुलना में थोड़ा अधिक महंगा होने जा रहा है। हालांकि, यह परिणामी शोर की उपस्थिति में काफी सुधार करता है:

बेहतर हैश फ़ंक्शन के साथ fbm शोर


आपके स्पष्टीकरण के लिए बहुत- बहुत धन्यवाद । यह शायद ऑफ-टॉपिक है, लेकिन मैं वैसे भी पूछूंगा; कुछ स्रोत कोड में, जो शोर की गणना करते हैं, लोग वर्तमान समन्वय के साथ डॉट उत्पाद की गणना करने के लिए वेक्टर vec3 (1, 57, 113) का उपयोग करते हैं (मुझे लगता है कि इसका उद्देश्य हैश प्राप्त करना भी है)। स्थिरांक की यह विशेष पसंद (57 डिग्री में लगभग 1 रेडियन है, 133 = लगभग। 2 * डिग्री में रेडियन)? क्या यह ट्रिगर कार्यों में आवधिकता के कारण है? मैं यह करने में असमर्थ हूँ।
सरस्वती

3
@ सरस्वती मुझे वास्तव में यकीन नहीं है, लेकिन एक अनुमान है कि 57 और 113 चुने गए हैं क्योंकि वे प्राइम-ईश संख्या हैं। (113 अभाज्य है; 57 नहीं है, लेकिन यह 3 * 19 है, इसलिए अभी भी प्रिया है ... अगर यह बात है।) एक प्राइम-ईश संख्या से गुणा या संशोधन करना बिट्स को समेटना है, तो यह असामान्य नहीं है घटक हैश में।
नाथन रीड

1
@ मुझे संदेह है कि GLSL का PRNG है, यह देखते हुए कि GLSL कार्यक्रम नियतात्मक हैं।
user253751

1
ऐसा लगता है कि इस टिप्पणी थ्रेड में कई संभावित नए प्रश्न हैं ...
ट्राइकोप्लेक्स

1
मैं उन कलाकृतियों को रख रहा था और इस रैंड () फ़ंक्शन ने इसे ठीक कर दिया। समस्या यह है कि मैं अपने इलाके में 2 किमी चलने के बाद, ओपी जैसी कलाकृतियों को फिर से दिखाना शुरू कर दिया। यह यहाँ हैश फ़ंक्शन का उपयोग कर रहा था: amindforeverprogramming.blogspot.com/2013/07/… , जिससे कलाकृतियाँ चली गईं (100 किमी की दूरी को छोड़कर, अपवित्रता की ई.पू., लेकिन ठीक है, मुझे बस विखंडू में विभाजित करना पड़ा और मिल गया दोनों मूल्यों को हैशिंग के द्वारा काम करने के लिए, जिससे पेर्लिन का शोर लगभग अनिश्चित काल तक चलेगा)। तो, मैं इसे यहाँ छोड़ दूँगा शायद किसी को भी, जो एक ही मुद्दा है मदद करने के लिए।
निकोलस पिपिटोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.