मैं स्क्रीन पर प्राकृतिक बारिश की बूंदें कैसे बना सकता हूं?


11

मैं के साथ बारिश प्रभाव ड्रॉप बनाने के लिए कोशिश कर रहा हूँ metaballs shadertoy में एक सुराग खोजने के परदे पर और निशान, लेकिन मैं समझ में नहीं आया कैसे लागू किया:

https://www.shadertoy.com/view/ltffzl

दुर्भाग्य से यह कई गणित गणना है और मैं इसे एकता में उपयोग नहीं कर सकता क्योंकि यह एक लैग पैदा करता है। जाहिर तौर पर मुझे बनावट का उपयोग करना चाहिए लेकिन मेरे पास प्रभाव कैसे हो सकता है ?!

यहाँ छवि विवरण दर्ज करें

मेरा विचार ड्रॉपिंग के लिए एक बनावट और ट्रेल रेंडरर का उपयोग कर रहा है लेकिन मैं मेटाबॉल्स प्रभाव कैसे कर सकता हूं? यहाँ छवि विवरण दर्ज करें


अपडेट करें

मैं इस अनुच्छेद द्वारा मेटाबॉल को लागू कर सकता था

https://github.com/smkplus/RainFX/tree/master

लेकिन मैं ट्रेल के बारे में विचार नहीं किया है

जवाबों:


11

मुझे लगता है कि आपको इस प्रभाव के बारे में सोचना चाहिए कि "उस नक्शे की गणना करें जहां पानी है" + "उस नक्शे से एक सामान्य वेक्टर उत्पन्न करता है और पृष्ठभूमि बनावट की खोज को ऑफसेट करने के लिए इसका उपयोग करता है"।

अपने उदाहरण shadertoy क्या करता है नीचे तोड़कर, यह सिर्फ एक "निशान" की गणना करता है यह दिखाने के लिए कि जहां डिफोगिंग होता है:

यहाँ छवि विवरण दर्ज करें

परिपत्र वर्षाबूंदों के मानदंडों की गणना करता है,

यहाँ छवि विवरण दर्ज करें

और नकली अपवर्तन के लिए एक बनावट देखने के ऑफसेट करने के लिए उस सामान्य नक्शे का उपयोग करता है।

यदि आप किसी shader में पोस्ट-प्रोसेसिंग के माध्यम से किए गए ट्रेल्स चाहते हैं, तो आपको कुछ बीजगणित का उपयोग करके shader में "ट्रेल" आकार बनाना चाहिए। उदाहरण के लिए, निम्नलिखित फ़ंक्शन में, मैंने "वॉबलि पथ" और सिर पर एक टेपर से आगे निकल जाना और प्राप्त करने के लिए पूंछ करना

float trailDrop(vec2 uv, vec2 id, float t) { 
    // wobbly path
    float wobble = 0.5 + 0.5 
        * cos(120.0 * uv.y) 
        * sin(50.0 * uv.y);
    float v = 1.0 - 10.0 * abs(uv.x - 0.5 + 0.2 * wobble);
    // head
    v *= clamp(30.0 * uv.y, 0.0, 1.0);
    v *= clamp( uv.y + 7.0 * t - 0.6, 0.0, 1.0);
    // tail
    v *= clamp(1.0 - uv.y - pow(t, 2.0), 0.0, 1.0);
    return clamp(v * 10.0, 0.0, 1.0);
}

यहाँ shadertoy में एक मोटा POC है - https://www.shadertoy.com/view/XlBfz1 जिसमें रेनड्रॉप ट्रेल्स का एक सेट बनाया गया है। यह डेरिवेटिव रिज़ॉल्यूशन के कारण छोटे प्रस्तावों पर दानेदार दिखता है, लेकिन यदि आप इसे फुलस्क्रीन करते हैं तो बेहतर दिखना चाहिए।

संपादित करें: ओवरलेड रेनड्रॉप्स के साथ एक उदाहरण जोड़ा गया

यहाँ छवि विवरण दर्ज करें

पाठक को एक अभ्यास के रूप में छोड़ दिया:

1) छोटे गोल बूँदें जोड़ें। प्रेरणा के लिए, StaticDropsअपने मूल shadertoy उदाहरण में फ़ंक्शन देखें।

2) उच्च गुणवत्ता वाले सामान्य गणनाओं में जोड़ें। जैसा कि #define CHEAP_NORMALSआपके मूल shadertoy उदाहरण में विकल्प का अर्थ है, अंतर्निहित dFdx एक कम-निष्ठा सन्निकटन है और आप मैन्युअल रूप से डेरिवेटिव की गणना करके (फ़ंक्शन 3 बार गणना करने की लागत पर) बेहतर परिणाम प्राप्त कर सकते हैं।

3) स्तंभों के बीच रिक्ति को बेतरतीब करना। आप स्तंभों को चौड़ा कर सकते हैं और फिर uv.x - 0.5 + 0.2 * wobbleएक्स अक्ष पर एक यादृच्छिक ऑफसेट जोड़ने के लिए थोड़ा संशोधित कर सकते हैं । आप शायद एक बार फिर मूल उदाहरण से एक पृष्ठ निकालना चाहते हैं और एक समान रूप देखने के लिए एक दूसरे के ऊपर धाराओं के कुछ अलग-अलग परतों को परत कर सकते हैं।



@ डीडीग्रेगरी नोटेड। मेटाबॉल टिप्पणी को हटाने
जिमी

निशान खुद को बफर के माध्यम से किया जा सकता है, लुप्त होती (पुरानेवैल्यू * .95 + न्यूडिस्कपोजिशन) लौटें। आमतौर पर लोग पेरलिन शोर का उपयोग एक सीधी रेखा को रोकने के लिए करते हैं।
सैयद मोर्तेज़ा कामली

इस shadertoy.com/view/4dy3zR की तरह कुछ मैं शोर निशान बनाने की कोशिश की, लेकिन मैं नहीं कर सकता
Seyed Morteza Kamali

7

आप नीचे दिए गए चरणों का पालन करके इस आशय को बना सकते हैं:

कण

कण

RenderTextuer

आप RenderTexture का उपयोग करके परिणाम संग्रहीत कर सकते हैं। यह shadertoy में मल्टीपास का उदाहरण है:

https://www.shadertoy.com/view/ltccRl

iñigo quilez: Shadertoy कई पास का उपयोग करता है, एक "बफर"। जैसा कि नाम से संकेत मिलता है, यह पास परिणामों को एक बफर में संग्रहीत करता है। एक बफर सिर्फ एक बनावट है। एकता आपको बनावट को भी प्रस्तुत करने देगी।

मैंने रेंडरिंग कणों के लिए एक कैमरा बनाया

कुल्हाड़ी

RenderTexture

GrabPassing

आप विरूपण लागू करने के लिए पास हड़पने कर सकते हैं

मैंने इसे इस पोस्ट में समझाया:

मैं क्वांटम ब्रेक के विरूपण कण प्रभाव को कैसे दोहरा सकता हूं?

कलंक

लाइफटाइम ओवर कलर में अल्फा का उपयोग करने से हमारे पास सरल ब्लर होता है

alphaovertime

gradiant

बेहतर परिणाम प्राप्त करने के लिए साधारण ब्लर का उपयोग करना बेहतर है, लेकिन हम ब्लर कैसे प्राप्त करते हैं?

कन्वेंशन मैट्रिक्स

इमेज प्रोसेसिंग में, एक कर्नेल, कनवल्शन मैट्रिक्स या मास्क एक छोटा मैट्रिक्स होता है। इसका उपयोग धुंधलापन, तेज करने, उभारने, धार का पता लगाने और बहुत कुछ करने के लिए किया जाता है। यह एक कर्नेल और एक छवि के बीच एक कनवल्शन को पूरा करके किया जाता है।

अधिक जानकारी के लिए, कृपया इस लिंक का अनुसरण करें

गुठली

 Shader "Smkgames/Convolution"
    {
        Properties
        {
            _MainTex ("Texture", 2D) = "white" {}
            [Enum(kerEdgeDetectionA,1,kerEdgeDetectionB,2,kerEdgeDetectionC,3,kerSharpen,4,kerBoxBlur,5)]
            _Kernel("Kernel", Float) = 1
        }
        SubShader
        {
            // No culling or depth
            Cull Off ZWrite Off ZTest Always

            Pass
            {
                CGPROGRAM

                #pragma vertex vert
                #pragma fragment frag

                #include "UnityCG.cginc"

                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                };

                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                };

                v2f vert (appdata v)
                {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.uv = v.uv;
                    return o;
                }

                sampler2D _MainTex;
                float4 _MainTex_TexelSize;

                float3x3 GetData(int channel, sampler2D tex, float2 uv, float4 size)
                {
                    float3x3 mat;
                    for (int y=-1; y<2; y++)
                    {  
                        for(int x=-1; x<2; x++)
                        {      
                            mat[x+1][y+1]=tex2D(tex, uv + float2(x*size.x, y*size.y))[channel];
                        }              
                    }
                    return mat;
                }
                float3x3 GetMean(float3x3 matr, float3x3 matg, float3x3 matb)
                {
                    float3x3 mat;
                    for (int y=0; y<3; y++)
                    {  
                        for(int x=0; x<3; x++)
                        {
                            mat[x][y] = (matr[x][y] + matg[x][y] + matb[x][y]) / 3.0;
                        }
                    }
                    return mat;
                }

                float Convolve(float3x3 kernel, float3x3 pixels, float denom, float offset)
                {
                    float res = 0.0;
                    for (int y=0; y<3; y++)
                    {  
                        for(int x=0; x<3; x++)
                        {
                            res += kernel[2-x][2-y]*pixels[x][y];
                        }
                    }

                    return  res;
                }

                float _Kernel;

                fixed4 frag (v2f i) : SV_Target
                {


                    float3x3 kerEdgeDetectionA = float3x3 (    0.0,  0,  -1.0,
                                                        1.0,  0,  -1.0,
                                                        0.0,  1.0,  0.0);

                   float3x3 kerEdgeDetectionB = float3x3 (0.0,  1.0,  0.0,
                                                 1.0, -4.0,  1.0,
                                                 0.0,  1.0, 0.0);

                   float3x3 kerEdgeDetectionC = float3x3 (-1.0, -1.0, -1.0,
                                                    -1.0,  8.0, -1.0,
                                                    -1.0, -1.0, -1.0);

                   float3x3 kerSharpen = float3x3 (0.0, -1.0, 0.0,
                                                    -1.0, 5.0, -1.0,
                                                    0.0, -1.0, 0.0);



                    float3x3 kerBoxBlur = (1.0/9.0)*float3x3 (    1.0,  1.0,  1.0,
                                                        1.0,  1.0,  1.0,
                                                        1.0,  1.0,  1.0);




                    float3x3 kernelSelection;
                if(_Kernel == 1){
                kernelSelection = kerEdgeDetectionA;
                }else if(_Kernel == 2){
                kernelSelection = kerEdgeDetectionB;    
                }else if(_Kernel == 3){
                kernelSelection = kerEdgeDetectionC;
                }else if(_Kernel == 4){
                kernelSelection = kerSharpen;   
                }else if(_Kernel == 5){
                kernelSelection = kerBoxBlur;
                }

                float3x3 matr = GetData(0, _MainTex, i.uv, _MainTex_TexelSize);
                float3x3 matg = GetData(1, _MainTex, i.uv, _MainTex_TexelSize);
                float3x3 matb = GetData(2, _MainTex, i.uv, _MainTex_TexelSize);
                float3x3 mata = GetMean(matr, matg, matb);


                // kernel
               float4 gl_FragColor = float4(Convolve(kernelSelection,matr,1.0,0.0),
                                            Convolve(kernelSelection,matg,1.0,0.0),
                                            Convolve(kernelSelection,matb,1.0,0.0),
                                            1.0);

                return gl_FragColor;
            }
            ENDCG
        }
    }
}

बॉक्स ब्लर

एक बॉक्स ब्लर (जिसे बॉक्स रैखिक फ़िल्टर के रूप में भी जाना जाता है) एक स्थानिक डोमेन रैखिक फ़िल्टर है, जिसके परिणामस्वरूप छवि में प्रत्येक पिक्सेल का इनपुट छवि में अपने पड़ोसी पिक्सल के औसत मूल्य के बराबर मूल्य होता है। यह कम-पास ("धुंधला") फिल्टर का एक रूप है। 3 बाय 3 बॉक्स ब्लर को मैट्रिक्स के रूप में लिखा जा सकता है

https://en.wikipedia.org/wiki/Box_blur

1_oos3y1ztoewgsubpdnbvea

Shader "Smkgames/Simple Box Blur"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Blend SrcAlpha OneMinusSrcAlpha


        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex;
            float4 _MainTex_TexelSize;

            float4 box(sampler2D tex, float2 uv, float4 size)
            {
                float4 c = tex2D(tex, uv + float2(-size.x, size.y)) + tex2D(tex, uv + float2(0, size.y)) + tex2D(tex, uv + float2(size.x, size.y)) +
                            tex2D(tex, uv + float2(-size.x, 0)) + tex2D(tex, uv + float2(0, 0)) + tex2D(tex, uv + float2(size.x, 0)) +
                            tex2D(tex, uv + float2(-size.x, -size.y)) + tex2D(tex, uv + float2(0, -size.y)) + tex2D(tex, uv + float2(size.x, -size.y));

                return c / 9;
            }

            float4 frag (v2f i) : SV_Target
            {
                float4 col = box(_MainTex, i.uv, _MainTex_TexelSize);
                return col;
            }
            ENDCG
        }
    }
}

blurbox

दुहराव

आप पिछले फ्रेम को स्टोर करने के लिए Rendertexture का उपयोग कर सकते हैं। तो आप पिछले फ्रेम को फिर से धुंधला कर सकते हैं। इसे दोहराने से आप धुंधलापन प्राप्त करते हैं।

0fe28c6167db2132d4bb8677fc1b2050 - Leandro-एर्लिच-अर्जेंटीना

साधारण

float4 distortion = tex2D(_MainTex,i.uv);
float3 distortionNormal = UnpackNormal(distortion);

record_2019_03_03_21_35_45_417

निष्कर्ष

अंतिम शेडर:

Shader "Smkgames/BrokenGlass3D"
{
    Properties{
        _MainTex("MainTex",2D) = "white"{}
        _NormalIntensity("NormalIntensity",Float) = 1
        _Alpha("Alpha",Float) = 1
    }
    SubShader
    {
Tags {"Queue"="Transparent" "RenderType"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha 


        GrabPass
        {
            "_GrabTexture"
        }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float2 grabPos : TEXCOORD1;
                float3 normal :NORMAL;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 grabPos : TEXCOORD1;
                half3 worldNormal :TEXCOORD2;
                float4 vertex : SV_POSITION;

            };
            sampler2D _MainTex;
            float _Intensity,_Alpha;

            v2f vert (appdata v)
            {
                v2f o;
                o.uv = v.uv;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.grabPos = ComputeGrabScreenPos(o.vertex);
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                return o;
            }

            sampler2D _GrabTexture;
            float _NormalIntensity;

            fixed4 frag (v2f i) : SV_Target
            {
                float4 distortion = tex2D(_MainTex,i.uv);
                float3 distortionNormal = UnpackNormal(distortion);
                distortionNormal.xy *= _NormalIntensity;
                normalize(distortionNormal);
                fixed4 col = tex2Dproj(_GrabTexture, i.grabPos+float4(distortionNormal.rgb,0));
                return col;
            }
            ENDCG
        }
    }
}

जीवनकाल में रंग में अल्फा का उपयोग किए बिना:

record_2019_03_03_21_48_36_273

जीवनकाल में रंग में अल्फा का उपयोग करके:

record_2019_03_03_21_48_19_786

स्रोत उपलब्ध है:

https://github.com/smkplus/RainDrop

अभी और है!

भी आप Ripples बना सकते हैं

record_2019_03_04_22_10_25_457

उपयोगी कड़ियाँ

https://80.lv/articles/breakdown-animated-raindrop-material-in-ue4/

https://seblagarde.wordpress.com/2013/01/03/water-drop-2b-dynamic-rain-and-its-effects/


1

वास्तव में इस साल के बारे में एक सवाल था, लेकिन यह एकता (दुर्भाग्य से) से संबंधित नहीं है। यदि आप स्लाइड 57 को देखते हैं लिंक की गई प्रस्तुति की को , तो वे ग्रिड-आधारित दृष्टिकोण का उल्लेख करते हैं।

वहाँ एक है कुछ हद तक संबंधित भौतिकी एसई पर सवाल है कि आपको दिलचस्प लग सकते। लिंक किए गए प्रश्न में droplet.pdf का लिंक टूटा हुआ है, लेकिन यह अभी भी वेबैक मशीन पर है। यह कुछ प्रकार की सतहों से बहते पानी के गणित में जाता है। बूंदों को पहले के वर्षाबूंदों द्वारा उपयोग किए जाने वाले रास्तों में यात्रा करना पसंद है, उदाहरण के लिए (p926 देखें)।

आप शायद प्रत्येक "रेनड्रॉप" के सिर और पूंछ को मॉडल कर सकते हैं और इसे ज़िग और ज़ैग को थोड़ा सा करने की अनुमति दे सकते हैं। जब दो लम्बी वर्षा होती है, तो मुझे लगता है कि आप उन्हें एक बड़ी और तेज गति वाली बारिश की पृष्ठभूमि में जोड़ सकते हैं। पानी की मात्रा समान रहती है। यह सिर्फ गुरुत्वाकर्षण, कांच के आसंजन, और सामंजस्य की शक्तियों द्वारा स्थानांतरित और आकार में हो रहा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.