three.js就不过多介绍了 可以看另一篇文章 总结就是场景  相机  和 渲染器

学起来 也比较轻松

后来看到了着色器 给我整懵乐了  一会一个API  一会一个API 都没见过 然后就一点点去学习 真的是费了好大劲了 需要知道很多新东西 才能初步知道和使用着色器

当然如果只是简单的使用着色器  比如就画一个点  加个颜色还是很容易的

我想做的是一个几个顶点确定一个平面 并且颜色是渐变色的

(之前还好奇渐变色是怎么做的 就是 顶点间的颜色不同 两个顶点间就会有过渡色了)

上最后效果图

要想知道着色器的使用 确实需要了解一下webgl 因为是用它的底层实现的 不然很多基本的概念很模糊

webgl 其实就和canvas差不多 都是用来绘画的

他的用法 例子  推荐一篇文章 初学者很适合

【WebGL】简单入门教程_小沈曰的博客-CSDN博客

建议看一遍 然后 我再用大白话解释一遍 以及总结一下 不然初学者可能会问 为什么使用这个API

1首先要想使用webgl 就要有canvs画布

2 获取到画布元素的基于webgl上下文环境对象  可以把这个当做webgl(可能概念不是那么准确不较真的话是可以这么认为的)

3  一个webgl 最少两个着色器 当然我也只是试了两个着色器  一个是顶点着色器 一个是片段着色器

顶点着色器 是描述顶点的  片段着色器是用来描述颜色的 (当前我是这么用的)

如果涉及到了变量 需要注意的是 都是将变量传递到顶点着色器  再在着色器内 赋值给两个共用的变量

里面的变量声明 有三个标识  我反正没纠结他 就当做 public  private这种表明一下是什么变量吧

attribute,varying 这种

var vertShader = gl.createShader(gl.VERTEX_SHADER)

var fragShader = gl.createShader(gl.FRAGMENT_SHADER)

4 声明好两个着色器以后 就要把代码段传进去

gl.shaderSource(fragShader, FSHADER_SOURCE)

gl.shaderSource(vertShader, VSHADER_SOURCE)

5 传进去后 就要编译代码段 类似执行里面的预言main函数

gl.compileShader(fragShader)

gl.compileShader(vertShader)

6任何的着色器都需要一个启动程序

创建启动程序  然后 将两个着色器加进去   然后 将两个着色器连接起来

var shaderProgram = gl.createProgram()

//分别附加两个已编译好的着色器对象

gl.attachShader(shaderProgram, vertShader)

gl.attachShader(shaderProgram, fragShader)

//链接两个附件加好的着色器程序

gl.linkProgram(shaderProgram)

gl.useProgram(shaderProgram)

7 然后就可以绘画了 无语的是绘画这里还有个坑 第一个参数代表了绘画的类型  图形 线和点都是不一样的

gl.drawArrays(gl.TRIANGLES, 0, 3)

8不使用变量的话 这里就结束了

使用变量的话

需要一个中间第三方 缓存区 将变量的值赋值给第三方 然后 再从第三方去取

可以理解为不可以直接将我们的js 的变量传给webgl使用

流程就是

创建一个缓存区

然后绑定缓存区  其实就是定义他的类型

得到webgl执行程序的变量 这个是我们js理解的那种变量 不是具体的值 只是声明得一个变量

然后将变量值赋值  ( 使用这个API 会直接将缓存区的值赋值到变量中 第一个参数是数字是说第几个变量 webgl自己算出来的 )

开启变量的使用就可以了

var vertexBuffer = gl.createBuffer()

//说明缓存对象保存的类型

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)

//写入坐标数据

gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

//获取到数组中单个元素的字节数

var FSIZE = vertices.BYTES_PER_ELEMENT

//获取到顶点着色器中变量

var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position')

//将坐标值赋值给变量

gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0)

//开启变量值的使用

gl.enableVertexAttribArray(a_Position)

代码

<body><canvas id="cvs" width="200" height="200" style="border: dashed 1px red">你的浏览器不支持画布元素</canvas><script type="text/javascript">//获取画布元素var cvs = document.getElementById('cvs')//获取到元素的上下文环境对象var gl = cvs.getContext('webgl')//顶点着色器变量var VSHADER_SOURCE =//使用存储限定符定义一个接受顶点坐标的变量'attribute vec4 a_Position;' +'attribute vec4 a_Color;' +'varying vec4 v_Color;' +'void main() {' +//定义点的坐标并转换成变量保存'gl_Position = a_Position; ' +'v_Color = a_Color; ' +'} '//片段着色器变量var FSHADER_SOURCE ='precision mediump float;' +'varying vec4 v_Color;' +'void main() {' +//设置图形像素的颜色并保存'gl_FragColor = v_Color ;' +'}'//新建一个用于装顶点字符串的着色器对象var vertShader = gl.createShader(gl.VERTEX_SHADER)//加载保存好的顶点代码字符串变量gl.shaderSource(vertShader, VSHADER_SOURCE)//编译顶点着色器gl.compileShader(vertShader)//新建一个用于装片段字符串的着色器对象var fragShader = gl.createShader(gl.FRAGMENT_SHADER)//加载保存好的片段代码字符串变量gl.shaderSource(fragShader, FSHADER_SOURCE)//编译片段着色器gl.compileShader(fragShader)//新建一个程序var shaderProgram = gl.createProgram()//分别附加两个已编译好的着色器对象gl.attachShader(shaderProgram, vertShader)gl.attachShader(shaderProgram, fragShader)//链接两个附件加好的着色器程序gl.linkProgram(shaderProgram)//开启程序的使用gl.useProgram(shaderProgram)//定义一个类型数组保存顶点坐标值var vertices = new Float32Array([//  x,   y,   red, green, blue0.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 vertexBuffer = gl.createBuffer()//说明缓存对象保存的类型gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)//写入坐标数据gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)//获取到数组中单个元素的字节数var FSIZE = vertices.BYTES_PER_ELEMENT//获取到顶点着色器中变量var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position')//将坐标值赋值给变量gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0)//开启变量值的使用gl.enableVertexAttribArray(a_Position)//获取到顶点着色器中变量var a_Color = gl.getAttribLocation(shaderProgram, 'a_Color')//将坐标值赋值给变量gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2)//开启变量值的使用gl.enableVertexAttribArray(a_Color)//绘制指定位置的图形gl.drawArrays(gl.TRIANGLES, 0, 3)</script>
</body>

这是webgl 的简单使用

three.js的 着色器 底层是他  但是使用却不完全一样的

首先声明好three的要素对象  场景 相机 渲染器

最简单的 是可以只传坐标 着色器都不写的 因为three已经写好了

可是我想传颜色 就需要 我们自己写一下了

说一下流程

首先定义颜色和坐标

然后给几何体设置这两个属性 (然后在main函数里面这两个就是默认的变量了)

然后定义着色器 因为颜色是变量需要传进去  所以没办法  只能定义着色器了

这里用到了gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0)

gl_FragColor = vec4(vColor, 1.0);

1 注意 两个共用的变量使用    varying  来声明

2 projectionMatrix * modelViewMatrix * vec4(position, 1.0) 这个算出来的就是世界坐标

在这个场景中有各种各样的坐标系  这是几个坐标系的转化  可以这么简单的记 这就是转化公式 到了世界坐标系

3 vertexColors: true, 要想颜色生效需要这个属性

4 必须加;

5 三点确定一个平面如果需要更多的点做一个矩形而不是三角形 则需要geometry.setIndex()

需要特别注意的事四个点的方向必须是这四个0123 否则渲染不出来

three.js(13)-三角形面 - 简书

img.png

我们把图形的顶点做个索引编号,其中0,1,2顶点可以确定一个三角形面,而2,3,0可以再确定一个三角形面,二者合起来就是一个完整的矩形了。

   var index = [0,1,2,2,3,0];

最后的代码

<template><div id="my-three"></div>
</template>
<script lang="ts" setup>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { onMounted } from "vue";//创建一个三维场景
const scene = new THREE.Scene();
//创建一个物体(形状)
const geometry = new THREE.BufferGeometry();
const points = [0, 0, 5, 5, 0, 5, -5, 5, 0];
// const points=[]
// points.push(2.5,2.5,0)
// points.push(-2.5,2.5,0)
// points.push(0,0,2.5)
geometry.setAttribute("position", new THREE.Float32BufferAttribute(points, 3));
const colors = [1, 0, 0, 6.6613381, 1, 0, 0, 6.661, 1];geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
//创建材质(外观)
const material = new THREE.ShaderMaterial({vertexShader: `varying vec3 vColor;void main() {vColor = color;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);}`,fragmentShader: `varying vec3 vColor;void main() {gl_FragColor = vec4(vColor, 1.0);}`,side: THREE.FrontSide,blending: THREE.AdditiveBlending,depthTest: false,transparent: true,vertexColors: true,
});
//创建一个网格模型对象
const mesh = new THREE.Mesh(geometry, material); //网络模型对象Mesh
//把网格模型添加到三维场景
scene.add(mesh); //网络模型添加到场景中
mesh.position.set(0, 0, 0);//添加光源 //会照亮场景里的全部物体(氛围灯),前提是物体是可以接受灯光的,这种灯是无方向的,即不会有阴影。
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
const light = new THREE.PointLight("yellow", 1); //点光源,color:灯光颜色,intensity:光照强度scene.add(ambient);
light.position.set(200, 300, 400);scene.add(light);//创建一个透视相机,窗口宽度,窗口高度
const width = window.innerWidth,height = window.innerHeight;
const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);//设置相机位置  相机的位置
camera.position.set(300, 300, 300);
//设置相机方向  相机的摄像头对准的位置
camera.lookAt(0, 0, 0);//创建辅助坐标轴
const axesHelper = new THREE.AxesHelper(200); //参数200标示坐标系大小,可以根据场景大小去设置
scene.add(axesHelper);//创建一个WebGL渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //设置渲染区尺寸
renderer.render(scene, camera); //执行渲染操作、指定场景、相机作为参数const controls = new OrbitControls(camera, renderer.domElement); //创建控件对象
controls.addEventListener("change", () => {renderer.render(scene, camera); //监听鼠标,键盘事件
});
onMounted(() => {document.getElementById("my-three")?.appendChild(renderer.domElement);
});
</script>
<style scoped></style>

three.js的着色器(巨详细 初学者 大白话)相关推荐

  1. 小朱opengl学习笔记(三)------着色器的详细学习

    上篇博客,主要是介绍了Opengl的大致使用流程,由于中间过程可能比较复杂, 所以今天笔者首先梳理一遍整个的流程. 祭宝图哈. 上篇博客我们的重点是放在由 顶点数据-->顶点着色器 的这个过程上 ...

  2. Three.js进阶篇之4 - 着色器

    "渲染"(Rendering)是即使非计算机专业的都不会觉得陌生的词,虽然在很多人说这个词的时候,并不清楚"渲染"究竟意味着什么.相反,"着色器&qu ...

  3. 使用着色器在WebGL3D场景中呈现行星表面地形

    实验目的:按照一定规律生成类地行星地表地形区块,并用合理的方式将地形块显示出来 涉及知识:Babylon.js引擎应用.着色器编程.正态分布.数据处理.canvas像素操作 github地址:http ...

  4. Turing渲染着色器网格技术分析

    Turing渲染着色器网格技术分析 图灵体系结构通过使用 网格着色器 引入了一种新的可编程几何着色管道.新的着色器将计算编程模型引入到图形管道中,因为协同使用线程在芯片上直接生成紧凑网格( meshl ...

  5. 着色器的细节层次技术 Shader Level of Detail

    Shader Level of Detail (LOD) works by only using shaders or subshaders that have their LOD value les ...

  6. Windows 8 Directx 开发学习笔记(十四)使用几何着色器实现三角形细分

    几何着色器是从DirectX 10才引入的着色器,是一个可选阶段,位于顶点着色器和像素着色器阶段之间.顶点着色器以顶点作为输入数据,而几何着色器以完整的图元作为输入数据,像点.直线.三角形等.之所以引 ...

  7. 《Android 应用案例开发大全(第3版)》——第2章,第2.8节壁纸中的着色器开发...

    本节书摘来自异步社区<Android 应用案例开发大全(第3版)>一书中的第2章,第2.8节壁纸中的着色器开发,作者 吴亚峰 , 苏亚光 , 于复兴,更多章节内容可以访问云栖社区" ...

  8. VTK 学习----3D基础知识-着色器和图形管道

    2.5 着色器和图形管道 2.5.1 图形管道 在三维绘图引擎中,一切物体都在三维空间,但屏幕和窗口是2D像素阵列,因此三维引擎的大部分工作是将所有3D坐标转换为合适屏幕的2D像素.将3D坐标转换为2 ...

  9. 什么是着色器/Threejs如何使用着色器/Threejs使用着色器实现平面网格的动态效果案例

    1,什么是着色器 着色器(Shader)是计算机图形学中的一个重要概念,它是在 GPU 上运行的程序,用于计算三维场景中每个像素的颜色和其他属性. 着色器通常分为两种类型:顶点着色器和片元着色器.顶点 ...

最新文章

  1. JDBC第一篇之获得数据库连接
  2. 默认标题栏字体_不喜欢Windows10上的默认系统字体,可以这样更改
  3. C#中获取当前时间字符串给文件命名防止重复
  4. 软考-信息系统项目管理师-量化的项目管理
  5. c# 结构体 4字节对齐_【专题4:平时遇到的问题】 之 【3.由结构体字节对齐引发的通信故障】...
  6. win7重置密码的方法
  7. vim基础学习之自动补全功能
  8. 游戏开发热门技术浅析
  9. POI导出换行和水平居中
  10. 当心!你的NAS设备正成为勒索软件攻击的目标
  11. 苹果系统macos腾讯企点无法打开麦克风权限
  12. 马云控股“中国文化”什么暗藏玄机?
  13. 电脑键盘错乱完美解决
  14. 、HTML“计算机输出”标签codekbdsampttvarpre
  15. 第三届世界5G大会召开之前,我们来复习一下这本6G白皮书
  16. java查询neo4j_Java中使用neo4j--创建和查询
  17. 激光雷达和相机联合标定之cam_lidar_calibration
  18. java+决策树结构_机器学习——决策树,DecisionTreeClassifier参数详解,决策树可视化查看树结构...
  19. 《移动App测试实战》读书笔记
  20. 服务器连接mysql数据库,报错message from server: “Host xxx is not allowed to connect to this MySQL server“

热门文章

  1. 1461 Beads
  2. PDF文件不能编辑的原因
  3. 【三维目标检测】SSN(二)
  4. 阿里云网盘公测_阿里云网盘公测预约开启,领2T永久免费空间
  5. 【第二弹】社区跑腿 校园跑腿升级版 毕设 创业 微信小程序+java后台
  6. maven项目子模块相互引用无效
  7. 博客园登录太麻烦,于是来了。
  8. 【颜色代码】代码中16进制表示颜色
  9. Redis数据类型之stream类型
  10. ps --sort排序功能