Maison interface Web js tutoriel THREE.JS入门教程(3)着色器-下_基础知识

THREE.JS入门教程(3)着色器-下_基础知识

May 16, 2016 pm 05:43 PM

译序
Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D。但是目前这项技术还处在发展阶段,资料极为匮乏,爱好者学习基本要通过Demo源码和Three.js本身的源码来学习。

.简介
这是WebGL着色器教程的后半部分,如果你没看过前一篇,阅读这一篇教程可能会使你感到困惑,建议你翻阅前面的教程。

上一篇结束的时候,我们在屏幕中央画了一个好看的粉红色的球体。现在我要开始创建一些更加有意思的东西了。

在这一篇教程中,我们会先花点时间来加入一个动画循环,然后是顶点attributes变量和一个uniform变量。我们还要加一些varying变量,这样顶点着色器就可以向片元着色器传递信息了。最终的结果是哪个粉红色的球体会从顶部开始向两侧“点燃”,然后作有规律的运动。这有一点迷幻,但是会帮助你对着色器中的三种变量有更好的了解:他们互相联系,实现了整个集合体。当然我们会在Three.js的框架中做这些。
1.模拟光照
让我们更新颜色吧,这样球体看起来就不会是个扁平晦暗的圆了。如果我们想看看Three.js是怎样处理光照的,我敢肯定你会发现这比我们需要的要复杂得多,所以我们先模拟光照吧。你应该浏览一下Three.js中那些奇妙的着色器,还有一些来自最近的一个 Chris Milk 和 Google, Rome 的WebGL项目。
回到着色器,我们要更新顶点着色器来向片元着色器传递顶点的法向量。利用一个varying变量:
复制代码 代码如下:

// 创建一个varying变量vNormal,顶点着色器和片元着色器都包含了该变量
varying vec3 vNormal;
void main() {
// 将vNormal设置为normal,后者是Three.js创建并传递给着色器的attribute变量
vNormal = normal;
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(position, 1.0);
}

在片元着色器中,我们将会创建一个相同变量名的变量,然后将法线向量和另一个表示来自右上方光线的向量点乘,并将结果作用于颜色。最后结果的效果有点像平行光。
复制代码 代码如下:

// 和顶点着色器中一样的变量vNormal
varying vec3 vNormal;
void main() {
// 定义光线向量
vec3 light = vec3(0.5,0.2,1.0);
// 确保其归一化
light = normalize(light);
// 计算光线向量和法线向量的点积,如果点积小于0(即光线无法照到),就设为0
float dProd = max(0.0, dot(vNormal, light));
// 填充片元颜色
gl_FragColor = vec4(dProd, // R
dProd, // G
dProd, // B
1.0); // A
}

使用点积的原因是:两个向量的点积表明他们有多么“相似”。如果两个向量都是归一化的,而且他们的方向一模一样,点积的值就是1;如果两个向量的方向恰巧完全相反,点积的值就是-1。我们所做的就是把点积的值拿来作用到光纤上,所以如果这个点在球体的右上方,点积的值就是1,也就是完全照亮了;而在另一边的点,获得的点积值接近0,甚至到了-1。我们将获得的任何负值都设置为0。当你将数据传入之后,你就会看到最基本的光照效果了。

下面是什么?我们会将顶点的坐标掺和进来。
2.Attribut变量
接下来我要通过Attribute变量为每一个顶点传递一个随机数,这个随机数被用来将顶点沿着法线向量推出去一段距离。新的结果有点像一个怪异的不规则物体,每次刷新页面物体都会随机变化。现在,他还不会动(后面我会让他动起来),但是几次刷新就可以很好地观察到,他的形状是随机的。
让我们开始为顶点着色器加入attribute变量吧:
复制代码 代码如下:

attribute float displacement;
varying vec3 vNormal;
void main() {
vNormal = normal;
// 将随机数displacement转化为三维向量,这样就可以和法线相乘了
vec3 newPosition = position +
normal * vec3(displacement);
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(newPosition, 1.0);
}

你看到什么都没变,因为attribute变量displacement还没有被设定你,所以着色器就使用了0作为默认值。这时displacement还没起作用,但我们马上就要在着色器材质中加上attribute变量了,然后Three.js就会自动地把它们绑在一起运行了。

同时也要注意这样一个事实,我将更新后的位置指定给了一个新的三维向量变量,因为原来的位置变量position,就像所有的attribute变量一样,都是只读的。
3.更新着色器材质
现在我们来更新着色器材质,传入一些东西给attribute对象displacement。记住,attribute对象是和顶点一一对应的,所以我们对球体的每一个顶点都有一个值,就像这样:
复制代码 代码如下:

var attributes = {
displacement: {
type: 'f', // 浮点数
value: [] // 空数组
}
};
var vShader = $('#vertexshader');
var fShader = $('#fragmentshader');
// 创建一个包含attribute属性的着色器材质
var shaderMaterial =
new THREE.MeshShaderMaterial({
attributes: attributes,
vertexShader: vShader.text(),
fragmentShader: fShader.text()
});
// 向displacement中填充随机数
var verts = sphere.geometry.vertices;
var values = attributes.displacement.value;
for(var v = 0; v values.push(Math.random() * 30);
}

这样,就可以看到一个变形的球体了。最Cool的是:所有这些变形都是在GPU中完成的。
4.动起来
要使这东西动起来,应该怎么做?好吧,应该做这两件事情。
一个uniform变量amplitude,在每一帧控制displacement实际造成了多少位移。我们可以使用正弦或余弦函数来在每一帧中生成它,因为这两个函数的取值范围从-1到1。
一个帧循环。

我们需要将这个uniform变量加入到着色器材质中,同时也需要加入到顶点着色器中。先来看顶点着色器:
复制代码 代码如下:

uniform float amplitude;
attribute float displacement;
varying vec3 vNormal;
void main() {
vNormal = normal;
// 将displacement乘以amplitude,当我们在每一帧中平滑改变amplitude时,画面就动起来了
vec3 newPosition =
position +
normal *
vec3(displacement *
amplitude);
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(newPosition, 1.0);
}

然后更新着色器材质:
复制代码 代码如下:

var uniforms = {
amplitude: {
type: 'f', // a float
value: 0
}
};
var vShader = $('#vertexshader');
var fShader = $('#fragmentshader');
// 创建最终的着色器材质
var shaderMaterial =
new THREE.MeshShaderMaterial({
uniforms: uniforms,
attributes: attributes,
vertexShader: vShader.text(),
fragmentShader: fShader.text()
});

我们的着色器也已经就绪了。但我们好像又倒退了一步,屏幕中又只剩下光滑的球了。别担心,这是因为amplitude值设置为0,因为我们将amplitude乘上了displacement,所以现在看不到任何变化。我们还没设置循环呢,所以amplitude只可能是0.

在我们的JavaScript中,需要将渲染过程打包成一个函数,然后用requestAnimationFrame去调用该函数。在这个函数里,我们更新uniform(译者注:即amplitude)的值。
复制代码 代码如下:

var frame = 0;
function update() {
// amplitude来自于frame的正弦值
uniforms.amplitude.value =
Math.sin(frame);
// 更新全局变量frame
frame += 0.1;
renderer.render(scene, camera);
// 指定下一次屏幕刷新时,调用update
requestAnimFrame(update);
}
requestAnimFrame(update);

5.小结
就是它了!你看到球体正在奇怪地脉动着。关于着色器,还有太多的内容没有讲到呢,但是我希望这篇教程能够对你有一些帮助。现在,当你看到一些其他的着色器时,我希望你能够理解它们,而且你应该有信心去创建自己的着色器了!

和往常一样,我将这一课的源码打包了
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Que dois-je faire si je rencontre l'impression de code brouillé pour les reçus en papier thermique frontal? Que dois-je faire si je rencontre l'impression de code brouillé pour les reçus en papier thermique frontal? Apr 04, 2025 pm 02:42 PM

Des questions et des solutions fréquemment posées pour l'impression de billets thermiques frontaux pour le développement frontal, l'impression de billets est une exigence commune. Cependant, de nombreux développeurs mettent en œuvre ...

Qui est payé plus de python ou de javascript? Qui est payé plus de python ou de javascript? Apr 04, 2025 am 12:09 AM

Il n'y a pas de salaire absolu pour les développeurs Python et JavaScript, selon les compétences et les besoins de l'industrie. 1. Python peut être davantage payé en science des données et en apprentissage automatique. 2. JavaScript a une grande demande dans le développement frontal et complet, et son salaire est également considérable. 3. Les facteurs d'influence comprennent l'expérience, la localisation géographique, la taille de l'entreprise et les compétences spécifiques.

Démystifier javascript: ce qu'il fait et pourquoi c'est important Démystifier javascript: ce qu'il fait et pourquoi c'est important Apr 09, 2025 am 12:07 AM

JavaScript est la pierre angulaire du développement Web moderne, et ses principales fonctions incluent la programmation axée sur les événements, la génération de contenu dynamique et la programmation asynchrone. 1) La programmation axée sur les événements permet aux pages Web de changer dynamiquement en fonction des opérations utilisateur. 2) La génération de contenu dynamique permet d'ajuster le contenu de la page en fonction des conditions. 3) La programmation asynchrone garantit que l'interface utilisateur n'est pas bloquée. JavaScript est largement utilisé dans l'interaction Web, les applications à une page et le développement côté serveur, améliorant considérablement la flexibilité de l'expérience utilisateur et du développement multiplateforme.

Comment fusionner les éléments du tableau avec le même ID dans un seul objet en utilisant JavaScript? Comment fusionner les éléments du tableau avec le même ID dans un seul objet en utilisant JavaScript? Apr 04, 2025 pm 05:09 PM

Comment fusionner les éléments du tableau avec le même ID dans un seul objet en JavaScript? Lors du traitement des données, nous rencontrons souvent la nécessité d'avoir le même ID ...

Comment réaliser des effets de défilement de parallaxe et d'animation des éléments, comme le site officiel de Shiseido?
ou:
Comment pouvons-nous réaliser l'effet d'animation accompagné d'un défilement de page comme le site officiel de Shiseido? Comment réaliser des effets de défilement de parallaxe et d'animation des éléments, comme le site officiel de Shiseido? ou: Comment pouvons-nous réaliser l'effet d'animation accompagné d'un défilement de page comme le site officiel de Shiseido? Apr 04, 2025 pm 05:36 PM

La discussion sur la réalisation des effets de défilement de parallaxe et d'animation des éléments dans cet article explorera comment réaliser le site officiel de Shiseido (https://www.shiseido.co.jp/sb/wonderland/) ...

La différence dans Console.Log de sortie Résultat: Pourquoi les deux appels sont-ils différents? La différence dans Console.Log de sortie Résultat: Pourquoi les deux appels sont-ils différents? Apr 04, 2025 pm 05:12 PM

Discussion approfondie des causes profondes de la différence de sortie Console.log. Cet article analysera les différences dans les résultats de sortie de la fonction Console.log dans un morceau de code et expliquera les raisons derrière. � ...

JavaScript est-il difficile à apprendre? JavaScript est-il difficile à apprendre? Apr 03, 2025 am 12:20 AM

Apprendre JavaScript n'est pas difficile, mais c'est difficile. 1) Comprendre les concepts de base tels que les variables, les types de données, les fonctions, etc. 2) Master la programmation asynchrone et les implémenter via des boucles d'événements. 3) Utilisez les opérations DOM et promettez de gérer les demandes asynchrones. 4) Évitez les erreurs courantes et utilisez des techniques de débogage. 5) Optimiser les performances et suivre les meilleures pratiques.

PowerPoint peut-il exécuter JavaScript? PowerPoint peut-il exécuter JavaScript? Apr 01, 2025 pm 05:17 PM

JavaScript peut être exécuté dans PowerPoint et peut être implémenté en appelant des fichiers JavaScript externes ou en intégrant des fichiers HTML via VBA. 1. Pour utiliser VBA pour appeler les fichiers JavaScript, vous devez activer les macros et avoir des connaissances en programmation VBA. 2. ENCHED des fichiers HTML contenant JavaScript, qui sont simples et faciles à utiliser mais sont soumis à des restrictions de sécurité. Les avantages incluent les fonctions étendues et la flexibilité, tandis que les inconvénients impliquent la sécurité, la compatibilité et la complexité. En pratique, l'attention doit être accordée à la sécurité, à la compatibilité, aux performances et à l'expérience utilisateur.

See all articles