【Threejs进阶教程-着色器篇】3. Uniform的基本用法2与基本地球昼夜效果

news2024/9/21 14:45:17

Uniform的基本用法2

  • 关于本Shader教程
  • 前两篇地址,请按顺序学习
  • 本篇使用到的资源
  • 用uniform传递纹理
    • 代码分析
    • texture类型的uniform
    • 在shader中接收uniform
    • texture2D()
      • 处理图片压缩
      • 修改wrapS和wrapT
  • 切换成夜景
    • 效果切换
    • Mix()
  • 昼夜切换升级
    • 改动代码
    • 效果分析
      • 解决球体分界线太过明显的问题
  • 让昼夜动起来
    • 改动代码
    • 最终效果
  • 案例完整源码
  • 如有不明白的,可以在下方留言或者加群

关于本Shader教程

  1. 本教程着重讲解Shadertoy的shader和Threejs的Shader,与原生WebGLShader略有不同,如果需要学习原生WebGL的shader,请参考《WebGL编程指南》
  2. 本人的shader水平也比较基础,文章中所写代码,不一定是最佳的代码,思路也不一定是最好的思路,所以一切本人的Shader教程下,所有的代码及思路以及学习建议均仅供参考,且目前本教程可能不适用于WebGPU,如果有大佬路过看到本人文章,觉得有可以指点之处,可以在下面留言,我们一起进步
  3. 数学水平不行的人,尤其是高中数学都及格不了的,不建议入坑Shader
  4. 本教程会在讲解片元着色器时,使用Shadertoy来编写demo,所以教程中会出现一部分Shadertoy的代码
  5. 本段内容将会出现在本人所有的【进阶教程-着色器篇】的文章中

前两篇地址,请按顺序学习

【Threejs进阶教程-着色器篇】1. Shader入门(ShadertoyShader和ThreejsShader入门)
【Threejs进阶教程-着色器篇】2. Uniform的基本用法与Uniform的调试

本篇使用到的资源

threejs开发包中
three/examples/textures/plantes/earth_atmos_2048.jpg 注意这张图片后缀是jpg!
three/examples/textures/plantes/earth_lights_2048.png
three/examples/textures/transition/transition5.png

用uniform传递纹理

有些时候不是说所有的图形效果都需要用数学去实现,还可以使用贴图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body{
            width:100vw;
            height: 100vh;
            overflow: hidden;
            margin: 0;
            padding: 0;
            border: 0;
        }
    </style>
</head>
<body>
<script type="importmap">
			{
				"imports": {
					"three": "../three/build/three.module.js",
					"three/addons/": "../three/examples/jsm/"
				}
			}
		</script>

<script type="x-shader/x-vertex" id="vertexShader">
    varying vec2 vUv;
    void main(){
        vUv = vec2(uv.x,uv.y);
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        gl_Position = projectionMatrix * mvPosition;
    }

</script>
<script type="x-shader/x-fragment" id="fragmentShader">
    varying vec2 vUv;
    uniform sampler2D uDiffuse1;
    void main(){
        vec4 col = texture2D(uDiffuse1,vUv);
        gl_FragColor = col;
    }
</script>

<script type="module">

    import * as THREE from "../three/build/three.module.js";
    import {OrbitControls} from "../three/examples/jsm/controls/OrbitControls.js";

    window.addEventListener('load',e=>{
        init();
        addMesh();
        render();
    })

    let scene,renderer,camera;
    let orbit;

    function init(){

        scene = new THREE.Scene();
        renderer = new THREE.WebGLRenderer({
            alpha:true,
            antialias:true
        });
        renderer.setSize(window.innerWidth,window.innerHeight);
        document.body.appendChild(renderer.domElement);

        camera = new THREE.PerspectiveCamera(50,window.innerWidth/window.innerHeight,0.1,2000);
        camera.add(new THREE.PointLight());
        camera.position.set(15,15,15);
        scene.add(camera);

        orbit = new OrbitControls(camera,renderer.domElement);
        orbit.enableDamping = true;
        scene.add(new THREE.GridHelper(10,10));
    }

    let uniforms = {
        uDiffuse1:{value:null}
    }

    function addMesh() {

        let textureLoader = new THREE.TextureLoader();

        uniforms.uDiffuse1.value = textureLoader.load('./earth_atmos_2048.jpg');

        let geometry = new THREE.SphereGeometry(5,32,32);
        let material = new THREE.ShaderMaterial({
            uniforms,
            vertexShader:document.getElementById('vertexShader').textContent,
            fragmentShader:document.getElementById('fragmentShader').textContent,
        })
        let mesh = new THREE.Mesh(geometry,material);
        scene.add(mesh);
    }


    function render() {
        renderer.render(scene,camera);
        orbit.update();
        requestAnimationFrame(render);
    }

</script>
</body>
</html>

代码效果
在这里插入图片描述

代码分析

texture类型的uniform

shader允许传递一个texture类型的对象到uniform,这里在threejs中,对应的是 THREE.Texture类型的对象,也就是TexthreLoader读取出来的图片,并转换成的texture实例

注意,一般情况下,图片的使用要考虑异步,本地化的读取效率非常高,不会出现渲染延迟,线上的话,可能会让地球变成一个黑色或者白色的球体

这个uniform的写法有两种,一种是像上面一样先赋值null,然后再读取,另一种是在读取的时候创建uniform的key,任选一个自己喜欢的风格即可,没有太多的要求,只是注意,给uniform赋值要这样写

//如果采用第二种写法,可以这样写
uniforms.uDiffuse1 = {value:texture}

在shader中接收uniform

    varying vec2 vUv;
    uniform sampler2D uDiffuse1; //这里在shader中,对应sampler2D这个类型
    void main(){
        vec4 col = texture2D(uDiffuse1,vUv); // 对图片逐uv取色
        gl_FragColor = col;
    }

texture2D()

texture2D函数的参数有两个,第一个是一个vec2的对象,第二个是一个sampler2D类型的数据
一般前者我们都使用uv,这个就是最基本的贴图代码,读取图片的uv并将颜色给到指定uv的顶点处

我们把几何体换成正方向平面,这样看的更明显一些

在这里插入图片描述
可以看出,在正方形平面的贴图上,图片出现了压缩,这是因为图片本身并不是一个正方形,但是以逐uv的形式来读取了这张图片,所以最终造成了压缩的问题

处理图片压缩

这里我们在shader中,把vUv.x 放大即可

    varying vec2 vUv;
    uniform sampler2D uDiffuse1;
    void main(){
        vec2 uUv = vec2(vUv.x / 2.0, vUv.y);
        vec4 col = texture2D(uDiffuse1,uUv);
        gl_FragColor = col;
    }

我们把uv.x除以2.0,这样我们就只加载 0 < uv.x < 0.5范围内的图片, 0< uv.y < 1的图片,所以我们可以看到,y轴没有变化,而x轴拉回去了
我们也可以继续修改,看看对uv的xy都乘或除2.0的效果怎么样

在这里插入图片描述
发现新的问题了,我们在除以2.0的情况下,我们只取了图片的左下角,但是乘以2.0的时候,并不如我们想的结果那样,平铺四张图

所以这里我们要对纹理做一下处理

修改wrapS和wrapT

        uniforms.uDiffuse1.value = textureLoader.load('./earth_atmos_2048.jpg');
        uniforms.uDiffuse1.value.wrapT = THREE.RepeatWrapping;
        uniforms.uDiffuse1.value.wrapS = THREE.RepeatWrapping;
    varying vec2 vUv;
    uniform sampler2D uDiffuse1;
    void main(){
        vec2 uUv = vec2(vUv.x * 2.0, vUv.y * 2.0);
        vec4 col = texture2D(uDiffuse1,uUv);
        gl_FragColor = col;
    }

在这里插入图片描述

这样,我们就解决了没有平铺图片的问题,这是一种通过shader的方式,来改变图片平铺方式的解决办法

切换成夜景

首先我们引入第二张图片,并改回球体和uv,并额外添加一个 uChange属性

修改代码

    let uniforms = {
        uDiffuse1:{value:null},
        uDiffuse2:{value:null},
        uChange:{value:0.0}
    }

    function addMesh() {

        let textureLoader = new THREE.TextureLoader();

        uniforms.uDiffuse1.value = textureLoader.load('./earth_atmos_2048.jpg');
        uniforms.uDiffuse1.value.wrapT = THREE.RepeatWrapping;
        uniforms.uDiffuse1.value.wrapS = THREE.RepeatWrapping;

        uniforms.uDiffuse2.value = textureLoader.load('./earth_lights_2048.png');
        uniforms.uDiffuse2.value.wrapT = THREE.RepeatWrapping;
        uniforms.uDiffuse2.value.wrapS = THREE.RepeatWrapping;

        let geometry = new THREE.SphereGeometry(5,32,32);
        let material = new THREE.ShaderMaterial({
            uniforms,
            vertexShader:document.getElementById('vertexShader').textContent,
            fragmentShader:document.getElementById('fragmentShader').textContent,
        })
        let mesh = new THREE.Mesh(geometry,material);
        scene.add(mesh);

        let gui = new GUI();
        gui.add(uniforms.uChange,'value',0,1).name('渐变');
    }

片元着色器代码

    varying vec2 vUv;
    uniform sampler2D uDiffuse1;
    uniform sampler2D uDiffuse2;
    uniform float uChange;
    void main(){
        vec4 col = texture2D(uDiffuse2,vUv);
        gl_FragColor = col;
    }

在这里插入图片描述

效果切换

我们现在要做的是,如果uChange = 1 ,则显示白天的贴图,如果uChange = 0,则显示夜晚贴图

    varying vec2 vUv;
    uniform sampler2D uDiffuse1;
    uniform sampler2D uDiffuse2;
    uniform float uChange;
    void main(){
        vec4 col1 = texture2D(uDiffuse1,vUv);
        vec4 col2 = texture2D(uDiffuse2,vUv);
        gl_FragColor = vec4(
            col1.r * uChange + col2.r * (1.0 - uChange),
            col1.g * uChange + col2.g * (1.0 - uChange),
            col1.b * uChange + col2.b * (1.0 - uChange),
            col1.a * uChange + col2.a * (1.0 - uChange)
        );
    }

我们这样想,既然change = 0.1的时候,那么此时图片1的颜色值为最淡,然后图片2的颜色值为最深,对应rgb三个颜色都是这样的结果

在这里插入图片描述

Mix()

但是其实,这个算法,官方早就给你想好了,我们只需使用mix即可,下面两种写法的效果完全一致

//旧代码
        gl_FragColor = vec4(
            col1.r * uChange + col2.r * (1.0 - uChange),
            col1.g * uChange + col2.g * (1.0 - uChange),
            col1.b * uChange + col2.b * (1.0 - uChange),
            col1.a * uChange + col2.a * (1.0 - uChange)
        );
//新代码
gl_FragColor = mix(col2,col1,uChange);

mix是个非常非常常用的函数,主要用来线性混合数据,mix可以适用于很多种类型的数据,也有很多种用法,后续会经常用到和提到mix
在这里插入图片描述

昼夜切换升级

细心的朋友注意到了,这个切换效果,是全地球一起在切换,而并不是在模拟日出日落的那种昼夜切换,所以这个时候我们就要用到特殊的一种混合模式,这里我们加载第三张图,且拿掉uChange这个uniform

改动代码

我们加入第三张贴图,且加入时间变量iTime
由于在shadertoy中的时间变量也是iTime,所以后续所有的教程中,出现的时间变量都会命名为iTime

    let uniforms = {
        uDiffuse1:{value:null},
        uDiffuse2:{value:null},
        uChangeTexture:{value:null},
        iTime:{value:0.01}
    }

    function addMesh() {

        let textureLoader = new THREE.TextureLoader();

        uniforms.uDiffuse1.value = textureLoader.load('./earth_atmos_2048.jpg');
        uniforms.uDiffuse1.value.wrapT = THREE.RepeatWrapping;
        uniforms.uDiffuse1.value.wrapS = THREE.RepeatWrapping;

        uniforms.uDiffuse2.value = textureLoader.load('./earth_lights_2048.png');
        uniforms.uDiffuse2.value.wrapT = THREE.RepeatWrapping;
        uniforms.uDiffuse2.value.wrapS = THREE.RepeatWrapping;

        uniforms.uChangeTexture.value = textureLoader.load('./transition5.png');
        uniforms.uChangeTexture.value.wrapT = THREE.RepeatWrapping;
        uniforms.uChangeTexture.value.wrapS = THREE.RepeatWrapping;


        let geometry = new THREE.SphereGeometry(5,32,32);
        let material = new THREE.ShaderMaterial({
            uniforms,
            vertexShader:document.getElementById('vertexShader').textContent,
            fragmentShader:document.getElementById('fragmentShader').textContent,
        })
        let mesh = new THREE.Mesh(geometry,material);
        scene.add(mesh);
    }


    function render() {
        renderer.render(scene,camera);
        orbit.update();
        requestAnimationFrame(render);
        uniforms.iTime.value += 0.01;
    }

片元着色器改动

    varying vec2 vUv;
    uniform sampler2D uDiffuse1;
    uniform sampler2D uDiffuse2;
    uniform sampler2D uChangeTexture;
    void main(){
        vec4 col1 = texture2D(uDiffuse1,vUv);
        vec4 col2 = texture2D(uDiffuse2,vUv);
        vec4 col3 = texture2D(uChangeTexture,vUv);
        gl_FragColor = mix(col2,col1,col3.r);
    }

效果分析

在这里插入图片描述
在这里插入图片描述

这样,我们看到的效果,就是一边是白天,一边是黑夜的效果了

我们切换回plane,来看看效果演变
在这里插入图片描述
在这里插入图片描述
可以看出,最黑的地方,最终使用的是夜晚的图片,也就是说此处的值,r值是最低的
最白的地方,最终使用的是白天的图片,也就是说此处的值,r值是最高的
中间的部分,随着上图的颜色变化而变化,白色越强的地方,白天图片的强度越高
黑色越强的地方,黑夜图片的强度越高

解决球体分界线太过明显的问题

但是这里有个很明显的问题,就是应用到球体上之后,左右两侧的颜色差距太大,导致了明显的分界线

我们切换回球体,然后对uv做一下处理

首先,我们的图片,是左边黑右边白,那么我们试着移动一下图片的像素,给uv.x - 0.5

此时图片会变成下面圈出来的这一块
在这里插入图片描述
然后,接下来,我们让负数变正数,则左边的这一块变成了,对abs(uv.x - 0.5)
在这里插入图片描述
原先按照正常的取值流程,红框的最左边是-0.5,但是我们给它变成正的了,所以后面会产生镜像效果

但是这一块黑色区域太大,所以我们要把最终结果再乘2,让图片截取到完全白色的区域

在这里插入图片描述
此时,uv.x的取值范围,就变成了 -1 ~1,就变成了上面的图片效果

然后我们带入到代码中试一下

<script type="x-shader/x-fragment" id="fragmentShader">
    varying vec2 vUv;
    uniform sampler2D uDiffuse1;
    uniform sampler2D uDiffuse2;
    uniform sampler2D uChangeTexture;
    void main(){
        vec4 col1 = texture2D(uDiffuse1,vUv);
        vec4 col2 = texture2D(uDiffuse2,vUv);
                                              //对vUv.x - 0.5然后绝对值,再乘2
        vec4 col3 = texture2D(uChangeTexture, vec2(abs(vUv.x - 0.5) * 2.0,vUv.y));
        gl_FragColor = mix(col2,col1,col3.r);
    }
</script>

在这里插入图片描述

让昼夜动起来

改动代码

    varying vec2 vUv;
    uniform sampler2D uDiffuse1;
    uniform sampler2D uDiffuse2;
    uniform sampler2D uChangeTexture;
    uniform float iTime;
    void main(){
        vec4 col1 = texture2D(uDiffuse1,vec2(vUv.x + iTime,vUv.y));
        vec4 col2 = texture2D(uDiffuse2,vec2(vUv.x + iTime,vUv.y));
        vec4 col3 = texture2D(uChangeTexture,vec2(abs(vUv.x - 0.5) * 2.0,vUv.y));
        gl_FragColor = mix(col2,col1,col3.r);
    }

由于col3中的vUv.x已经做了太多处理了,所以我们把跟随时间动的代码,放到了前面两张图上,让前面两张图动起来

然后发现动的实在是太快了,所以我们把运动速度也做了调整

    function render() {
        renderer.render(scene,camera);
        orbit.update();
        requestAnimationFrame(render);
        //旧代码 uniforms.iTime.value += 0.001;
        uniforms.iTime.value += 0.001;
    }

最终效果

在这里插入图片描述

完整效果由于gif图近10M,csdn承受不了,所以就不发了

案例完整源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body{
            width:100vw;
            height: 100vh;
            overflow: hidden;
            margin: 0;
            padding: 0;
            border: 0;
        }
    </style>
</head>
<body>

<script type="importmap">
			{
				"imports": {
					"three": "../three/build/three.module.js",
					"three/addons/": "../three/examples/jsm/"
				}
			}
		</script>

<script type="x-shader/x-vertex" id="vertexShader">
    varying vec2 vUv;
    void main(){
        vUv = vec2(uv.x,uv.y);
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        gl_Position = projectionMatrix * mvPosition;
    }

</script>
<script type="x-shader/x-fragment" id="fragmentShader">
    varying vec2 vUv;
    uniform sampler2D uDiffuse1;
    uniform sampler2D uDiffuse2;
    uniform sampler2D uChangeTexture;
    uniform float iTime;
    void main(){
        vec4 col1 = texture2D(uDiffuse1,vec2(vUv.x + iTime,vUv.y));
        vec4 col2 = texture2D(uDiffuse2,vec2(vUv.x + iTime,vUv.y));
        vec4 col3 = texture2D(uChangeTexture,vec2(abs(vUv.x - 0.5) * 2.0,vUv.y));
        gl_FragColor = mix(col2,col1,col3.r);
    }
</script>

<script type="module">

    import * as THREE from "../three/build/three.module.js";
    import {OrbitControls} from "../three/examples/jsm/controls/OrbitControls.js";

    window.addEventListener('load',e=>{
        init();
        addMesh();
        render();
    })

    let scene,renderer,camera;
    let orbit;

    function init(){

        scene = new THREE.Scene();
        renderer = new THREE.WebGLRenderer({
            alpha:true,
            antialias:true
        });
        renderer.setSize(window.innerWidth,window.innerHeight);
        document.body.appendChild(renderer.domElement);

        camera = new THREE.PerspectiveCamera(50,window.innerWidth/window.innerHeight,0.1,2000);
        camera.add(new THREE.PointLight());
        camera.position.set(15,15,15);
        scene.add(camera);

        orbit = new OrbitControls(camera,renderer.domElement);
        orbit.enableDamping = true;
        scene.add(new THREE.GridHelper(10,10));
    }

    let uniforms = {
        uDiffuse1:{value:null},
        uDiffuse2:{value:null},
        uChangeTexture:{value:null},
        iTime:{value:0.01}
    }

    function addMesh() {

        let textureLoader = new THREE.TextureLoader();

        uniforms.uDiffuse1.value = textureLoader.load('./earth_atmos_2048.jpg');
        uniforms.uDiffuse1.value.wrapT = THREE.RepeatWrapping;
        uniforms.uDiffuse1.value.wrapS = THREE.RepeatWrapping;

        uniforms.uDiffuse2.value = textureLoader.load('./earth_lights_2048.png');
        uniforms.uDiffuse2.value.wrapT = THREE.RepeatWrapping;
        uniforms.uDiffuse2.value.wrapS = THREE.RepeatWrapping;

        uniforms.uChangeTexture.value = textureLoader.load('./transition5.png');
        uniforms.uChangeTexture.value.wrapT = THREE.RepeatWrapping;
        uniforms.uChangeTexture.value.wrapS = THREE.RepeatWrapping;


        let geometry = new THREE.SphereGeometry(5,32,32);
        let material = new THREE.ShaderMaterial({
            uniforms,
            vertexShader:document.getElementById('vertexShader').textContent,
            fragmentShader:document.getElementById('fragmentShader').textContent,
        })
        let mesh = new THREE.Mesh(geometry,material);
        scene.add(mesh);
    }


    function render() {
        renderer.render(scene,camera);
        orbit.update();
        requestAnimationFrame(render);
        uniforms.iTime.value += 0.001;
    }

</script>
</body>
</html>

如有不明白的,可以在下方留言或者加群

如有其他不懂的问题,可以在下方留言,也可以加入qq群咨询,本人的群于2024/7/8日正式创建,群号867120877,欢迎大家来群里交流
在这里插入图片描述

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

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

相关文章

Linux dig命令常见用法

Linux dig命令常见用法 一、dig安装二、dig用法 DIG命令(Domain Information Groper命令)是常用的域名查询工具&#xff0c;通过此命令&#xff0c;你可以实现域名查询和域名问题的定位&#xff0c;对于网络管理员和在域名系统(DNS)领域工作的小伙伴来说&#xff0c;它是一个非…

【大模型LLM面试合集】大语言模型架构_attention

1.attention 1.Attention 1.1 讲讲对Attention的理解&#xff1f; Attention机制是一种在处理时序相关问题的时候常用的技术&#xff0c;主要用于处理序列数据。 核心思想是在处理序列数据时&#xff0c;网络应该更关注输入中的重要部分&#xff0c;而忽略不重要的部分&…

YOLOv8改进 | 注意力机制| 引入多尺度分支来增强特征表征的注意力机制 【CVPR2021】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

顶会FAST24最佳论文|阿里云块存储架构演进的得与失-5.其他话题分享

4.1 可用性威胁与解决方案 挑战1&#xff1a;BlockServer故障影响众多VD 问题描述&#xff1a;单个BlockServer的故障可能会影响到多个虚拟磁盘&#xff08;VDs&#xff09;的正常运作&#xff0c;这是由于传统架构中BlockServer承担了过多的职责&#xff0c;其稳定性直接关系…

Eyes Wide Shut Exploring the Visual Shortcomings of Multimodal LLMs

Eyes Wide Shut? Exploring the Visual Shortcomings of Multimodal LLMs 近两年多模态大模型&#xff08;Multimodal LLM&#xff0c;MLLM&#xff09;取得了巨大的进展&#xff0c;能够基于图片与人类对话&#xff0c;展现出强大的识别甚至推理能力。然而&#xff0c;在某些…

字符串操作(CC++)

字符串操作 1. C语言基本使用字符串操作函数 2. C3. 对比 C语言和C在字符串操作上有很大的不同&#xff0c;这主要是因为C标准库提供了更强大、更易于使用的字符串类&#xff08;std::string&#xff09;&#xff0c;而C语言主要依赖字符数组和一系列标准库函数&#xff08;如s…

Halcon Ean13 一维码读取

一 EAN码介绍 1 EAN码定义: EAN码是国际物品编码协会制定的一种商品用条码&#xff0c;通用于全世界。EAN码符号有标准版&#xff08;EAN-13&#xff09;和缩短版&#xff08;EAN-8&#xff09;两种。标准版表示13位数字&#xff0c;又称为EAN13码&#xff0c;缩短版表示8位数…

SSM慢性病患者健康管理系统-计算机毕业设计源码04877

目 录 摘要 1 绪论 1.1 研究意义 1.2研究目的 1.3论文结构与章节安排 2 慢性病患者健康管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分…

day02_员工管理

文章目录 新增员工需求分析和设计代码开发功能测试代码完善录入的用户名已存在&#xff0c;抛出异常后没有处理新增员工的时候&#xff0c;创建人id和修改人id设置为了固定值ThreadLocal&#xff08;面试题&#xff09; 分页查询问题解决 启用禁用员工账号需求和分析代码设计 编…

分享外贸工作中常用英文标准表达和英文语句

常用英文表达 报拉格斯最低到岸价 quote the lowest price CIF Lagos经营纺织品多年 be in the line of textiles for many years货物受欢迎 the goods are very popular with customers / have met with a warm reception /be well received/accepted/ enjoy a wide populari…

2024年7月2日~2024年7月8日周报

目录 一、前言 二、完成情况 2.1 吴恩达机器学习系列课程 2.1.1 分类问题 2.1.2 假说表示 2.1.3 判定边界 2.2 学习数学表达式 2.3 论文写作情况 2.3.1 题目选取 2.3.2 摘要 2.3.3 关键词 2.3.4 引言部分 2.3.4 文献综述部分 三、下周计划 3.1 存在的问题 3.2 …

Nacos注册中心相关错误记录

文章目录 1&#xff0c;com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:jar:unknown was not found1.1 定位及解决方案1.2&#xff0c;简要说明dependencyManagement的作用 2&#xff0c;nacos启动失败2.1 解决方案 1&#xff0c;com.alibaba.cloud:spring-c…

七大AI绘画软件大比拼!高效且免费!

在当今数字时代&#xff0c;人工智能技术广泛应用于各个行业&#xff0c;包括艺术创作。人工智能绘画软件可以帮助艺术家更快、更有效地创作。然而&#xff0c;市场上人工智能绘画软件的选择也令人眼花缭乱。那么&#xff0c;哪种人工智能绘画软件更好呢&#xff1f;需要明确的…

《UDS协议从入门到精通》系列——图解0x84:安全数据传输

《UDS协议从入门到精通》系列——图解0x84&#xff1a;安全数据传输 一、简介二、数据包格式2.1 服务请求格式2.2 服务响应格式2.2.1 肯定响应2.2.2 否定响应 Tip&#x1f4cc;&#xff1a;本文描述中但凡涉及到其他UDS服务的&#xff0c;均提供专栏内文章链接跳转方式以便快速…

平安消保在行动 | 守护每一个舒心笑容 不负每一场双向奔赴

“要时刻记得以消费者为中心&#xff0c;把他们当做自己的朋友&#xff0c;站在他们的角度去思考才能更好地解决问题。” 谈及如何成为一名合格的消费者权益维护工作人员&#xff0c;平安养老险深圳分公司负责咨诉工作的庞宏霄认为&#xff0c;除了要具备扎实的专业技能和沟通…

大舍传媒:如何在海外新闻媒体发稿报道摩洛哥?

引言 作为媒体行业的专家&#xff0c;我将分享一些关于在海外新闻媒体发稿报道摩洛哥的干货教程。本教程将带您深入了解三个重要的新闻媒体平台&#xff1a;Mediterranean News、Morocco News和North African News。 地中海Mediterranean News Mediterranean News是一个知名…

景芯SoC训练营DFT debug

景芯训练营VIP学员在实践课上遇到个DFT C1 violation&#xff0c;导致check_design_rule无法通过&#xff0c;具体报错如下&#xff1a; 遇到这个问题第一反映一定是确认时钟&#xff0c;于是小编让学员去排查add_clock是否指定了时钟&#xff0c;指定的时钟位置是否正确。 景芯…

Spring AOP源码篇四之 数据库事务

了解了Spring AOP执行过程&#xff0c;再看Spring事务源码其实非常简单。 首先从简单使用开始, 演示Spring事务使用过程 Xml配置&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema…

SpringBoot的热部署和日志体系

SpringBoot的热部署 每次修改完代码&#xff0c;想看效果的话&#xff0c;不用每次都重新启动代码&#xff0c;等待项目重启 这样就可以了 JDK官方提出的日志框架&#xff1a;Jul log4j的使用方式&#xff1a; &#xff08;1&#xff09;引入maven依赖 &#xff08;2&#x…

Qt QWizard新建向导实例

使用QWizard做新建向导&#xff0c;最简单的实例 class MyWizard : public QWizard { public: MyWizard(QWidget* parent nullptr); QWizardPage* createFirstPage(); QWizardPage* createSecondPage(); QWizardPage* createThirdPage(); }; MyWizard::MyWizard(QWidget* par…