着色器语言GLSL学习

这篇具有很好参考价值的文章主要介绍了着色器语言GLSL学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 初步尝试

import { Scene, WebGLRenderer, OrthographicCamera, PlaneGeometry, ShaderMateria } from 'three.js'

const scene = new Scene()
const camera = new OrthographicCamera(-1,1,1,-1,0.1, 10)

const renderer = new WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

// 创建一个大小为2 的平面几何容器
const geometry = new PlaneGeometry(2,2)

// 设置着色器材质
const material = new ShaderMaterial()

// 创建网格对象 绘制平面
const plane = new mesh(geometry, material)
scene.add(plane)

//设置相机z轴以便能看到平面,注意范围为0.1 - 10,即远近裁截面
camera.position.z = 1 
renderer.render(scene, camera)

2 颜色随时间改变

const fragmentShader = {
	uniform float u_time;
	void main() {
		vec3 color = vec3((sin(u_time) + 1.0) /2.0, 0.0, (cos(u_time) + 1.0) /2.0);
		gl_FragColor = vec4(color, 1.0);
	}
}

const uniforms = {
	u_time: { value: 0.0 }
}

const clock =  new THREE.Clock()

function animate(){
	requestAnimation(animate)
	uniforms.u_time.value += clock.getDelta()
	renderer.render(scene, camera)
}

3 混合

用法:mix(a,b,c)
公式:a*(1-c)+b*c, 0<=c<=1

4 颜色随位置改变

注意:位置坐标大小可能大于1,小于0,因此要将其转化为0-1之间

clamp(num, min, max):将num值约束在(min, max)之间,小于min,值为min,大于max,值为max,在min-max之间,值为num

//注意带分号
//顶点
const vshader = `
	varying vec3 v_position;
	void main() {
		v_position = position;
		// 左乘modelMatrix 将坐标转换到世界坐标系下 左乘viewMatrix 将坐标转换到相机坐标系下 左乘projectMatrix 将三维坐标映射到二维屏幕上
		gl_Position = projectMatrix * modelViewMatrix * vec4(position, 1.0);	
	}
`

const fshader = `
	varying vec3 v_position;
	void main(){
		vec3 color = vec3(0.0);
		color.r = clamp(position.x, 0.0, 1.0);	
		color.g = clamp(position.y, 0.0, 1.0);	
		gl_FragColor = vec4(color, 1.0);
	}
`

5 位置颜色分块

step(n, x):当x<n, 返回0;否则返回1

const fshader = `
	varying vec3 v_position;
	void main(){
		vec3 color = vec3(0.0);
		color.r = step(0.0, position.x);	
		color.g = step(0.0, position.y);	
		gl_FragColor = vec4(color, 1.0);
	}
`

6 画一个圆

const fshader = `
	varying vec3 v_position;
	void main(){
		// 半径为0.5范围内的显示颜色
		float inCircle = 1.0 - step(0.5, length(v_position.xy))
		vec3 color = vec3(1.0, 1.0, 0.0) * inCircle;
		gl_FlagColor = veec4(color, 1.0);
	}
`

7 画一个矩形

const fshader = `
	varying vec3 v_position;
	//位置是否处于矩形边界内,三个参数分别为检测点坐标,矩形宽高和矩形中心的坐标
	flat rect(vec2 pt, vec2 size, vec2 center) {
		vec2 p = pt - center;
		vec2 halfSize = size * 0.5;
		//float horz = (v_position.x>-halfSize.x && v_position.x<halfSize.x) ? 1.0 : 0.0;
		// 大于左边界返回1 小于右边界返回0
		float horz = step(-halfSize.x, p.x) - step(halfSize.x, p.x);
		float vert = step(-halfSize.y, p.y) - step(halfSize.y, p.y);
		return horz * vert;	
	}
	void main(){
		float inRect = rect(v_position.xy, vec2(1.0), vec2(0.0));
		vec3 color = vec3(1.0, 1.0, 0.0) * inRect;
		gl_FlagColor = veec4(color, 1.0);
	}
`

8 绕中心旋转

着色器语言GLSL学习,着色器,学习
设长度为r,则可列出如下公式
着色器语言GLSL学习,着色器,学习

const uniforms = {
	u_time: { value: 0.0 }
}

const fshader = `
	uniform float u_time;
	flat rect(vec2 pt, vec2 size, vec2 center) {
		vec2 p = pt - center;
		vec2 halfSize = size * 0.5;
		//float horz = (v_position.x>-halfSize.x && v_position.x<halfSize.x) ? 1.0 : 0.0;
		// 大于左边界返回1 小于右边界返回0
		float horz = step(-halfSize.x, p.x) - step(halfSize.x, p.x);
		float vert = step(-halfSize.y, p.y) - step(halfSize.y, p.y);
		return horz * vert;	
	}
	mat getRotationMatrix(float theta) {
		float s = sin(theta);
		float c = cos(theta);
		return mat2(c, -s, s, c)	
	}
	void main() {
		vec2 center = vec2(0.0);
		mat2 mat = getRotationMatrix(u_time);
		vac2 pt = mat * position.xy;
		float inRect = rect(pt, vec2(0.5),vec2(0.0))
		fl_FragColor = vec4(color, 1.0)
	}
`

const clock =  new THREE.Clock()

function animate(){
	requestAnimation(animate);
	uniforms.u_time.value += clock.getDelta();
	renderer.render(scene, camera);
}

animate();

9 实战——辉光效果

由于光照的运算需要放在视图空间下,所以需要将法线向量变换到视图矩阵中

//法线和法线矩阵相乘将会被变换到视图空间,归一化向量可以保证使用点乘得到余弦值
vec3 viewNormal = normalize(normalMatrix * normal);

首先画出最外层的辉光
着色器语言GLSL学习,着色器,学习

着色器语言GLSL学习,着色器,学习
这里是将intensity大于0.55的全部改成0
着色器语言GLSL学习,着色器,学习

// 顶点着色器
// 计算顶点法向量 顶点的世界坐标
const vertexShader = `
	varying vec3 vVertexWorldPosition;
	varying vec3 vVertexNormal;
	varying vec4 FragColor;
	void main(){
		vVertexNormal = normalize(normalMatrix * normal);	
		vVertexWorldPosition = (modelMMatrix * vec4(position, 1.0)).xyz;
		gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
	}
`

//计算世界坐标下 顶点位置到相机位置的距离 计算距离向量在视图坐标系下的坐标
//计算不透明度 从中心向外角度越来越大,点乘得到的cos值越来越小,因此intensity不断减小
//所以可以得到一个从中心向两边透明度逐渐减小的圆
const fragmentShader = `
	uniform vec3 glowColor;
	uniform float coeficient;
	
	varying vec3 vVertexWorldPosition;
	varying vec3 vVertexNormal;
	varying vec4 FragColor;
	
	void main() {
		vec3 worldCameraToVertex = 	cameraPosition - vVertexWorldPosition;
		vec3 viewCameraToVertex = (viewMatrix * vec4(worldCameraToVertex, 0.0)).xyz;
		viewCameraToVertex = normalize(viewCameraToVertex);
		float intensity = coeficient+ dot(vVertexNormal, viewCameraToVertex);
		if(intensity > 0.55){ intensity = 0.0;}
		gl_FragColor = vec4(FragColor, intensity)
	}
`

之后在画大气层
着色器语言GLSL学习,着色器,学习
从中心向外面角度越来越小(从钝角到锐角)从cos函数也可以知道这个值由负变正
图和文字完全不能理解,这里放弃了

着色器语言GLSL学习,着色器,学习文章来源地址https://www.toymoban.com/news/detail-810254.html


//计算世界坐标下 相机位置到顶点位置的距离 计算距离向量在视图坐标系下的坐标
//计算不透明度
const fragmentShader = `
	uniform vec3 glowColor;
	uniform float coeficient;
	uniform float power;
	
	varying vec3 vVertexWorldPosition;
	varying vec3 vVertexNormal;
	varying vec4 FragColor;
	
	void main() {
		vec3 worldCameraToVertex = 	vVertexWorldPosition- cameraPosition;
		vec3 viewCameraToVertex = (viewMatrix * vec4(worldCameraToVertex, 0.0)).xyz;
		viewCameraToVertex = normalize(viewCameraToVertex);
		float intensity = pow(coeficient+ dot(vVertexNormal, viewCameraToVertex), power);
		gl_FragColor = vec4(FragColor, intensity)
	}
`
const container = document.createElement( 'div' );

const camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 1, 1000 );

const scene = new THREE.Scene()
const render = new THREE.webGLRenderer()
render.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement);


const sphere = new THREE.SphereBufferGeometry(6. 32, 32)
const material = new THREE.ShaderMaterial({
	uniforms: {
	coeficient	: {
       type: "f",
           value	: 1.0
       },
       power: {
           type	: "f",
           value	: 2
       },
       glowColor: {
           type	: "c",
           value	: new THREE.Color('blue')
       }
	},
	vertexShader: vertexShader,
	fragmentShader,
	blending: THREE.NormalBlending,
	transparent: true,
})

const mesh = new THREE.Mesh(sphere, material)


scene.add(mesh)

10 实战-小球上的粒子

const r = 60

// r小球半径 num 生成粒子数量
// 在球面上生成随机均匀分布的粒子
// 随机产生随机数u,v∈[-1,1]
// 满足 u^2+v^2 <=1
// radiu = u^2+v^2
// x = 2*u*sqrt(1-r^2)
// y = 2*v*sqrt(1-r^2)
// z = 1-2*r^2
const getPointsxyz = (r, num) => {
	const position = []
	for (let i = 0;i<num;i++) {
		const u = Math.random() * 2 - 1
		const v = Math.random() * 2 - 1
		const radius = u **2 + v ** 2
		if (radius <= 1) {
			const x = 2 * u * Math.sqrt(1- radius**2)
			const x = 2 * v * Math.sqrt(1- radius**2)
			const z = 1 - 2*radius**2
			position.push({x, y, z})
		}
	}
	return position
}

const pointUniforms = {
	pointSize: {value: 1.0},
	color: { value: new Color('#ffffff') },
	center: { value: new Vector2(width / 2, height / 2) },
}

// 随机生成粒子坐标
const posxyz = getPointsxyz(r, 10000)

const geometry = new THREE.Geometry()

//将点放入几何体中
for (let i = 0;i<posxyz.length;i++) {
	const {x,y,z} = posxyz[i]
	const vertex  = new Vector3(x,y,z)
	geometry.vertices.push(vertex)
}
//顶点着色器
const vertexShader = `
	uniform float pointSize;
	void main() {
		gl_PointSize = pointSize;
		gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);	
	}
`

const fragmentShader =  `
	uniform vec3 color;
	uniform vec2 center;
	float random2(float x, float x1) {
		return smoothstep(-40.0, x, x1)	
	}
	void main (){
		gl_FragColor = vec4(color, random2(center.x, length(gl_FragCoord.xy - center)))	;
	}
`

const pointMaterial = new ShaderMaterial({
	uniforms: pointUniforms,
	vertexShader,
	fragmentShader,
	transparent: true,	//启用透明效果
	blending: THREE.AdditiveBlending,	//颜色直接相加, 不受透明度影响
	depthWrite: false	//禁用depthWrite可防止渲染材质影响深度缓冲区
})

const spherePoint = new Points(geometry, pointMaterial)
group.add(spherePoint)

到了这里,关于着色器语言GLSL学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 跟随chatgpt学习如何使用GLSL进行简单的图形渲染

    运行成功页面 一个简单的glsl小实验成功了,不过我想要这个三角形动起来。 修改后的script代码如下 运行成功截图 他现在就是一个游来游去的红色三角形了。太神奇了!~

    2024年01月18日
    浏览(48)
  • opengl 学习着色器

            着色器是使用一种叫GLSL的类C语言写成的。GLSL着色器编码顺序:声明版本==》定义输入输出==》uniform==》main函数。每个着色器的入口点是main函数,在main函数中我们处理所有的输入变量,并将结果输出到输出变量中。如下图:         顶点着色器的每个输入变量

    2024年02月22日
    浏览(35)
  • shader学习(二)顶点着色器

    1、C#脚本设置shader参数 2、在shader里做变换和颜色显示 3、改变顶点的位置信息 4.顶点扭曲(做周期旋转) 5、实现波浪效果 6、实现漫反射和点光源照射 效果图: 7、实现镜面反射

    2024年02月13日
    浏览(44)
  • Shader学习(三)(片元着色器)

    1、在片元着色器处理漫反射 在片元处理的漫反射相较于顶点中处理的漫反射在明暗交接处更加清晰

    2024年02月11日
    浏览(47)
  • UE4 顶点着色 学习笔记

    首先区别一下StaticMesh和StaticMeshComponent StaticMesh是模型本身 而StaticMeshComponent是模型出来的实例 直接修改StaticMesh的内容,所有StaticMeshComponent实例都会产生变化 而修改StaticMeshComponent直会对实例产生影响不会对StaticMesh有任何修改 函数参数 1、要修改顶点着色的StaticMeshCommponent

    2024年02月04日
    浏览(53)
  • 使用 OpenCV 和深度学习对黑白图像进行着色

    在本文中,我们将创建一个程序将黑白图像(即灰度图像)转换为彩色图像。我们将为此程序使用 Caffe 着色模型。您应该熟悉基本的 OpenCV 功能和用法,例如读取图像或如何使用 dnn 模块加载预训练模型等。现在让我们讨论实现该程序所遵循的过程。 给定一张灰度照片作为输

    2024年02月14日
    浏览(45)
  • Unity | HDRP高清渲染管线学习笔记:材质系统Lit着色器

    目录 一、Lit着色器 1. Surface Options 2. Surface Inputs(表面输入) 3. Transparency Inputs 二、HDRP渲染优先级 目录 一、Lit着色器 1. Surface Options 2. Surface Inputs(表面输入) 3. Transparency Inputs 4. Emission Inputs(自发光输入) 二、HDRP渲染优先级        我们可以把现实世界中的物体分成不

    2024年02月12日
    浏览(51)
  • 利用深度学习进行黑白照片着色:使用 Keras 构建 GAN 进行照片自动上色的详细实践指南

    在这篇博客文章中,我们将探讨一个具有挑战性的问题,即如何利用深度学习自动为黑白照片上色。传统的图片上色过程是一个艰苦且劳动密集型的过程,必须由熟练的平面设计师在 Photoshop 中手动完成,整个过程可能需要很长时间,因为它依赖于设计师的想象力和效率来产

    2024年02月16日
    浏览(45)
  • GLSL ES 1.0

    程序是大小写敏感的 每一个语句都应该以英文分号结束 一个shader必须包含一个main函数,该函数不接受任何参数,并且返回void GLSL支持三种数据类型: 整型 浮点型 :必须包含小数点,不然会被认为是浮点型,比如1表示整形,1.0才表示浮点型 布尔类型 GLSL是强类型语言,这意

    2024年02月22日
    浏览(40)
  • OpenGLES(四)glsl语法

    GLSL是OpenGL着色器语言(OpenGL Shading Language) 版本说明 OpenGLES版本 GLSL版本 2.0 100 3.0 300 3.1 310 3.2 320 GLSL3.0与2.0差异 用 in 和 out 取代 attribute 和 varying 头文件多了个 #version 300 es 纹理 texture2D 和 texture3D 统统改为 texture 内置函数 gl_FragColor 和 gl_FragData 删除,如果片段着色器要输出用

    2024年02月06日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包