[Godot4] 水底气泡的 gdshader

news2024/10/19 11:53:09

水底气泡的 gdshader

来自 shadertoy 的代码

在这里,我添加了 x 方向和 y 方向上的 uv 位移

但是还是感觉太弱智

shader_type canvas_item;
// Created by greenbird10
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0

uniform float bubble_size = 0.1;   // Size of the bubbles
uniform float upward_speed = 0.2;  // Speed at which bubbles rise
uniform float movable_x = 0.0;
uniform float movable_y = 0.0;

float hash(vec2 p) {
	return 0.5*(
    sin(dot(p, vec2(271.319, 413.975)) + 1217.13*p.x*p.y)
    ) + 0.5;
}

float noise(vec2 p) {
  vec2 w = fract(p);
  w = w * w * (3.0 - 2.0*w);
  p = floor(p);
  return mix(
    mix(hash(p+vec2(0,0)), hash(p+vec2(1,0)), w.x),
    mix(hash(p+vec2(0,1)), hash(p+vec2(1,1)), w.x), w.y);
}

// wave octave inspiration
// Alexander Alekseev - Seascape
// https://www.shadertoy.com/view/Ms2SD1
float map_octave(vec2 uv) {
  uv = (uv + noise(uv)) / 2.5;
  uv = vec2(uv.x*0.6-uv.y*0.8, uv.x*0.8+uv.y*0.6);
  vec2 uvsin = 1.0 - abs(sin(uv));
  vec2 uvcos = abs(cos(uv));
  uv = mix(uvsin, uvcos, uvsin);
  float val = 1.0 - pow(uv.x * uv.y, 0.65);
  return val;
}

float map(vec3 p) {
  vec2 uv = p.xz + TIME/2.;
  float amp = 0.6, freq = 2.0, val = 0.0;
  for(int i = 0; i < 3; ++i) {
    val += map_octave(uv) * amp;
    amp *= 0.3;
    uv *= freq;
    // uv = vec2(uv.x*0.6-uv.y*0.8, uv.x*0.8+uv.y*0.6);
  }
  uv = p.xz - 1000. - TIME/2.;
  amp = 0.6;
  freq = 2.0;
  for(int i = 0; i < 3; ++i) {
    val += map_octave(uv) * amp;
    amp *= 0.3;
    uv *= freq;
    // uv = vec2(uv.x*0.6-uv.y*0.8, uv.x*0.8+uv.y*0.6);
  }
  return val + 3.0 - p.y;
}

vec3 getNormal(vec3 p, vec2 resolution) {
  float eps = 1./resolution.x;
  vec3 px = p + vec3(eps, 0, 0);
  vec3 pz = p + vec3(0, 0, eps);
  return normalize(vec3(map(px),eps,map(pz)));
}

// raymarch inspiration
// Alexander Alekseev - Seascape
// https://www.shadertoy.com/view/Ms2SD1
float raymarch(vec3 ro, vec3 rd, vec2 resolution, out vec3 outP, out float outT) {
    float l = 0., r = 26.;
    int i = 0, steps = 16;
    float dist = 1000000.;
    for(int i = 0; i < steps; ++i) {
        float mid = (r+l)/2.;
        float mapmid = map(ro + rd*mid);
        dist = min(dist, abs(mapmid));
        if(mapmid > 0.) {
        	l = mid;
        }
        else {
        	r = mid;
        }
        if(r - l < 1./resolution.x) break;
    }
    outP = ro + rd*l;
    outT = l;
    return dist;
}

float fbm(vec2 n) {
	float total = 0.0, amplitude = 1.0;
	for (int i = 0; i < 5; i++) {
		total += noise(n) * amplitude; 
		n += n;
		amplitude *= 0.4; 
	}
	return total;
}

float lightShafts(vec2 st) {
    float angle = -0.2;
    vec2 _st = st;
    float t = TIME / 16.;
    st = vec2(st.x * cos(angle) - st.y * sin(angle), 
              st.x * sin(angle) + st.y * cos(angle));
    float val = fbm(vec2(st.x*2. + 200. + t, st.y/4.));
    val += fbm(vec2(st.x*2. + 200. - t, st.y/4.));
    val = val / 3.;
    float mask = pow(clamp(1.0 - abs(_st.y-0.15), 0., 1.)*0.49 + 0.5, 2.0);
    mask *= clamp(1.0 - abs(_st.x+0.2), 0., 1.) * 0.49 + 0.5;
	return pow(val*mask, 2.0);
}

vec2 bubble(vec2 uv, float scale) {
    if(uv.y > 0.2) return vec2(0.);
    float t = TIME/4.;
    vec2 st = uv * scale;
    vec2 _st = floor(st);
    vec2 bias = vec2(0., 4. * sin(_st.x*128. + t));
    float mask = smoothstep(0.1, 0.2, -cos(_st.x*128. + t));
    st += bias;
    vec2 _st_ = floor(st);
    st = fract(st);
	float warpped_time = mod(noise(_st_) - TIME * upward_speed, 1.0);
    float size = noise(_st_)*bubble_size+0.01;
    vec2 pos = vec2(noise(vec2(t, _st_.y*64.1)) * 0.8 + 0.1, 0.5);
    if(length(st.xy - pos) < size) {
        return (st + pos) * vec2(.1, .2) * mask;
    }
    return vec2(0.);
}

void fragment() {
	vec2 resolution = 1.0/SCREEN_PIXEL_SIZE;
		
    vec3 ro = vec3(0.,0.,2.);
    vec3 lightPos = vec3(8, 3, -3);
    vec3 lightDir = normalize(lightPos - ro);

    // adjust uv
    vec2 uv = FRAGCOORD.xy;
    uv = (-(1.0/SCREEN_PIXEL_SIZE).xy + 2.0*uv) / (1.0/SCREEN_PIXEL_SIZE).y;
	uv.y = 1.0 - uv.y; // flip
    uv.y *= 0.5;
    uv.x *= 0.45;
	uv.y -= 0.4;
	
	uv.x += movable_x * 0.1 * sin(TIME);
	uv.y += movable_y * 0.1 * cos(TIME);
    uv += bubble(uv, 12.) + bubble(uv, 12.) + bubble(uv, 36.) + bubble(uv, 48.); // add bubbles

    vec3 rd = normalize(vec3(uv, -1.));
    vec3 hitPos;
    float hitT;
    vec3 seaColor = vec3(11,82,142)/255.;
    vec3 color;
    
    // waves
    float dist = raymarch(ro, rd, resolution, hitPos, hitT);
    float diffuse = dot(getNormal(hitPos, resolution), rd) * 0.5 + 0.5;
    color = mix(seaColor, vec3(15,120,152)/255., diffuse);
    color += pow(diffuse, 12.0);
	// refraction
    vec3 ref = normalize(refract(hitPos-lightPos, getNormal(hitPos, resolution), 0.05));
    float refraction = clamp(dot(ref, rd), 0., 1.0);
    color += vec3(245,250,220)/255. * 0.6 * pow(refraction, 1.5);

    vec3 col = vec3(0.);
    col = mix(color, seaColor, pow(clamp(0., 1., dist), 0.2)); // glow edge
    col += vec3(225,230,200)/255. * lightShafts(uv); // light shafts

    // tone map
    col = (col*col + sin(col))/vec3(1.8, 1.8, 1.9);
    
    // vignette
    // inigo quilez - Stop Motion Fox 
    // https://www.shadertoy.com/view/3dXGWB
    vec2 q = FRAGCOORD.xy / resolution.xy;
    col *= 0.7+0.3*pow(16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.2);

    COLOR = vec4(col,1.0);
}

添加水平移动的功能

shader_type canvas_item;
// Created by greenbird10
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0

uniform float bubble_size = 0.1;   // Size of the bubbles
uniform float upward_speed = 0.2;  // Speed at which bubbles rise
uniform float yaw_angle = 0.0;
uniform vec3 camera_pos = vec3(0.,0.,2.);

mat2 rotation_matrix(float angle) {
    float s = sin(angle);
    float c = cos(angle);
    return mat2(vec2(c, -s), vec2(s, c));
}

float hash(vec2 p) {
	return 0.5*(
    sin(dot(p, vec2(271.319, 413.975)) + 1217.13*p.x*p.y)
    ) + 0.5;
}

float noise(vec2 p) {
  vec2 w = fract(p);
  w = w * w * (3.0 - 2.0*w);
  p = floor(p);
  return mix(
    mix(hash(p+vec2(0,0)), hash(p+vec2(1,0)), w.x),
    mix(hash(p+vec2(0,1)), hash(p+vec2(1,1)), w.x), w.y);
}

// wave octave inspiration
// Alexander Alekseev - Seascape
// https://www.shadertoy.com/view/Ms2SD1
float map_octave(vec2 uv) {
  uv = (uv + noise(uv)) / 2.5;
  uv = vec2(uv.x*0.6-uv.y*0.8, uv.x*0.8+uv.y*0.6);
  vec2 uvsin = 1.0 - abs(sin(uv));
  vec2 uvcos = abs(cos(uv));
  uv = mix(uvsin, uvcos, uvsin);
  float val = 1.0 - pow(uv.x * uv.y, 0.65);
  return val;
}

float map(vec3 p) {
  vec2 uv = p.xz + TIME/2.;
  float amp = 0.6, freq = 2.0, val = 0.0;
  for(int i = 0; i < 3; ++i) {
    val += map_octave(uv) * amp;
    amp *= 0.3;
    uv *= freq;
    // uv = vec2(uv.x*0.6-uv.y*0.8, uv.x*0.8+uv.y*0.6);
  }
  uv = p.xz - 1000. - TIME/2.;
  amp = 0.6;
  freq = 2.0;
  for(int i = 0; i < 3; ++i) {
    val += map_octave(uv) * amp;
    amp *= 0.3;
    uv *= freq;
    // uv = vec2(uv.x*0.6-uv.y*0.8, uv.x*0.8+uv.y*0.6);
  }
  return val + 3.0 - p.y;
}

vec3 getNormal(vec3 p, vec2 resolution) {
  float eps = 1./resolution.x;
  vec3 px = p + vec3(eps, 0, 0);
  vec3 pz = p + vec3(0, 0, eps);
  return normalize(vec3(map(px),eps,map(pz)));
}

// raymarch inspiration
// Alexander Alekseev - Seascape
// https://www.shadertoy.com/view/Ms2SD1
float raymarch(vec3 ro, vec3 rd, vec2 resolution, out vec3 outP, out float outT) {
    float l = 0., r = 26.;
    int i = 0, steps = 16;
    float dist = 1000000.;
    for(int i = 0; i < steps; ++i) {
        float mid = (r+l)/2.;
        float mapmid = map(ro + rd*mid);
        dist = min(dist, abs(mapmid));
        if(mapmid > 0.) {
        	l = mid;
        }
        else {
        	r = mid;
        }
        if(r - l < 1./resolution.x) break;
    }
    outP = ro + rd*l;
    outT = l;
    return dist;
}

float fbm(vec2 n) {
	float total = 0.0, amplitude = 1.0;
	for (int i = 0; i < 5; i++) {
		total += noise(n) * amplitude; 
		n += n;
		amplitude *= 0.4; 
	}
	return total;
}

float lightShafts(vec2 st) {
    float angle = -0.2;
    vec2 _st = st;
    float t = TIME / 16.;
    st = vec2(st.x * cos(angle) - st.y * sin(angle), 
              st.x * sin(angle) + st.y * cos(angle));
    float val = fbm(vec2(st.x*2. + 200. + t, st.y/4.));
    val += fbm(vec2(st.x*2. + 200. - t, st.y/4.));
    val = val / 3.;
    float mask = pow(clamp(1.0 - abs(_st.y-0.15), 0., 1.)*0.49 + 0.5, 2.0);
    mask *= clamp(1.0 - abs(_st.x+0.2), 0., 1.) * 0.49 + 0.5;
	return pow(val*mask, 2.0);
}

vec2 bubble(vec2 uv, float scale) {
    if(uv.y > 0.2) return vec2(0.);
    float t = TIME/4.;
    vec2 st = uv * scale;
    vec2 _st = floor(st);
    vec2 bias = vec2(0., 4. * sin(_st.x*128. + t));
    float mask = smoothstep(0.1, 0.2, -cos(_st.x*128. + t));
    st += bias;
    vec2 _st_ = floor(st);
    st = fract(st);
	float warpped_time = mod(noise(_st_) - TIME * upward_speed, 1.0);
    float size = noise(_st_)*bubble_size+0.01;
    vec2 pos = vec2(noise(vec2(t, _st_.y*64.1)) * 0.8 + 0.1, 0.5);
    if(length(st.xy - pos) < size) {
        return (st + pos) * vec2(.1, .2) * mask;
    }
    return vec2(0.);
}

void fragment() {
	vec2 resolution = 1.0/SCREEN_PIXEL_SIZE;
		
    vec3 ro = camera_pos;
    vec3 lightPos = vec3(8, 3, -3);
    vec3 lightDir = normalize(lightPos - ro);

    // adjust uv
    vec2 uv = FRAGCOORD.xy;
    uv = (-(1.0/SCREEN_PIXEL_SIZE).xy + 2.0*uv) / (1.0/SCREEN_PIXEL_SIZE).y;
	uv.y = 1.0 - uv.y; // flip
    uv.y *= 0.5;
    uv.x *= 0.45;
	uv.y -= 0.4;
	
	uv = rotation_matrix(yaw_angle) * uv;
	
    uv += bubble(uv, 12.) + bubble(uv, 12.) + bubble(uv, 36.) + bubble(uv, 48.); // add bubbles

    vec3 rd = normalize(vec3(uv, -1.));
    vec3 hitPos;
    float hitT;
    vec3 seaColor = vec3(11,82,142)/255.;
    vec3 color;
    
    // waves
    float dist = raymarch(ro, rd, resolution, hitPos, hitT);
    float diffuse = dot(getNormal(hitPos, resolution), rd) * 0.5 + 0.5;
    color = mix(seaColor, vec3(15,120,152)/255., diffuse);
    color += pow(diffuse, 12.0);
	// refraction
    vec3 ref = normalize(refract(hitPos-lightPos, getNormal(hitPos, resolution), 0.05));
    float refraction = clamp(dot(ref, rd), 0., 1.0);
    color += vec3(245,250,220)/255. * 0.6 * pow(refraction, 1.5);

    vec3 col = vec3(0.);
    col = mix(color, seaColor, pow(clamp(0., 1., dist), 0.2)); // glow edge
    col += vec3(225,230,200)/255. * lightShafts(uv); // light shafts

    // tone map
    col = (col*col + sin(col))/vec3(1.8, 1.8, 1.9);
    
    // vignette
    // inigo quilez - Stop Motion Fox 
    // https://www.shadertoy.com/view/3dXGWB
    vec2 q = FRAGCOORD.xy / resolution.xy;
    col *= 0.7+0.3*pow(16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.2);

    COLOR = vec4(col,1.0);
}

尝试使气泡跟随移动

本来想这么写

在这里插入图片描述

用粒子发射器来发射圆

模拟气泡的样子

但是首先这个就要对海底的 canvasitem 采样,才能做出气泡的通透的效果,这个效果我还没搞懂

然后就是我希望整个海底是可以移动的时候,气泡也跟着移动

粒子发射器发射出来的粒子似乎并不方便实现这个功能

虽然改一下 UV 确实可行,但是如果我想让所有粒子整体跟着摄像机动,并且还可以 repeat 的话,那么我感觉……一时间想不到什么方法

尝试修改原 shadertoy 的气泡尺寸

改 bubble_size 到很大的话,会超出矩形框

请添加图片描述

所以这个矩形框很烦人……理论上来讲,我是在大的 canvasitem 里面画的,不应该是像这样,好像我在单独的 sprite 里面画一样

后面有点看懂了一些

这个气泡的绘制是单纯给 UV 加一个偏移

uv += bubble(uv, bubble_scale); // add bubbles

就能得到类似透射的效果

因为你相当于直接对偏移的地方采样,但是绘制在原来的像素位置

真的很妙啊这个思路

于是我想能不能偏移 uv

uv += vec2(camera_pos.x, camera_pos.y);

但是这样会导致海面出错

请添加图片描述

于是加在 bubble 的参数里面就好了

uv += bubble(uv + 0.1 * vec2(camera_pos.x, camera_pos.y), bubble_scale); // add bubbles

请添加图片描述

气泡之所以增大半径之后会变成矩形,是因为他是 floor 取小数位作为一个新的坐标系了

    vec2 _st = floor(st);
    vec2 bias = vec2(0., 4. * sin(_st.x*128. + t));
    float mask = smoothstep(0.1, 0.2, -cos(_st.x*128. + t));

所以气泡半径就是 0.5 也合理

但是现在这个气泡的这个一列上升会很怪

所以我在想能不能从粒子发射器获得粒子的数据呢

查到了别人的问题

https://www.reddit.com/r/godot/comments/rrrty9/is_it_possible_to_get_positions_of_particles_in/?rdt=50664

so,看上去不行,没有开放这个属性

但是源码很简洁

或许我可以尝试改源码,但是这应该会花一些时间

然后我给 bubble 加上了 size 参数,本来以为我可以过渡三种形态的

	// add bubbles
    uv += bubble(uv + 0.05 * vec2(camera_pos.x, camera_pos.y), mod(0.1 * camera_pos.z + 0.05, 0.3), 30.0);
	uv += bubble(uv + 0.1 * vec2(camera_pos.x, camera_pos.y), mod(0.1 * camera_pos.z + 0.1, 0.3), 20.0);
	uv += bubble(uv + 0.2 * vec2(camera_pos.x, camera_pos.y), mod(0.1 * camera_pos.z + 0.2, 0.3), 5.0);

但是随着前进后退,这个变化还是太奇怪

请添加图片描述
于是放弃

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言笔记(指针的进阶)

目录 1.字符指针 2.指针数组 3.数组指针 3.1.创建数组指针 3.2.&数组名和数组名 1.字符指针 int main() { char ch w;char* pc &ch;const char *p "abcdef";//常量字符串 产生的值就是首元素的地址//常量字符串不能被修改 因此需要加上一个…

go 环境安装

最近搭建AIGC大模型聚合平台&#xff0c;涉及到了go语言&#xff0c;随手整理一下环境安装步骤分享给大家。 1、安装 官网下载地址&#xff1a;https://go.dev/ 1.1 Linux 安装 yum install git -y yum install golang -y yum install gcc -y # 日志工具&#xff0c;如需要…

Web保存状态的手段(请求转发,Cookie的使用)

一&#xff0c;掌握请求转发 请求转发与重定向技术都是跳转页面的途径&#xff0c;但是这两个技术之间也有不同之处。 请求转发更倾向于servlet跳转jsp&#xff0c;而重定向更倾向于servlet跳转到servlet。 1. 常用页面跳转方法2:请求转发(重写URL) RequestDispatcher接口对…

基于SpringBoot+Vue+uniapp微信小程序的教学质量评价系统的详细设计和实现

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

细胞力学需测量,多种方法齐上场,优劣互补要明了

大家好&#xff01;今天我们来了解细胞力学方法的比较研究——《A comparison of methods to assess cell mechanical properties》发表于《Nature Methods》。细胞力学对细胞的多种功能至关重要&#xff0c;然而不同测量方法得到的结果差异较大。本次研究选取了MCF-7细胞&…

用Java爬虫API,轻松获取taobao商品SKU信息

在电子商务的世界里&#xff0c;SKU&#xff08;Stock Keeping Unit&#xff0c;库存单位&#xff09;是商品管理的基础。对于商家来说&#xff0c;SKU的详细信息对于库存管理、价格策略制定、市场分析等都有着重要作用。taobao作为中国最大的电子商务平台之一&#xff0c;提供…

JavaSE——集合4:List接口实现类—LinkedList

目录 一、LinkedList的全面说明 二、LinkedList的底层操作机制 (一)LinkedList添加结点源码 (二)LinkedList删除结点源码 三、LinkedList常用方法 四、ArrayList与LinkedList的选择 一、LinkedList的全面说明 LinkedList底层实现了双向链表和双端队列的特点可以添加任意…

【热门】用ChatGPT做智慧农业云平台——农业ERP管控系统

随着科技的进步,原有农业种植方式已经不能满足社会发展的需要,必须对传统的农业进行技术更新和改造。经过多年的实践,人们总结出一种新的种植方法——温室农业,即“用人工设施控制环境因素,使作物获得最适宜的生长条件,从而延长生产季节,获得最佳的产出”。这种农业生产方式…

“智改数转”转了什么?

万界星空科技专门针对数字化改造申报的MES系统具有显著的技术优势和实施效果&#xff0c;能够为制造型企业提供全方位、高效、可靠的数字化转型支持。项目合作可以私信或者百度上海万界星空科技官网。 “智改数转”是一个综合性的过程&#xff0c;涉及企业多个方面的转型和升…

随机抽取学号

idea 配置 抽学号 浏览器 提交一个100 以内的整数。&#xff0c;后端接受后&#xff0c;根据提供的整数&#xff0c;产生 100 以内的 随机数&#xff0c;返回给浏览器&#xff1f; 前端&#xff1a;提供 随机数范围 &#xff0c;病发送请求后端&#xff1a;处理随机数的产生&…

C 408—《数据结构》算法题基础篇—链表(下)

目录 Δ前言 一、两个升序链表归并为一个降序链表 0.题目&#xff1a; 1.算法设计思想&#xff1a; 2.C语言描述&#xff1a; 3.算法的时间和空间复杂度&#xff1a; 二、两个链表的所有相同值结点生成一个新链表 0.题目&#xff1a; 1.算法设计思想&#xff1a; 2.C语言描述…

DDD重构-实体与限界上下文重构

DDD重构-实体与限界上下文重构 概述 DDD 方法需要不同类型的类元素&#xff0c;例如实体或值对象&#xff0c;并且几乎所有这些类元素都可以看作是常规的 Java 类。它们的总体结构是 Name: 类的唯一名称 Properties&#xff1a;属性 Methods: 控制变量的变化和添加行为 一…

MySQL中 truncate、drop和delete的区别

MySQL中 truncate、drop和delete区别 truncate 执行速度快&#xff0c;删除所有数据&#xff0c;但是保留表结构不记录日志事务不安全&#xff0c;不能回滚可重置自增主键计数器 drop 执行速度较快&#xff0c;删除整张表数据和结构不记录日志事务不安全&#xff0c;不能回…

JavaWeb——Maven(3/8):配置Maven环境(当前工程,全局),创建Maven项目

目录 配置Maven环境 当前工程 全局 创建Maven项目 配置Maven环境 当前工程 选择 IDEA中 File --> Settings --> Build,Execution,Deployment --> Build Tools --> Maven 设置 IDEA 使用本地安装的 Maven&#xff0c;并修改配置文件及本地仓库路径 首先在 IDE…

QtCreator14调试Qt5.15出现 Launching Debugger 错误

1、问题描述 使用QtCreator14调试程序&#xff0c;Launching Debugger 显示红色&#xff0c;无法进入调试模式。 故障现象如下&#xff1a; 使能Debugger Log窗口&#xff0c;显示&#xff1a; 325^error,msg"Error while executing Python code." 不过&#xff…

【软件推荐】信创终端上通过kshutdown实现定时关机 _ 统信 _ 麒麟 _ 方德

往期好文&#xff1a;【功能介绍】麒麟2403支持配置任务栏上的图标“从不合并”啦&#xff01; Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于如何在信创终端系统上通过kshutdown实现定时关机的文章。在日常使用中&#xff0c;定时关机是一个非常实用的功能&am…

Leetcode 841. 钥匙和房间

1.题目基本信息 1.1.题目描述 有 n 个房间&#xff0c;房间按从 0 到 n – 1 编号。最初&#xff0c;除 0 号房间外的其余所有房间都被锁住。你的目标是进入所有的房间。然而&#xff0c;你不能在没有获得钥匙的时候进入锁住的房间。 当你进入一个房间&#xff0c;你可能会在…

uniapp 微信小程序分包操作

1. 在项目根目录创建一个新的目录&#xff0c;名称为分包名称 2. 打开manifest.json&#xff0c;选择源码视图&#xff0c;加入以下代码 "optimization" : {"subPackages" : true } 3. 在pages.json中&#xff0c;pages后面添加分包代码 "subPackag…

tkinter Listbox 列表框实现多列对齐排列并绑定下拉框和滚动条

from tkinter import * from tkinter import ttk, Button, Canvas, Listbox, Entry, LabelFrame, IntVar, Checkbutton, messageboximport win32print root Tk() root.title("tkinter Listbox 列表框实现多列对齐排列") root.geometry(550x450)def callback2(t, eve…

k8s-对命名空间资源配额

对k8s命名空间限制的方法有很多种&#xff0c;今天来演示一下很常用的一种 用的k8s对象就是ResourceQuota 一&#xff1a;创建命名空间 kubectl create ns test #namespace命名空间可以简写成ns 二&#xff1a; 对命名空间进行限制 创建resourcequota vim resourcequ…