当前位置: 首页 > news >正文

WebGL Varing变量的作用和内插过程,及执行Varing时涉及的图形装配、光栅化、颜色插值、片元着色器执行机制等详解

目录

前言

在 WebGL 或 OpenGL 中,“varying” 是一种用于在顶点着色器和片元着色器之间传递数据的特殊类型的变量。它允许在顶点着色器对数据进行处理后,在片元着色器中使用该处理后的数据进行进一步计算。 

彩色三个点 

​编辑

彩色三个点示例代码

varying变量使用规范 

彩色三角形

几何形状的装配和光栅化

红色三角形示例代码

顶点坐标 --> 图形装配 --> 光栅化 --> 执行片元着色器

图元装配过程

光栅化过程

顶点着色器和片元着色器之间图形装配和光栅化的过程详解

第1步:执行顶点着色器,缓冲区对象中的第1个坐标(0.0,0.5)被传递给attribute变量a_Position。一旦一个顶点的坐标被赋值给了gl_Position,它就进入了图形装配区域,并暂时储存在那里。你应该还记得,我们仅仅显式地向a_Position赋了x分量和y分量,所以向z分量和w分量赋的是默认值,进入图形装配区域的坐标其实是(0.0,0.5,0.0,1.0)。

第2步:再次执行顶点着色器,类似地,将第2个坐标(-0.5,-0.5,0.0,1.0)传入并储存在装配区。

第3步:第3次执行顶点着色器,将第3个坐标(0.5,-0.5,0.0,1.0)传入并储存在装配区。现在,顶点着色器执行完毕,三个顶点坐标都已经处在装配区了。

第4步:开始装配图形。使用传入的点坐标,根据gl.drawArrays()的第一个参数信息(gl.TRIANGLES)来决定如何装配。本例使用三个顶点来装配出一个三角形。

第5步:显示在屏幕上的三角形是由片元(像素)组成的,所以还需要将图形转化为片元,这个过程被称为光栅化(rasterization)。光栅化之后,我们就得到了组成这个三角形的所有片元。在上图中的最后一步,你可以看到光栅化后得到的组成三角形的片元。

调用片元着色器

做个试验:根据片元的位置来确定片元颜色

gl.drawingBufferWidth / gl.drawingBufferHeight

显示效果

varying变量的作用和内插过程

varying变量的行为

​编辑varying变量的内插​编辑

颜色值的内插

总结 


前言

在 WebGL 或 OpenGL 中,“varying” 是一种用于在顶点着色器和片元着色器之间传递数据的特殊类型的变量。它允许在顶点着色器对数据进行处理后,在片元着色器中使用该处理后的数据进行进一步计算。 

彩色三个点 

彩色三个点示例代码

// 顶点着色器
var VSHADER_SOURCE ='attribute vec4 a_Position;\n' +'attribute vec4 a_Color;\n' +'varying vec4 v_Color;\n' + // varying 变量'void main() {\n' +'  gl_Position = a_Position;\n' +'  gl_PointSize = 10.0;\n' +'  v_Color = a_Color;\n' +  // 将数据传给片元着色器'}\n';// 片元着色器
var FSHADER_SOURCE ='precision mediump float;\n' + // 设置varing精度'varying vec4 v_Color;\n' +    // 从顶点着色器接受数据'void main() {\n' +'  gl_FragColor = v_Color;\n' +'}\n';function main() {var canvas = document.getElementById('webgl');var gl = getWebGLContext(canvas);// 设置顶点的坐标和颜色var n = initVertexBuffers(gl);gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.POINTS, 0, n);
}function initVertexBuffers(gl) {var verticesColors = new Float32Array([// 顶点坐标和颜色0.0,  0.5,  1.0,  0.0,  0.0, -0.5, -0.5,  0.0,  1.0,  0.0, 0.5, -0.5,  0.0,  0.0,  1.0, ]);var n = 3; // 顶点数量// 创建缓冲区对象var vertexColorBuffer = gl.createBuffer();  if (!vertexColorBuffer) {console.log('Failed to create the buffer object');return false;}// 将顶点坐标和颜色写入缓冲区对象gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);var FSIZE = verticesColors.BYTES_PER_ELEMENT;// 获取a_Position的存储位置,分配缓冲区并开启var a_Position = gl.getAttribLocation(gl.program, 'a_Position');gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0);gl.enableVertexAttribArray(a_Position);  // 开启变量// 获取a_Color的存储位置,分配缓冲区并开启var a_Color = gl.getAttribLocation(gl.program, 'a_Color');gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2);gl.enableVertexAttribArray(a_Color);  // 开启缓冲区分配return n;
}

varying变量使用规范 

 在顶点着色器中,我们声明了attribute变量a_Color用以接收颜色数据(第4行),然后声明了新的varying变量v_Color,该变量负责将颜色值将被传给片元着色器(第5行)。注意,varying变量只能是float(以及相关的vec2,vec3,vec4,mat2,mat3和mat4)类型的。

我们将a_Color变量的值直接赋给之前声明的v_Color变量(第9行)。 

那么,片元着色器该如何接收这个变量呢?答案很简单,只需要在片元着色器中也声明一个(与顶点着色器中的那个varying 变量同名)varying变量就可以了:

在WebGL中,如果顶点着色器与片元着色器中有类型和命名都相同的varying变量,那么顶点着色器赋给该变量的值就会被自动地传入片元着色器,如下图所示。 

所以,顶点着色器赋给v_Color变量的值(第9行)被传递给了片元着色器中的v_Color变量,然后片元着色器将v_Color赋值给gl_FragColor,这样每个顶点的颜色将被修改(第17行)。 

数组verticesColor中有两种不同类型的数据(坐标和颜色)。现在的颜色有3个分量值,所以每个顶点所占字节数是FSIZE*5,需要修改相应的gl.vertexAttribPointer()函数的stride参数和offset参数(第53和58行)。

最后,执行绘图命令(第27行),在浏览器中绘制了红、蓝、绿三个点。

彩色三角形

让我们来看看将gl.drawArrays()函数的第一个参数改成gl.TRIANGLES后会怎样(第27行)

程序的结果如下图所示,程序绘制了一个颜色平滑过渡的、三个角各是红、绿、蓝颜色的三角形。

我们只改变了一个参数,程序的运行结果却从三个不同颜色的孤立的点变成了一个颜色平滑过渡的三角形。到底发生了什么?

几何形状的装配和光栅化

为了简单起见,这里拿一个红色三角形的代码来解释

红色三角形示例代码

 我们在initVertexBuffers()函数中将顶点坐标写入了缓冲区对象(第50行和第52行),然后将缓冲区对象分配给a_Position变量(第74行)。最后调用gl.drawArrays()执行顶点着色器(第46行)。当顶点着色器执行时,缓冲区中的三个顶点坐标依次传给了a_Position变量(第4行),再赋值给gl_Position(第6行),这样WebGL系统就可以根据顶点坐标进行绘制。在片元着色器中,我们将红色的RGBA值(1.0,0.0,0.0,1.0)赋给gl_FragColor,这样就画出了一个红色的三角形。

可是直到现在,你还是不明白这究竟是如何做到的?在你向gl_Position给出了三角形的三个顶点的坐标时,片元着色器又怎样才能进行所谓的逐片元操作呢?

如下图显示了问题所在,程序向gl_Position给出了三个顶点的坐标,谁来确定这三个点就是三角形的三个顶点?最终,为了填充三角形内部,谁来确定哪些像素需要被着色?谁来负责调用片元着色器,片元着色器又是怎样处理每个片元的?

顶点坐标 --> 图形装配 --> 光栅化 --> 执行片元着色器

 在顶点着色器和片元着色器,有这样两个步骤:

  • 图元装配过程

  这一步的任务是,将孤立的顶点坐标装配成几何图形。几何图形的类别由gl.drawArrays()函数的第一个参数决定。

  • 光栅化过程

  这一步的任务是,将装配好的几何图形转换为片元。

上图所示,gl_Position实际上是几何图形装配(geometric shape assembly)阶段的输入数据。注意,几何图形装配过程又被称为图元装配过程(primitive assembly process),因为被装配出的基本图形(点、线、面)又被称为图元(primitives)。 

顶点着色器和片元着色器之间图形装配和光栅化的过程详解

第1步:执行顶点着色器,缓冲区对象中的第1个坐标(0.0,0.5)被传递给attribute变量a_Position。一旦一个顶点的坐标被赋值给了gl_Position,它就进入了图形装配区域,并暂时储存在那里。你应该还记得,我们仅仅显式地向a_Position赋了x分量和y分量,所以向z分量和w分量赋的是默认值,进入图形装配区域的坐标其实是(0.0,0.5,0.0,1.0)。

第2步:再次执行顶点着色器,类似地,将第2个坐标(-0.5,-0.5,0.0,1.0)传入并储存在装配区。

第3步:第3次执行顶点着色器,将第3个坐标(0.5,-0.5,0.0,1.0)传入并储存在装配区。现在,顶点着色器执行完毕,三个顶点坐标都已经处在装配区了。

第4步:开始装配图形。使用传入的点坐标,根据gl.drawArrays()的第一个参数信息(gl.TRIANGLES)来决定如何装配。本例使用三个顶点来装配出一个三角形。

第5步:显示在屏幕上的三角形是由片元(像素)组成的,所以还需要将图形转化为片元,这个过程被称为光栅化(rasterization)。光栅化之后,我们就得到了组成这个三角形的所有片元。在上图中的最后一步,你可以看到光栅化后得到的组成三角形的片元。

上图为了示意,只显示了10个片元。实际上,片元数目就是这个三角形最终在屏幕上所覆盖的像素数。如果修改了gl.drawArrays()的第1个参数,那么第4步的图形装配、第5步的片元数目和位置就会相应地变化。比如说,如果这个参数是gl.LINE,程序就会使用前两个点装配出一条线段,舍弃第3个点;如果是gl.LINE_LOOP,程序就会将三个点装配成为首尾相接的折线段,并光栅化出一个空心的的三角形(不产生中间的像素)。

调用片元着色器

一旦光栅化过程结束后,程序就开始逐片元调用片元着色器。在下图中,片元着色器被调用了10次,每调用一次,就处理一个片元(为了整洁,下图省略了中间步骤)。对于每个片元,片元着色器计算出该片元的颜色,并写入颜色缓冲区。直到第15步最后一个片元被处理完成,浏览器就会显示出最终的结果。

红色三角形代码中的片元着色器将每个片元的颜色都指定为红色,如下所示。因此,浏览器就绘制出了一个红色的三角形。

做个试验:根据片元的位置来确定片元颜色

这样可以证明片元着色器对每个片元都执行了一次。光栅化过程生成的片元都是带有坐标信息的,调用片元着色器时这些坐标信息也随着片元传了进去,我们可以通过片元着色器中的内置变量来访问片元的坐标(如下表)。 

 为了证明片元着色器是逐片元执行的,我们修改了原红色三角形程序的第12行(gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0)),如下所示:

从片元着色器的程序代码中可见,三角形中每个片元的颜色,其红色分量和蓝色分量都是根据片元的位置计算得到的。注意,canvas中的Y轴方向和WebGL系统中的Y轴方向是相反的,而且WebGL中的颜色分量值区间为0.0到1.0,所以你需要将Y轴坐标除以<canvas>元素的高度(400像素)以将其压缩到0.0到1.0之间。我们将gl.drawingBufferWidth(颜色缓冲区的宽度)gl.drawingBufferHeight(颜色缓冲区的高度)的值传给uniform变量u_Width和u_Height。下面彩色三角形显示了程序的运行结果:一个三角形,像素颜色由像素的位置决定,从左上方到右下方呈现一个渐变效果。 

gl.drawingBufferWidth / gl.drawingBufferHeight

  gl.uniform1f(u_Width, gl.drawingBufferWidth); // 颜色缓冲区的宽度,下面同理 高度gl.uniform1f(u_Height, gl.drawingBufferHeight);

显示效果

由于片元颜色取决于它的坐标位置,所以很自然地,片元颜色会随着片元位置逐渐变化,三角形呈现平滑的颜色渐变效果。

varying变量的作用和内插过程

现在,我们已经了解了顶点着色器与片元着色器之间的几何图形装配和光栅化过程,明白了WebGL系统是怎样逐片元执行片元着色器的了。

回到上面彩色三角形程序,这个程序也可以用刚学到的知识来解释为什么在顶点着色器中只是指定了每个顶点的颜色,最后得到了一个具有渐变色彩效果的三角形呢?事实上,我们把顶点的颜色赋值给了顶点着色器中的varying变量v_Color,它的值被传给片元着色器中的同名、同类型变量(即片元着色器中的varying变量v_Color),如下图所示。但是,更准确地说,顶点着色器中的v_Color变量在传入片元着色器之前经过了内插过程。所以,片元着色器中的v_Color变量和顶点着色器中的v_Color变量实际上并不是一回事,这也正是我们将这种变量称为“varying”(变化的)变量的原因。

varying变量的行为

varying变量的内插

 更准确地说,在红色三角形中,我们在varying变量中为三角形的3个不同顶点指定了3种不同颜色,而三角形表面上这些片元的颜色值都是WebGL系统用这3个顶点的颜色内插出来的。

例如,考虑一条两个端点的颜色不同的线段。一个端点的颜色为红色(1.0,0.0,0.0),而另一个端点的颜色为蓝色(0.0,0.0,1.0)。我们在顶点着色器中向varying变量v_Color赋上这两个颜色(红色和蓝色),那么WebGL就会自动地计算出线段上的所有点(片元)的颜色,并赋值给片元着色器中的varying变量v_Color(如下图所示)。

颜色值的内插

在这个例子中RGBA中的R值从1.0降低为0.0,而B值则从0.0上升至1.0,线段上的所有片元的颜色值都会被恰当地计算出来——这个过程就被称为内插过程(interpolation process)。一旦两点之间每个片元的新颜色都通过这种方式被计算出来后,它们就会被传给片元着色器中的v_Color变量。 

再来看红色三角形的程序代码。在顶点着色器中,我们将三角形的3个顶点的颜色赋给了varying变量v_Color(第9行),然后片元着色器中的varying变量 v_Color就接收到了内插之后的片元颜色。在片元着色器中,我们把片元的颜色赋值给gl_FragColor变量(第19行),这样就绘制出了一个彩色的三角形,同理,每一个varying变量都会经过这样的内插过程

总结 

顶点着色器和片元着色器之间的过程非常重要。光栅化也是三维图形学的关键技术之一,它负责将矢量的几何图形转变为栅格化的片元(像素)。图形被转化为片元之后,我们就可以在片元着色器内做更多的事情,如为每个片元指定不同的颜色。颜色可以内插出来,也可以直接编程指定。 

相关文章:

WebGL Varing变量的作用和内插过程,及执行Varing时涉及的图形装配、光栅化、颜色插值、片元着色器执行机制等详解

目录 前言 在 WebGL 或 OpenGL 中,“varying” 是一种用于在顶点着色器和片元着色器之间传递数据的特殊类型的变量。它允许在顶点着色器对数据进行处理后,在片元着色器中使用该处理后的数据进行进一步计算。 彩色三个点 ​编辑 彩色三个点示例代码…...

赢在起跑线:战略定位咨询带来的核心价值

在企业的发展之路上,三个核心问题始终伴随着我们:我们是谁?我们要做什么?我们要如何做?在业务的马拉松比赛中,开始时的位置至关重要。而战略定位咨询就是帮助企业赢在起跑线的关键。那么什么是战略定位?战略定位包含…...

【链表OJ 11】复制带随机指针的链表

前言: 💥🎈个人主页:​​​​​​Dream_Chaser~ 🎈💥 ✨✨刷题专栏:http://t.csdn.cn/UlvTc ⛳⛳本篇内容:力扣上链表OJ题目 目录 leetcode138. 复制带随机指针的链表 1. 问题描述 2.代码思路: 2.1拷贝节点插入到…...

Jenkins自动构建(Gitee)

Gitee简介安装JenkinsCLI https://blog.csdn.net/tongxin_tongmeng/article/details/132632743 安装Gitee jenkins-cli install-plugin gitee:1.2.7 # https://plugins.jenkins.io/gitee/releases获取安装命令(稍作变更) JenkinsURL Dashboard-->配置-->Jenkins Locatio…...

nginx离线安装

ngixn的离线安装(centos7) 需要的依赖 gcc、gcc-c pcre-8.42.tar.gz zlib-1.2.11.tar.gz openssl-1.1.1s.tar.gz perl-5.28.0.tar.gz 在进行nginx离线安装时,首先查看系统是否安装 gcc、gcc-c,若没有进行安装,请先进行安装 gcc -v #查…...

Oracle Merge Into ORA-00001: unique constaint violated问题

最近使用Datax同步进行定时数据同步,并在同步完之后进行回调sql进行统计操作。对应的ORACLE表结构如下: create table DATA_STAT_DAY ( DATA_DATE DATE, ID VARCHAR2(2), NAME VARCHAR2(2), CLASSNO VARCHAR2(2), SCORES NUMBER(16,0) );CREATE UNIQU…...

javaScript:DOM中的CSS操作

目录 1.style 属性获取元素写在行间的样式 2.getComputedStyle(元素对象,null)可以获取元素的非行间样式 3.案例(定义一个div和按钮,每点击一次按钮div宽度增加) 效果预览图 代码实现 在 JavaScript 中,可以通过…...

2023最新UI工作室官网个人主页源码/背景音乐/随机壁纸/一言

2023最新UI工作室官网个人主页源码/支持背景音乐/随机壁纸/一言 功能介绍: 载入动画 站点简介 Hitokoto 一言 日期及时间 实时天气 时光进度条 音乐播放器 移动端适配 打开文件;index.html和setting.json修改替换你的相关信息&a…...

常用命令之mysql命令之show命令

一、mysql show命令简介 mysql数据库中show命令是一个非常实用的命令,SHOW命令用于显示MySQL数据库中的信息。它可以用于显示数据库、表、列、索引和用户等各种对象的信息。我们常用的有show databases,show tables,show full processlist等&…...

iOS接入IJKPlayer遇到的问题汇总

这里有一个我自己编译的IJKMediaFramework,能解决目前Github上反馈很多常见的IJKPlayer使用问题(包含播放异常,UI主线程Crash等),替换自己项目中的IJKMediaFramework即可链接: https://pan.baidu.com/s/1UO-YfN_1YIDOX81bgW8bag?pwdvq4u 提取…...

【LeetCode题目详解】第八章 贪心算法 part06 738.单调递增的数字 968.监控二叉树 (day37补)

本文章代码以c为例&#xff01; 一、力扣第738题&#xff1a;单调递增的数字 题目&#xff1a; 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数…...

代码随想录算法训练营Day48 | 198.打家劫舍,213.打家劫舍II,337.打家劫舍III | Day 20 复习

198.打家劫舍 文章链接 | 题目链接 | 视频链接 C解法 class Solution { public:int rob(vector<int>& nums) {vector<int> dp (nums.size(), 0);if (nums.size() 0){return 0;}if (nums.size() 1){return nums[0];}dp[0] nums[0];dp[1] max(nums[0]…...

Spring Boot @Validated 和Javax的@Valid配合使用

一、Validated 和Valid有什么用 Validation 和Valid 常常配合使用对传输的参数进行数据校验的注解&#xff0c;并通过配置全局异常处理器进行合理化的提示&#xff0c;增加用户的体验 并且Validated可以通过分组来指定什么时候触发什么样的参数校验&#xff08;这里看一下就行…...

论文复现--lightweight-human-pose-estimation-3d-demo.pytorch(单视角多人3D实时动作捕捉DEMO)

分类&#xff1a;动作捕捉 github地址&#xff1a;https://github.com/Daniil-Osokin/lightweight-human-pose-estimation-3d-demo.pytorch 所需环境&#xff1a; Windows10&#xff0c;conda 4.13.0&#xff1b; 目录 conda环境配置安装Pytorch全家桶安装TensorRT&#xff08;…...

在Windows下设置将EXE开机自启动

在Windows下设置将EXE开机自启动&#xff0c;有多种方法。以下是两种常用的方法&#xff1a; 方法一&#xff1a;通过注册表 打开“运行”&#xff08;快捷键&#xff1a;Win R&#xff09;&#xff0c;输入&#xff1a;reg add HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windo…...

反序列化漏洞及漏洞复现

文章目录 渗透测试漏洞原理不安全的反序列化1. 序列化与反序列化1.1 引例1.2 序列化实例1.2.1 定义一个类1.2.2 创建对象1.2.3 反序列化1.2.4 对象注入 2. 漏洞何在2.1 漏洞触发 3. 反序列化漏洞攻防3.1 PHP反序列化实例3.1.1 漏洞利用脚本3.1.2 漏洞利用3.1.3 获取GetShell 3.…...

软件工程笔记001

2023年9月5日&#xff0c;周二上午 软件工程的目标 软件工程的目标是成功地开发一个软件&#xff1a; 较低的开发成本能按时交付软件开发出来的软件该有的功能都有开发出来的软件运行效率高开发出来的软件可靠性高开发出来的软件易于维护 软件的生存周期 概念 软件生存周期…...

java进行系统的限流实现--Guava RateLimiter、简单计数、滑窗计数、信号量、令牌桶

本文主要介绍了几种限流方法&#xff1a;Guava RateLimiter、简单计数、滑窗计数、信号量、令牌桶&#xff0c;漏桶算法和nginx限流等等 1、引入guava集成的工具 pom.xml 文件 <dependency><groupId>com.google.guava</groupId><artifactId>guava<…...

《86盒应用于家居中控》——实现智能家居的灵动掌控

近年来&#xff0c;智能家居产品受到越来越多消费者的关注&#xff0c;其便捷、舒适的生活方式让人们对未来生活充满期待。作为智能家居方案领域的方案商&#xff0c;启明智显生产设计的86盒凭借出色的性能和良好的用户体验&#xff0c;成功应用于家居中控系统&#xff0c;让家…...

【LeetCode】328. 奇偶链表

328. 奇偶链表&#xff08;中等&#xff09; 思路 如果链表为空&#xff0c;则直接返回链表。 对于原始链表&#xff0c;每个节点都是奇数节点或偶数节点。头节点是奇数节点&#xff0c;头节点的后一个节点是偶数节点&#xff0c;相邻节点的奇偶性不同。因此可以将奇数节点和偶…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...

Monorepo架构: Nx Cloud 扩展能力与缓存加速

借助 Nx Cloud 实现项目协同与加速构建 1 &#xff09; 缓存工作原理分析 在了解了本地缓存和远程缓存之后&#xff0c;我们来探究缓存是如何工作的。以计算文件的哈希串为例&#xff0c;若后续运行任务时文件哈希串未变&#xff0c;系统会直接使用对应的输出和制品文件。 2 …...