Cube Map 系列之:手把手教你 实现 立方体贴图

news2024/12/24 2:13:03

什么是Cube Map

在开始立方体贴图之前,我们先简单了解下cube map。

cube map 包含了六个纹理,分别表示了立方体的六个面;
相较二维的纹理使用坐标uv来获取纹理信息,这里我们需要使用三维的方向向量来获取纹理信息(一些地方称为法线 normal,但我认为方向向量更合理)。

Cube Map可以用于:

  • 正方体表面贴图
  • 用于环境贴图(反射贴图),模拟镜面反射结果
  • 天空盒

什么是立方体贴图

故名思意,将cube map的六个纹理分别贴到立方体的六个面上,就算立方体贴图。效果如下:

  • 纹理图
    在这里插入图片描述
  • 立方体贴图
    效果如图

我们下面从两个部分来进行讲解

  • 使用文本生成对应的纹理图
  • 使用cubemap将对应的纹理分别贴到立方体的六个面上

生成立方体纹理

  • 纹理图效果如下
    在这里插入图片描述
  • 关键代码(使用canvas生成对应的图片)
function generateFace(ctx, faceColor, textColor, text){
    const {width, height} = ctx.canvas;
    ctx.fillStyle = faceColor;
    ctx.fillRect(0, 0, width, height);
    ctx.font = `${width * 0.7}px sans-serif`;
    ctx.textAlign = 'center';
    ctx.textBaseline = "middle";
    ctx.fillStyle = textColor;
    ctx.fillText(text, width / 2, height / 2);
}
  • 关键代码(组织数据,获得图片,并使用html显示)
const ctx = document.createElement("canvas").getContext("2d");

ctx.canvas.width = 128;
ctx.canvas.height = 128;

const faceInfos = [
    { faceColor: '#F00', textColor: '#0FF', text: '+X' },
    { faceColor: '#FF0', textColor: '#00F', text: '-X' },
    { faceColor: '#0F0', textColor: '#F0F', text: '+Y' },
    { faceColor: '#0FF', textColor: '#F00', text: '-Y' },
    { faceColor: '#00F', textColor: '#FF0', text: '+Z' },
    { faceColor: '#F0F', textColor: '#0F0', text: '-Z' },
];

faceInfos.forEach((faceInfo) => {
    const { faceColor, textColor, text } = faceInfo;
    generateFace(ctx, faceColor, textColor, text);

    ctx.canvas.toBlob((blob => {
        const img = new Image();
        img.src = URL.createObjectURL(blob);
        document.body.appendChild(img);
    }))
})
}

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CubeMap</title>
</head>
<body>
<script>

    function main(){
        const ctx = document.createElement("canvas").getContext("2d");

        ctx.canvas.width = 128;
        ctx.canvas.height = 128;

        const faceInfos = [
            { faceColor: '#F00', textColor: '#0FF', text: '+X' },
            { faceColor: '#FF0', textColor: '#00F', text: '-X' },
            { faceColor: '#0F0', textColor: '#F0F', text: '+Y' },
            { faceColor: '#0FF', textColor: '#F00', text: '-Y' },
            { faceColor: '#00F', textColor: '#FF0', text: '+Z' },
            { faceColor: '#F0F', textColor: '#0F0', text: '-Z' },
        ];

        faceInfos.forEach((faceInfo) => {
            const { faceColor, textColor, text } = faceInfo;
            generateFace(ctx, faceColor, textColor, text);

            ctx.canvas.toBlob((blob => {
                const img = new Image();
                img.src = URL.createObjectURL(blob);
                document.body.appendChild(img);
            }))
        })
    }

    function generateFace(ctx, faceColor, textColor, text){
        const {width, height} = ctx.canvas;
        ctx.fillStyle = faceColor;
        ctx.fillRect(0, 0, width, height);
        ctx.font = `${width * 0.7}px sans-serif`;
        ctx.textAlign = 'center';
        ctx.textBaseline = "middle";
        ctx.fillStyle = textColor;
        ctx.fillText(text, width / 2, height / 2);
    }

    main()

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


将纹理贴到立方体

关键代码说明

1. 创建gl

const canvas = document.querySelector("#canvas");
const gl = canvas.getContext("webgl");

2. 初始化片元着色器和顶点着色器

const V_SHADER_SOURCE = '' +
    'attribute vec4 a_position;' +
    'uniform mat4 u_matrix;' +
    'varying vec3 v_normal;' +
    'void main(){' +
    'gl_Position = u_matrix * a_position;' +
    'v_normal = normalize(a_position.xyz);' +
    '}'

const F_SHADER_SOURCE = '' +
    'precision mediump float;' +
    'varying vec3 v_normal;' +
    'uniform samplerCube u_texture;' +
    'void main(){' +
    'gl_FragColor = textureCube(u_texture, normalize(v_normal));' +
    '}'
    
if (!initShaders(gl, V_SHADER_SOURCE, F_SHADER_SOURCE)){
	console.log('Failed to initialize shaders.');
	return;
}

3. 配置attribute信息a_position

// 获取a_position
const positionLocation = gl.getAttribLocation(gl.program, "a_position");

// 创建数据buffer 并绑定pisitions数据
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);

// 开启顶点属性 并设置其对应的属性 从而从数据buffer中获取对应的数据
gl.enableVertexAttribArray(positionLocation);
const size = 3;
const type = gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);

4. 配置uniform信息u_texture

// 创建纹理对象 并绑定到 cube_map
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);

// 生成纹理图片 并调用 gl.texImage2D进行绑定
const ctx = document.createElement("canvas").getContext("2d");

ctx.canvas.width = 128;
ctx.canvas.height = 128;

const faceInfos = [
    { target: gl.TEXTURE_CUBE_MAP_POSITIVE_X, faceColor: '#F00', textColor: '#0FF', text: '+X' },
    { target: gl.TEXTURE_CUBE_MAP_NEGATIVE_X, faceColor: '#FF0', textColor: '#00F', text: '-X' },
    { target: gl.TEXTURE_CUBE_MAP_POSITIVE_Y, faceColor: '#0F0', textColor: '#F0F', text: '+Y' },
    { target: gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, faceColor: '#0FF', textColor: '#F00', text: '-Y' },
    { target: gl.TEXTURE_CUBE_MAP_POSITIVE_Z, faceColor: '#00F', textColor: '#FF0', text: '+Z' },
    { target: gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, faceColor: '#F0F', textColor: '#0F0', text: '-Z' },
];

faceInfos.forEach((faceInfo) => {
    const { target, faceColor, textColor, text } = faceInfo;
    generateFace(ctx, faceColor, textColor, text);

    // Upload the canvas to the cube map face.
    const level = 0;
    const internalFormat = gl.RGBA;
    const format = gl.RGBA;
    const type = gl.UNSIGNED_BYTE;
    gl.texImage2D(target, level, internalFormat, format, type, ctx.canvas);

})

// 生成cubemap纹理 并进行传递
gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
const textureLocation = gl.getUniformLocation(gl.program, "u_texture");
gl.uniform1i(textureLocation, 0);

5. 动态更新uniform信息u_matrix

// 获取每一帧的时间差
time *= 0.001;
const deltaTime = time - then;
then = time;

// 计算沿x y 轴的旋转角度
modelXRotationRadians += -0.7 * deltaTime;
modelYRotationRadians += -0.4 * deltaTime;

// 计算投影矩阵
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const projectionMatrix =
    m4.perspective(fieldOfViewRadians, aspect, 1, 2000);
    
// 计算相机矩阵
const cameraPosition = [0, 0, 2];
const up = [0, 1, 0];
const target = [0, 0, 0];
const cameraMatrix = m4.lookAt(cameraPosition, target, up);

// 获取view矩阵
const viewMatrix = m4.inverse(cameraMatrix);

// 计算得到vp矩阵
const viewProjectionMatrix = m4.multiply(projectionMatrix, viewMatrix);

// 返回有旋转角度的 vp矩阵
let matrix = m4.xRotate(viewProjectionMatrix, modelXRotationRadians);
return m4.yRotate(matrix, modelYRotationRadians);

6. 开始绘制

const matrixLocation = gl.getUniformLocation(gl.program, "u_matrix");

function drawScene(time){
    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
    gl.enable(gl.CULL_FACE);
    gl.enable(gl.DEPTH_TEST);

    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    gl.useProgram(gl.program);

    // 动态更新矩阵信息
    gl.uniformMatrix4fv(matrixLocation, false, updateMatrix(time));

    // Draw the geometry.
    gl.drawArrays(gl.TRIANGLES, 0, 6 * 6);

    requestAnimationFrame(drawScene);
}

效果

在这里插入图片描述

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CubeMap</title>
</head>
<body>
<script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
<canvas id="canvas" style="height: 256px; width: 246px"></canvas>
<script>
    const V_SHADER_SOURCE = '' +
        'attribute vec4 a_position;' +
        'uniform mat4 u_matrix;' +
        'varying vec3 v_normal;' +
        'void main(){' +
        'gl_Position = u_matrix * a_position;' +
        'v_normal = normalize(a_position.xyz);' +
        '}'

    const F_SHADER_SOURCE = '' +
        'precision mediump float;' +
        'varying vec3 v_normal;' +
        'uniform samplerCube u_texture;' +
        'void main(){' +
        'gl_FragColor = textureCube(u_texture, normalize(v_normal));' +
        '}'

    function main(){
        // Get A WebGL context
        /** @type {HTMLCanvasElement} */
        const canvas = document.querySelector("#canvas");
        const gl = canvas.getContext("webgl");
        if (!gl) {
            return;
        }

        if (!initShaders(gl, V_SHADER_SOURCE, F_SHADER_SOURCE)){
            console.log('Failed to initialize shaders.');
            return;
        }

        const matrixLocation = gl.getUniformLocation(gl.program, "u_matrix");

        setGeometry(gl, getGeometry());

        setTexture(gl)


        function radToDeg(r) {
            return r * 180 / Math.PI;
        }

        function degToRad(d) {
            return d * Math.PI / 180;
        }

        const fieldOfViewRadians = degToRad(60);
        let modelXRotationRadians = degToRad(0);
        let modelYRotationRadians = degToRad(0);

        // Get the starting time.
        let then = 0;

        requestAnimationFrame(drawScene);

        function drawScene(time){
            gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
            gl.enable(gl.CULL_FACE);
            gl.enable(gl.DEPTH_TEST);

            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

            gl.useProgram(gl.program);


            gl.uniformMatrix4fv(matrixLocation, false, updateMatrix(time));

            // Draw the geometry.
            gl.drawArrays(gl.TRIANGLES, 0, 6 * 6);

            requestAnimationFrame(drawScene);
        }

        function updateMatrix(time){
            time *= 0.001;
            const deltaTime = time - then;
            then = time;

            modelXRotationRadians += -0.7 * deltaTime;
            modelYRotationRadians += -0.4 * deltaTime;
            // Compute the projection matrix
            const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
            const projectionMatrix =
                m4.perspective(fieldOfViewRadians, aspect, 1, 2000);

            const cameraPosition = [0, 0, 2];
            const up = [0, 1, 0];
            const target = [0, 0, 0];

            // Compute the camera's matrix using look at.
            const cameraMatrix = m4.lookAt(cameraPosition, target, up);

            // Make a view matrix from the camera matrix.
            const viewMatrix = m4.inverse(cameraMatrix);

            const viewProjectionMatrix = m4.multiply(projectionMatrix, viewMatrix);

            let matrix = m4.xRotate(viewProjectionMatrix, modelXRotationRadians);
            return m4.yRotate(matrix, modelYRotationRadians);
        }

    }

    function generateFace(ctx, faceColor, textColor, text){
        const {width, height} = ctx.canvas;
        ctx.fillStyle = faceColor;
        ctx.fillRect(0, 0, width, height);
        ctx.font = `${width * 0.7}px sans-serif`;
        ctx.textAlign = 'center';
        ctx.textBaseline = "middle";
        ctx.fillStyle = textColor;
        ctx.fillText(text, width / 2, height / 2);
    }

    /**
     * create a program object and make current
     * @param gl GL context
     * @param vShader  a vertex shader program (string)
     * @param fShader   a fragment shader program(string)
     */
    function initShaders(gl, vShader, fShader){
        const program = createProgram(gl, vShader, fShader);
        if (!program){
            console.log("Failed to create program");
            return false;
        }

        gl.useProgram(program);
        gl.program = program;

        return true;
    }

    /**
     * create a program object and make current
     * @param gl GL context
     * @param vShader  a vertex shader program (string)
     * @param fShader   a fragment shader program(string)
     */
    function createProgram(gl, vShader, fShader){
        const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vShader);
        const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fShader);

        if (!vertexShader || !fragmentShader){
            return null;
        }

        const program = gl.createProgram();
        if (!program){
            return null;
        }

        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);

        gl.linkProgram(program);

        const linked = gl.getProgramParameter(program, gl.LINK_STATUS);
        if (!linked){
            const error = gl.getProgramInfoLog(program);
            console.log('Failed to link program: ' + error);
            gl.deleteProgram(program);
            gl.deleteShader(vertexShader);
            gl.deleteShader(fragmentShader);
        }
        return program;
    }

    /**
     *
     * @param gl GL context
     * @param type  the type of the shader object to be created
     * @param source    shader program (string)
     */
    function loadShader(gl, type, source){
        const shader = gl.createShader(type);
        if (shader == null){
            console.log('unable to create shader');
            return null;
        }

        gl.shaderSource(shader, source);

        gl.compileShader(shader);

        const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
        if (!compiled){
            const error = gl.getShaderInfoLog(shader);
            console.log('Failed to compile shader: ' + error);
            gl.deleteShader(shader);
            return null;
        }

        return shader;
    }


    function getGeometry(){
        return new Float32Array(
            [
                -0.5, -0.5, -0.5,
                -0.5, 0.5, -0.5,
                0.5, -0.5, -0.5,
                -0.5, 0.5, -0.5,
                0.5, 0.5, -0.5,
                0.5, -0.5, -0.5,

                -0.5, -0.5, 0.5,
                0.5, -0.5, 0.5,
                -0.5, 0.5, 0.5,
                -0.5, 0.5, 0.5,
                0.5, -0.5, 0.5,
                0.5, 0.5, 0.5,

                -0.5, 0.5, -0.5,
                -0.5, 0.5, 0.5,
                0.5, 0.5, -0.5,
                -0.5, 0.5, 0.5,
                0.5, 0.5, 0.5,
                0.5, 0.5, -0.5,

                -0.5, -0.5, -0.5,
                0.5, -0.5, -0.5,
                -0.5, -0.5, 0.5,
                -0.5, -0.5, 0.5,
                0.5, -0.5, -0.5,
                0.5, -0.5, 0.5,

                -0.5, -0.5, -0.5,
                -0.5, -0.5, 0.5,
                -0.5, 0.5, -0.5,
                -0.5, -0.5, 0.5,
                -0.5, 0.5, 0.5,
                -0.5, 0.5, -0.5,

                0.5, -0.5, -0.5,
                0.5, 0.5, -0.5,
                0.5, -0.5, 0.5,
                0.5, -0.5, 0.5,
                0.5, 0.5, -0.5,
                0.5, 0.5, 0.5,

            ]);

    }
    // Fill the buffer with the values that define a cube.
    function setGeometry(gl, positions) {
        const positionLocation = gl.getAttribLocation(gl.program, "a_position");

        const positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);

        gl.enableVertexAttribArray(positionLocation);
        const size = 3;
        const type = gl.FLOAT;
        const normalize = false;
        const stride = 0;
        const offset = 0;
        gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);

    }


    function setTexture(gl){

        // Create a texture.
        const texture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);

        const ctx = document.createElement("canvas").getContext("2d");

        ctx.canvas.width = 128;
        ctx.canvas.height = 128;

        const faceInfos = [
            { target: gl.TEXTURE_CUBE_MAP_POSITIVE_X, faceColor: '#F00', textColor: '#0FF', text: '+X' },
            { target: gl.TEXTURE_CUBE_MAP_NEGATIVE_X, faceColor: '#FF0', textColor: '#00F', text: '-X' },
            { target: gl.TEXTURE_CUBE_MAP_POSITIVE_Y, faceColor: '#0F0', textColor: '#F0F', text: '+Y' },
            { target: gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, faceColor: '#0FF', textColor: '#F00', text: '-Y' },
            { target: gl.TEXTURE_CUBE_MAP_POSITIVE_Z, faceColor: '#00F', textColor: '#FF0', text: '+Z' },
            { target: gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, faceColor: '#F0F', textColor: '#0F0', text: '-Z' },
        ];

        faceInfos.forEach((faceInfo) => {
            const { target, faceColor, textColor, text } = faceInfo;
            generateFace(ctx, faceColor, textColor, text);

            // Upload the canvas to the cube map face.
            const level = 0;
            const internalFormat = gl.RGBA;
            const format = gl.RGBA;
            const type = gl.UNSIGNED_BYTE;
            gl.texImage2D(target, level, internalFormat, format, type, ctx.canvas);

        })

        gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
        // Tell the shader to use texture unit 0 for u_texture
        const textureLocation = gl.getUniformLocation(gl.program, "u_texture");
        gl.uniform1i(textureLocation, 0);
    }

    main()

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


参考资料

WebGL Cubemaps

WebGL Environment Maps (reflections)

WebGL SkyBox

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

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

相关文章

力扣---LeetCode20. 有效的括号(栈)

文章目录 前言&#x1f31f;一、20. 有效的括号&#x1f31f;二、链接&#x1f31f;三、方法&#xff1a;栈实现&#x1f30f;3.1思路&#xff1a;&#x1f30f;3.2代码&#xff1a; &#x1f31f;四、补充&#xff1a;&#x1f63d;总结 前言 &#x1f467;个人主页&#xff1…

springboot+java高校教师学术成果管理系统-idea

功能介绍项目介绍Spring框架是Java平台的一个开放源代码的Full-stack(全栈)应用程序框架&#xff0c;和控制翻转容器的实现。Spring框架的一些核心功能理论&#xff0c;可以用于所有Java应用&#xff0c;Spring还为Java EE构建的Web应用提供大量的扩展支持。Spring框架没有实现…

python使用基础 pycharm代码的git同步

我们大家在编写代码的时候经常会遇到各种版本的控制问题。为此版本控制工具是每一个编写代码的同志均需要面临的问题。目前&#xff0c;业内已经有非常成熟的解决方案&#xff0c;比如我们常说的github、gitee等。由于国内网络原因&#xff0c;本文以gitee为例进行使用说明。 1…

基于SpringCloud的分布式网上商城的设计与实现

背景 经过网上调查和搜集数据,我们可以发现商城管理方面的系统并不是相当普及,在分布式架构商城管理方面的可以有许多改进。实际上如今信息化成为一个未来的趋势或者可以说在当前现代化的城市典范中,信息化已经成为主流,开发一个分布式架构网上商城系统一方面的可能会更合乎时…

chatgpt赋能Python-python3_7怎么安装pil

如何在Python3.7中安装PIL&#xff1f; Python3.7是一种流行的编程语言&#xff0c;广泛应用于机器学习、Web开发、数据科学等领域。PIL(Python Imaging Library)是一种Python图像处理库&#xff0c;它提供了丰富的图像处理功能&#xff0c;能够对图像进行缩放、旋转、裁剪等操…

chatgpt赋能Python-python3_8怎么调成黑色背景

如何将Python3.8调整为黑色背景 Python是一种高级编程语言&#xff0c;常用于开发Web应用程序和科学计算。Python3.8是其最新的版本&#xff0c;随着其市场份额的增加&#xff0c;越来越多的程序员对其进行学习和使用。对于那些想要使他们的编程环境更加现代化和个性化的程序员…

060:cesium设置网格Grid材质

第060个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中设置网格材质,请参考源代码,了解GridMaterialProperty的应用。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共93行)相关API参考:专栏目标示例效…

挂机宝搭建教程

nokvm主控面板推荐操作系统版本 Centos7.6.1810 &#xff08;纯净的操作系统&#xff0c;无其他软件环境&#xff09; 主控面板硬件要求配置&#xff1a; - 最低要求 推荐配置 内存 2G 2G CPU - - 带宽 不低于2M 2M 磁盘 / 分区不少于100GB 100GB 主控面板安装&#xff1…

关于shrio的动态授权

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、关于表的搭建1.表介绍二、配置shiroFilterFactoryBean 的权限访问三、配置doGetAuthorizationInfo的授权信息前言 其实一开始的写过一次关于shrio的动态授权但是那个是单表实现的不是特别完…

chatgpt赋能Python-python3_9_1怎么安装

Python 3.9.1 安装指南 介绍 Python是一种高级编程语言&#xff0c;具有简洁、易读、易学、可扩展等特点。它是一种面向对象的编程语言&#xff0c;支持多种编程范式&#xff0c;如面向过程编程、函数式编程、面向对象编程等&#xff0c;也支持各种不同的编程领域&#xff0c…

26-jQuery-概述和下载使用

一、什么是 jQuery&#xff1f; jQuery 是一款流行的 JavaScript 框架&#xff0c;被广泛应用于 Web 开发中。它简化了 DOM 操作、事件处理、动画效果等常见任务&#xff0c;提供了丰富的 API 和插件&#xff0c;让开发者能够快速地实现各种功能。jQuery设计的宗旨是"wri…

6G 第六代移动通信和sub6G第五代移动通信的中低频段

“ 6G&#xff1a;第六代移动通信&#xff0c;概念被炒得火热&#xff0c;却一直不冷不热&#xff0c; 受限于功率和传输距离等&#xff0c;很难落地。” “ sub6G&#xff1a;第五代移动通信的中低频段&#xff0c;虽然已部署了很多&#xff0c; 却受限于功耗、成本、杀手级…

使用Keras构建分类问题的MLP神经网络——用于糖尿病预测

大家好&#xff0c;我是带我去滑雪&#xff01; Keras 是一个用于构建和训练深度学习模型的高级 API&#xff0c;它基于 Python编写&#xff0c;并能够运行于 TensorFlow, CNTK, 或者 Theano 等深度学习框架之上。Keras简化了深度神经网络的构建流程&#xff0c;让用户能够更加…

基于Springboot的漫画网站

开发技术介绍 B/S架构 B/S结构是目前使用最多的结构模式&#xff0c;它可以使得系统的开发更加的简单&#xff0c;好操作&#xff0c;而且还可以对其进行维护。使用该结构时只需要在计算机中安装数据库&#xff0c;和一些很常用的浏览器就可以了。浏览器就会与数据库进行信息…

chatgpt赋能Python-python3_7_2怎么安装

Python 3.7.2 安装指南 Python 是一种广泛使用的计算机编程语言&#xff0c;在科学计算、数据处理、网络编程、人工智能等领域都有广泛应用。而 Python 3.7.2 是 Python 3 系列的一个重要版本。在本文中&#xff0c;我们将介绍如何在各种操作系统上安装 Python 3.7.2。 安装步…

chatgpt赋能Python-python3_8降到3_7

Python 3.8降级到3.7&#xff1a;这是否是一个明智的决策&#xff1f; Python 3.8是Python语言的最新版本&#xff0c;拥有许多显著的改进和新功能。然而&#xff0c;许多开发者们发现3.8版本并非适用于每个项目&#xff0c;因此他们可能会想要降级回Python 3.7。本文将探讨降…

5.19黄金持续下跌能否抄底做多?后市如何布局

近期有哪些消息面影响黄金走势&#xff1f;今日黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周四(5月18日)&#xff0c;美市盘中&#xff0c;现货黄金价格跌创4月21日以来新低至1952.01美元/盎司&#xff0c;迹象表明华府和国会可能就提高美国债务上限达成协…

使用CGImageRef创建图片及实现图片区域裁剪(附源码)

一 CGImageRef和UIImage的互相转化 CGImageRef 是一个结构体指针&#xff0c;通过CGImageRef可以获得UIImage的所有参数&#xff0c;比如像素宽高、颜色通道位深、像素点位深、像素点字节排列及读取顺序等信息&#xff0c;CGImageRef与UIImage的互相转化如下&#xff1a; UII…

GEE:计算每个斑块(超像素、对象)内的特征/统计值

作者:CSDN @ _养乐多_ 在遥感图像分析中,斑块(或对象)是指具有相似像素值的区域,通常代表地物或景观要素。通过计算斑块的特征,我们可以获得关于这些区域的有用信息,从而进行更深入的分析和研究。在本文中,我们将介绍如何使用Google Earth Engine(GEE)平台计算每个斑…

深入理解Java虚拟机:JVM高级特性与最佳实践-总结-7

深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践-总结-7 类文件结构概述无关性的基石 虚拟机类加载机制概述类加载的时机 类文件结构 代码编译的结果从本地机器码转变为字节码&#xff0c;是存储格式发展的一小步&#xff0c;却是编程语言发展的一大步 概述 我们写的程…