Unity中实现ShaderToy卡通火(移植篇)

文章目录

  • 前言
  • 一、准备好我们的后处理基础脚本
    • 1、C#:
    • 2、Shader:
  • 二、开始逐语句对ShaderToy进行转化
    • 1、首先,找到我们的主函数 mainImage
    • 2、其余的方法全部都是在 mainImage 函数中调用的方法
    • 3、替换后的代码(已经没报错了,但是效果不对)
  • 三、我们来调试一下Shader,看看问题出在了哪?
    • 1、return float4(col, 1.0);
    • 2、black or fire
    • 3、getDepth函数
  • 四、修改 STEPS 的数值出错问题
    • 法1:在属性面板增加 STEPS 参数,赋予初始值4
    • 法2:使用#define 预定义一个常量
  • 五、最终代码


前言

在上一篇文章中,我们讲解了基础的ShaderToy怎么转化为Unity中的Shader。我们在这篇文章中,复刻一个复杂的ShaderToy效果卡通火。

  • Unity中的ShaderToy

  • 卡通火

请添加图片描述


一、准备好我们的后处理基础脚本

1、C#:

using UnityEngine;

//后处理脚本
[ExecuteInEditMode]
public class P2_9 : MonoBehaviour
{
    public Shader PostProcessingShader;
    private Material mat;
    public Material Mat
    {
        get
        {
            if (PostProcessingShader == null)
            {
                Debug.LogError("没有赋予Shader");
                return null;
            }
            if (!PostProcessingShader.isSupported)
            {
                Debug.LogError("当前Shader不支持");
                return null;
            }
            //如果材质没有创建,则根据Shader创建材质,并给成员变量赋值存储
            if (mat == null)
            {
                Material _newMaterial = new Material(PostProcessingShader);
                _newMaterial.hideFlags = HideFlags.HideAndDontSave;
                mat = _newMaterial;
                return _newMaterial;
            }
            return mat;
        }
    }

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit(source,destination,Mat);
    }
}

2、Shader:

Shader "MyShader/P2_9"
{
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
            #include "UnityCG.cginc"
            
            fixed4 frag (v2f_img i) : SV_Target
            {
                
                return 1;
            }
            ENDCG
        }
    }
}

二、开始逐语句对ShaderToy进行转化

1、首先,找到我们的主函数 mainImage

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
	vec2 uv = fragCoord.xy / iResolution.xy;
    uv.x *= 4.0;
    float t = iTime * 3.0;    
    vec3 col = vec3(0);
    
   	float noise = getNoise(uv, t);
    
    //shape cutoff to get higher further up the screen
    CUTOFF = uv.y;    
    //and at horiz edges
    CUTOFF += pow(abs(uv.x*0.5 - 1.),1.0);   
    
    //debugview cutoff field
    //fragColor = vec4(vec3(CUTOFF),1.0);   
    
    if (noise < CUTOFF){       
		//black
        col = vec3(0.);
    }else{
		//fire
        float d = pow(getDepth(noise),0.7);        
        vec3 hsv = vec3(d *0.17,0.8 - d/4., d + 0.8);
        col = hsv2rgb(hsv);
	}
    
    fragColor = vec4(col,1.0);   
}

2、其余的方法全部都是在 mainImage 函数中调用的方法

因此,我们可以直接使用把这些方法复制到 我们片元着色器的上方,把参数类型转化为CG中的参数类型,即可直接使用

  • vec2 :float2
  • vec3 :float3
  • vec4 :float4
  • float4(0,0) : 0
  • fract(x) : frac(x) (取 x 的小数部分)
  • mix(a,b,x) :lerp(a,b,x) (线性插值)

选中需要转化的变量名,使用快捷键 Ctrl + F,进行全部替换

在这里插入图片描述

3、替换后的代码(已经没报错了,但是效果不对)

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

Shader "MyShader/P2_9"
{
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
            #include "UnityCG.cginc"

            float3 mod289(float3 x)
            {
                return x - floor(x * (1.0 / 289.0)) * 289.0;
            }

            float4 mod289(float4 x)
            {
                return x - floor(x * (1.0 / 289.0)) * 289.0;
            }

            float4 permute(float4 x)
            {
                return mod289(((x * 34.0) + 1.0) * x);
            }

            float4 taylorInvSqrt(float4 r)
            {
                return 1.79284291400159 - 0.85373472095314 * r;
            }

            float snoise(float3 v)
            {
                const float2 C = float2(1.0 / 6.0, 1.0 / 3.0);
                const float4 D = float4(0.0, 0.5, 1.0, 2.0);

                // First corner
                float3 i = floor(v + dot(v, C.yyy));
                float3 x0 = v - i + dot(i, C.xxx);

                // Other corners
                float3 g = step(x0.yzx, x0.xyz);
                float3 l = 1.0 - g;
                float3 i1 = min(g.xyz, l.zxy);
                float3 i2 = max(g.xyz, l.zxy);

                //   x0 = x0 - 0.0 + 0.0 * C.xxx;
                //   x1 = x0 - i1  + 1.0 * C.xxx;
                //   x2 = x0 - i2  + 2.0 * C.xxx;
                //   x3 = x0 - 1.0 + 3.0 * C.xxx;
                float3 x1 = x0 - i1 + C.xxx;
                float3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
                float3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y

                // Permutations
                i = mod289(i);
                float4 p = permute(permute(permute(
                            i.z + float4(0.0, i1.z, i2.z, 1.0))
                        + i.y + float4(0.0, i1.y, i2.y, 1.0))
                    + i.x + float4(0.0, i1.x, i2.x, 1.0));

                // Gradients: 7x7 points over a square, mapped onto an octahedron.
                // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
                float n_ = 0.142857142857; // 1.0/7.0
                float3 ns = n_ * D.wyz - D.xzx;

                float4 j = p - 49.0 * floor(p * ns.z * ns.z); //  mod(p,7*7)

                float4 x_ = floor(j * ns.z);
                float4 y_ = floor(j - 7.0 * x_); // mod(j,N)

                float4 x = x_ * ns.x + ns.yyyy;
                float4 y = y_ * ns.x + ns.yyyy;
                float4 h = 1.0 - abs(x) - abs(y);

                float4 b0 = float4(x.xy, y.xy);
                float4 b1 = float4(x.zw, y.zw);

                //float4 s0 = float4(lessThan(b0,0.0))*2.0 - 1.0;
                //float4 s1 = float4(lessThan(b1,0.0))*2.0 - 1.0;
                float4 s0 = floor(b0) * 2.0 + 1.0;
                float4 s1 = floor(b1) * 2.0 + 1.0;
                float4 sh = -step(h, 0);

                float4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
                float4 a1 = b1.xzyw + s1.xzyw * sh.zzww;

                float3 p0 = float3(a0.xy, h.x);
                float3 p1 = float3(a0.zw, h.y);
                float3 p2 = float3(a1.xy, h.z);
                float3 p3 = float3(a1.zw, h.w);

                //Normalise gradients
                float4 norm = taylorInvSqrt(float4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
                p0 *= norm.x;
                p1 *= norm.y;
                p2 *= norm.z;
                p3 *= norm.w;

                // Mix final noise value
                float4 m = max(0.6 - float4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
                m = m * m;
                return 42.0 * dot(m * m, float4(dot(p0, x0), dot(p1, x1),
                 dot(p2, x2), dot(p3, x3)));
            }

            //END ASHIMA /

            const float STEPS = 4.;
            float CUTOFF = 0.15; //depth less than this, show black

            float3 hsv2rgb(float3 c)
            {
                float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
                float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
                return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
            }

            float getNoise(float2 uv, float t)
            {
                //given a uv coord and time - return a noise val in range 0 - 1
                //using ashima noise

                //add time to y position to make noise field move upwards

                float TRAVEL_SPEED = 1.5;

                //octave 1
                float SCALE = 2.0;
                float noise = snoise(float3(uv.x * SCALE, uv.y * SCALE - t * TRAVEL_SPEED, 0));

                //octave 2 - more detail
                SCALE = 6.0;
                noise += snoise(float3(uv.x * SCALE + t, uv.y * SCALE, 0)) * 0.2;

                //move noise into 0 - 1 range    
                noise = (noise / 2. + 0.5);

                return noise;
            }

            float getDepth(float n)
            {
                //given a 0-1 value return a depth,

                //remap remaining non-cutoff region to 0 - 1
                float d = (n - CUTOFF) / (1. - CUTOFF);

                //step it
                d = floor(d * STEPS) / STEPS;

                return d;
            }


            fixed4 frag(v2f_img i) : SV_Target
            {
                float2 uv = i.uv;
                uv.x *= 4.0;
                float t = _Time.y * 3.0;
                float3 col = 0;

                float noise = getNoise(uv, t);

                //shape cutoff to get higher further up the screen
                CUTOFF = uv.y;
                //and at horiz edges
                CUTOFF += pow(abs(uv.x * 0.5 - 1.), 1.0);

                //debugview cutoff field
                //fragColor = float4(float3(CUTOFF),1.0);   

                if (noise < CUTOFF)
                {
                    //black
                    col = 0;
                }
                else
                {
                    //fire
                    float d = pow(getDepth(noise), 0.7);
                    float3 hsv = float3(d * 0.17, 0.8 - d / 4., d + 0.8);
                    col = hsv2rgb(hsv);
                }
                
                return float4(col, 1.0);
            }
            ENDCG
        }
    }
}

在这里插入图片描述


三、我们来调试一下Shader,看看问题出在了哪?

我们在调试Shader时,因为主要效果是在 片元着色器 中实现的。
所以,我们调试Shader一般 从 输出 倒着 来调试

1、return float4(col, 1.0);

在 ShaderToy中,已经规定了透明值为 1 。所以,最终效果为黑色,不是透明值导致的。我们应该顺着 col 去找bug。

2、black or fire

if (noise < CUTOFF)
{
	//black
	col = 0;
}
else
{
	//fire
	float d = pow(getDepth(noise), 0.7);
	float3 hsv = float3(d * 0.17, 0.8 - d / 4., d + 0.8);
	col = hsv2rgb(hsv);
}
  • 我们修改black中的col。发现黑色的背景变白了,说明这不是使col最终全为 0 的原因
    col = 1;
    请添加图片描述

  • 我们修改 fire 中的 col 分别为 hsv 、d 和 getDepth(noise); (没有变化,说明这也不是原因所在)
    col = hsv; / col = d; / col = getDepth(noise);
    在这里插入图片描述

  • 我们修改 fire 中的 col 为 noise 后,我们的火出现了变化(可以锁定getDepth函数出现了问题)
    col = noise;
    请添加图片描述

3、getDepth函数

float getDepth(float n)
{
	//given a 0-1 value return a depth,
	
	//remap remaining non-cutoff region to 0 - 1
	float d = (n - CUTOFF) / (1. - CUTOFF);
	
	//step it
	d = floor(d * STEPS) / STEPS;
	
	return d;
}
  • 在归一化(remap remaining non-cutoff region to 0 - 1)之后,返回一个d。(我们可以看出火有了大致的颜色,说明问题处在了d = floor(d * STEPS) / STEPS;这句话)
    请添加图片描述
  • 而 d 我们已经返回过了。所以,最终问题在 STEPS 参数上
    在这里插入图片描述

四、修改 STEPS 的数值出错问题

在Unity的Shader中,如果我们的常量直接定义在Pass中
不管初始值为多少,Unity都会默认为0。
如果我们想这样使用参数,必须在属性块定义一个变量给定初始值

法1:在属性面板增加 STEPS 参数,赋予初始值4

  • 在这样定义后,修改对应的变量名后即可使用
	Properties
    {
        _Steps("STEPS",float) = 4
    }

法2:使用#define 预定义一个常量

#define STEPS 4

  • 可以看出,我们效果正确了
    请添加图片描述

五、最终代码

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

Shader "MyShader/P2_9"
{
    Properties
    {
        _Steps("STEPS",float) = 4
        _CUTOFF("CUTOFF",float) = 0.15
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
            #include "UnityCG.cginc"

            float3 mod289(float3 x)
            {
                return x - floor(x * (1.0 / 289.0)) * 289.0;
            }

            float4 mod289(float4 x)
            {
                return x - floor(x * (1.0 / 289.0)) * 289.0;
            }

            float4 permute(float4 x)
            {
                return mod289(((x * 34.0) + 1.0) * x);
            }

            float4 taylorInvSqrt(float4 r)
            {
                return 1.79284291400159 - 0.85373472095314 * r;
            }

            float snoise(float3 v)
            {
                const float2 C = float2(1.0 / 6.0, 1.0 / 3.0);
                const float4 D = float4(0.0, 0.5, 1.0, 2.0);

                // First corner
                float3 i = floor(v + dot(v, C.yyy));
                float3 x0 = v - i + dot(i, C.xxx);

                // Other corners
                float3 g = step(x0.yzx, x0.xyz);
                float3 l = 1.0 - g;
                float3 i1 = min(g.xyz, l.zxy);
                float3 i2 = max(g.xyz, l.zxy);

                //   x0 = x0 - 0.0 + 0.0 * C.xxx;
                //   x1 = x0 - i1  + 1.0 * C.xxx;
                //   x2 = x0 - i2  + 2.0 * C.xxx;
                //   x3 = x0 - 1.0 + 3.0 * C.xxx;
                float3 x1 = x0 - i1 + C.xxx;
                float3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
                float3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y

                // Permutations
                i = mod289(i);
                float4 p = permute(permute(permute(
                            i.z + float4(0.0, i1.z, i2.z, 1.0))
                        + i.y + float4(0.0, i1.y, i2.y, 1.0))
                    + i.x + float4(0.0, i1.x, i2.x, 1.0));

                // Gradients: 7x7 points over a square, mapped onto an octahedron.
                // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
                float n_ = 0.142857142857; // 1.0/7.0
                float3 ns = n_ * D.wyz - D.xzx;

                float4 j = p - 49.0 * floor(p * ns.z * ns.z); //  mod(p,7*7)

                float4 x_ = floor(j * ns.z);
                float4 y_ = floor(j - 7.0 * x_); // mod(j,N)

                float4 x = x_ * ns.x + ns.yyyy;
                float4 y = y_ * ns.x + ns.yyyy;
                float4 h = 1.0 - abs(x) - abs(y);

                float4 b0 = float4(x.xy, y.xy);
                float4 b1 = float4(x.zw, y.zw);

                //float4 s0 = float4(lessThan(b0,0.0))*2.0 - 1.0;
                //float4 s1 = float4(lessThan(b1,0.0))*2.0 - 1.0;
                float4 s0 = floor(b0) * 2.0 + 1.0;
                float4 s1 = floor(b1) * 2.0 + 1.0;
                float4 sh = -step(h, 0);

                float4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
                float4 a1 = b1.xzyw + s1.xzyw * sh.zzww;

                float3 p0 = float3(a0.xy, h.x);
                float3 p1 = float3(a0.zw, h.y);
                float3 p2 = float3(a1.xy, h.z);
                float3 p3 = float3(a1.zw, h.w);

                //Normalise gradients
                float4 norm = taylorInvSqrt(float4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
                p0 *= norm.x;
                p1 *= norm.y;
                p2 *= norm.z;
                p3 *= norm.w;

                // Mix final noise value
                float4 m = max(0.6 - float4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
                m = m * m;
                return 42.0 * dot(m * m, float4(dot(p0, x0), dot(p1, x1),
                 dot(p2, x2), dot(p3, x3)));
            }

            //END ASHIMA /

            float _Steps;
            float _CUTOFF; //depth less than this, show black

            float3 hsv2rgb(float3 c)
            {
                float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
                float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
                return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
            }

            float getNoise(float2 uv, float t)
            {
                //given a uv coord and time - return a noise val in range 0 - 1
                //using ashima noise

                //add time to y position to make noise field move upwards

                float TRAVEL_SPEED = 1.5;

                //octave 1
                float SCALE = 2.0;
                float noise = snoise(float3(uv.x * SCALE, uv.y * SCALE - t * TRAVEL_SPEED, 0));

                //octave 2 - more detail
                SCALE = 6.0;
                noise += snoise(float3(uv.x * SCALE + t, uv.y * SCALE, 0)) * 0.2;

                //move noise into 0 - 1 range    
                noise = (noise / 2. + 0.5);

                return noise;
            }

            float getDepth(float n)
            {
                //given a 0-1 value return a depth,

                //remap remaining non-_CUTOFF region to 0 - 1
                float d = (n - _CUTOFF) / (1. - _CUTOFF);
                //step it
                d = floor(d * _Steps) / _Steps;

                return d;
            }


            fixed4 frag(v2f_img i) : SV_Target
            {
                float2 uv = i.uv;
                uv.x *= 4.0;
                float t = _Time.y * 3.0;
                float3 col = 0;

                float noise = getNoise(uv, t);

                //shape _CUTOFF to get higher further up the screen
                _CUTOFF = uv.y;
                //and at horiz edges
                _CUTOFF += pow(abs(uv.x * 0.5 - 1.), 1.0);

                //debugview _CUTOFF field
                //fragColor = float4(float3(_CUTOFF),1.0);   

                if (noise < _CUTOFF)
                {
                    //black
                    col = 0;
                }
                else
                {
                    //fire
                    float d = pow(getDepth(noise), 0.7);
                    float3 hsv = float3(d * 0.17, 0.8 - d / 4., d + 0.8);
                    col = hsv2rgb(hsv);
                }
                
                return float4(col, 1.0);
            }
            ENDCG
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/248149.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于ssm旅游网站的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本旅游网站就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&#x…

rocketmq window测试小Demo 解决找不到或无法加载主类的问题

文章目录 rocketMQ启动1.下在相关的二进制文件2.配置环境变量3.启动NameServer4.启动broker5. MQ 启动&#xff01;5.1 测试发送数据 6.关闭服务 rocketMQ启动 1.下在相关的二进制文件 下载地址&#xff0c;点击即达 2.配置环境变量 3.启动NameServer 在文件夹下执行cmd进…

嵌入式奇妙之旅:Python与树莓派编程深度探索

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在这个数字化的时代&#xff0c;嵌入式系统的应…

如何理解 RPC 远程服务调用?

本文主要讲解 RPC 远程服务调用相关的知识。 RPC 远程服务调用是分布式服务架构的基础&#xff0c;无论微服务设计上层如何发展&#xff0c;讨论服务治理都绕不开远程服务调用&#xff0c;那么如何理解 RPC、有哪些常见的 RPC 框架、实现一款 RPC 框架需要哪些技术呢&#xff…

3D点云广义零样本分类的递归循环对比生成网络笔记

1 Title Contrastive Generative Network with Recursive-Loop for 3D point cloud generalized zero-shot classification(Yun Hao, Yukun Su, Guosheng Lin, Hanjing Su, Qingyao Wu)【Pattern Recognition】 2 Conclusion This work aims to facilitate research on 3D poi…

web微服务规划

一、背景 通过微服务来搭建web系统&#xff0c;就要对微服务进行规划&#xff0c;包括服务的划分&#xff0c;每个服务和数据库的命名规则&#xff0c;服务用到的端口等。 二、微服务划分 1、根据业务进行拆分 如&#xff1a; 一个购物系统可以将微服务拆分为基础中心、会员…

卸载Postman?这款IDEA插件真可以!

Postman是大家最常用的API调试工具&#xff0c;那么有没有一种方法可以不用手动写入接口到Postman&#xff0c;即可进行接口调试操作&#xff1f;今天给大家推荐一款IDEA插件&#xff1a;Apipost Helper&#xff0c;写完代码就可以调试接口并一键生成接口文档&#xff01;而且还…

群晖7.2使用Docker安装容器魔方结合内网穿透实现远程访问

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 文章目录 1. 拉取容器魔方镜像2. 运行容器魔方3. 本地访问容器魔…

注意std::shared_ptr的循环引用

指针智能是RAII的思想的具体体现。利用对象生命周期来管理资源。 在C11中&#xff0c;引入shared_ptr、weak_ptr和unique_ptr。 share_ptr是一个能有效解决赋值和拷贝构造的引用技术。 std::shared_ptr通过引用计数的方式来管理对象的生命周期&#xff0c;但是如果两个对象互…

老卫带你学---leetcode刷题(29. 两数相除)

29. 两数相除 问题 给你两个整数&#xff0c;被除数 dividend 和除数 divisor。将两数相除&#xff0c;要求 不使用 乘法、除法和取余运算。 整数除法应该向零截断&#xff0c;也就是截去&#xff08;truncate&#xff09;其小数部分。例如&#xff0c;8.345 将被截断为 8 &…

动态面板简介以及ERP原型图案列

动态面板简介以及ERP原型图案列 1.Axure动态面板简介2.使用Axure制作ERP登录界面3.使用Asure完成左侧菜单栏4.使用Axuer完成公告栏5.使用Axuer完成左边侧边栏 1.Axure动态面板简介 在Axure RP中&#xff0c;动态面板是一种强大的交互设计工具&#xff0c;它允许你创建可交互的…

致远互联FE协作办公平台 editflow_manager.jsp 存在SQL注入漏洞

文章目录 产品简介漏洞概述指纹识别漏洞利用修复建议 产品简介 致远互联FE协作办公平台是一个专注于协同管理软件领域的数智化运营平台及云服务提供商。平台旨在为企业提供数字化转型和升级的解决方案&#xff0c;特别是针对大中型政府和企业客户。平台的主要特点包括开放共享…

Linux环境下HTTP请求的代码详解与实例

嘿&#xff0c;Linux狂热者们&#xff0c;是时候让我们在这个充满激情的平台上探索一下HTTP协议的奥秘了。我知道&#xff0c;对于这个我们每天都在使用&#xff0c;但却可能没深入了解过的HTTP&#xff0c;你们一定充满了好奇和期待。那么&#xff0c;让我们一起踏上这趟探索之…

LeetCode977有序数组的平方两种方法实现(java实现)

今天来分享的是LeetCode977有序数组的平方的实现方法&#xff0c;我们先来看下题目&#xff1a; 提示&#xff1a;我们在读题的时候一定要仔细&#xff0c;注意题目给定的条件是有序数组。 方法1&#xff1a;我们在看到题目的第一时间是无非是将数组每个元素进行平方&#xff…

高德地图+Vue中使用出现的问题

最近在做高德地图的逆向地理编码API出现了问题 按着官方的方式写代码运行时出现了问题&#xff0c;随后问了技术人员。 添加之后成功运行

云原生之深入解析Kubernetes中服务的性能

一、Pyroscope 简介 ① 什么是 Pyroscope&#xff1f; 开发人员通常需要查看生产应用程序中的性能瓶颈以确定问题的原因&#xff0c;为此通常需要可以通过日志和代码工具收集的信息。不幸的是&#xff0c;这种方法通常很耗时&#xff0c;并且不能提供有关潜在问题的足够详细信…

关于APP出海营销,有哪些开发者成功出圈?

NetMarvel 投身于开发者出海用户增长/广告变现业务已将近9个年头&#xff0c;帮助国内外众多开发者解决全球移动营销难题&#xff0c;最大化收益&#xff0c;实现全球范围内的极速增长。 NetMarvel有效助力Piggy Go、VNG、Candy Crack等游戏应用&#xff0c; Shopee、Tango等非…

四六级高频词组13

目录 词组 其他链接&#xff1a; 词组 551. beyond &#xff08;all&#xff09; question &#xff08;without question&#xff09; 毫无疑问 552. out of the question &#xff08;impossible&#xff09; 不可能的 553. in question &#xff08;under discussion&…

Etsy运营秘籍——打造大卖店铺的九大技巧

在跨境电商的浩瀚海洋中&#xff0c;Etsy 作为一个注重手工制作与独特设计的平台&#xff0c;吸引了众多卖家的关注。在 Etsy 的世界里&#xff0c;成功运营小店需要更多的智慧和技巧。作为一位在 Etsy 上开店多年的老手&#xff0c;在这过程中也总结了不少经验&#xff0c;这篇…

案例066:基于微信小程序的家政预约设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…