CesiumJS源码杂谈之从光到 Uniform

下面是关于“CesiumJS源码杂谈之从光到Uniform”的完整攻略的详细讲解。

前置知识

在讲解这个话题之前,需要对一些基本的知识有一定的了解。包括:WebGL的基础知识、Shader的基础知识、CesiumJS的基础知识等。

从光开始

在WebGL的渲染过程中,光是非常重要的一个环节。CesiumJS中的光源主要有以下几种:

  • sun:太阳光。
  • moon:月球光。
  • pointLight:点光源光。
  • spotLight:聚光灯光。

在CesiumJS中,光源的渲染是通过Shader来实现的。常见的光照Shader有PBRBlinnPhong两种。

其中,BlinnPhong是比较常用的光照模型。它可以通过Shader中的Uniform等变量来获取光源信息,并进行计算,最终得出物体在光照下的表现。

Uniform

在Shader中,Uniform是一类可以被纹理以外的外部数据修改的变量。

在CesiumJS源码中,Uniform主要是通过ShaderProgram来实现的。其中,ShaderProgram是一个Shader程序的封装,用于管理Shader中的变量。

ShaderProgram中,Uniform主要包括两种类型的变量:

  • 向量类型:包括vec2、vec3、vec4等等。
  • 矩阵类型:包括mat2、mat3、mat4等等。

在使用Uniform之前,首先需要在Shader中使用uniform关键字来声明和定义这些变量。然后,在JavaScript代码中获取这些Uniform变量的位置,并通过gl.uniformXXX系列函数来设置Uniform变量的值。

下面是一个使用Uniform的示例:

uniform mat4 u_ModelViewProjectionMatrix;

void main()
{
    gl_Position = u_ModelViewProjectionMatrix * vec4(a_Position, 1.0);
}

在JavaScript代码中,获取Uniform变量的位置,并设置其值:

var modelViewProjectionMatrixLoc = gl.getUniformLocation(shaderProgram, "u_ModelViewProjectionMatrix");
gl.uniformMatrix4fv(modelViewProjectionMatrixLoc, false, modelViewProjectionMatrix);

示例说明

下面,通过两条示例来具体说明“从光到Uniform”的攻略。

示例1:添加太阳光源

在CesiumJS中,要添加太阳光源,需要在对应的UIView中创建Sun对象,并设置其属性。

在Shader中,需要通过Uniform来获取太阳光源的信息。

具体步骤如下:

  1. 在UIView中创建Sun对象,并设置其颜色、方向等属性。
var sun = new Cesium.Sun();
sun.color = new Cesium.Color(1.0, 1.0, 1.0);
sun.direction = Cesium.Cartesian3.normalize(new Cesium.Cartesian3(1.0, 1.0, 1.0));
  1. 在Shader中声明和定义uniform变量,用于接收太阳光的方向和颜色信息。
uniform vec3 u_SunDirection;
uniform vec3 u_SunColor;
  1. 在Shader中计算太阳光的光照强度,并将其作为输出。
vec3 sunLightColor = u_SunColor * max(dot(-v_Normal, u_SunDirection), 0.0);
  1. 在JavaScript代码中获取uniform变量的位置,并设置其值。
var sunDirectionLoc = gl.getUniformLocation(shaderProgram, "u_SunDirection");
var sunColorLoc = gl.getUniformLocation(shaderProgram, "u_SunColor");

gl.uniform3fv(sunDirectionLoc, sun.direction);
gl.uniform3fv(sunColorLoc, sun.color.toRgb());

示例2:实现法线贴图

在3D场景中,法线贴图(Normal Map)可以用来增强物体表面的细节感。

在CesiumJS中,要实现法线贴图,需要在ShaderProgram中添加Texture类型的Uniform,并且在Shader中计算出法向量和切向量,最终计算出使用法线贴图之后的颜色信息。

具体步骤如下:

  1. 在ShaderProgram中添加Texture类型的Uniform。
var program = new Cesium.ShaderProgram({
    vertexShaderSource : vertexShaderSource,
    fragmentShaderSource : fragmentShaderSource,
    uniformMap : {
        u_ColorMap: colorMap,
        u_NormalMap: normalMap,
        u_WorldMatrix: function() {
            return Cesium.Matrix4.IDENTITY;
        }
    }
});
  1. 在Shader中声明和定义uniform变量,用于接收ColorMap和NormalMap的信息。
uniform sampler2D u_ColorMap;
uniform sampler2D u_NormalMap;
  1. 在Shader中计算出使用法线贴图之后的法向量和切向量,并计算出最终的颜色信息。
// 计算使用法线贴图之后的法向量和切向量
vec3 normal = texture2D(u_NormalMap, v_TexCoord).rgb * 2.0 - 1.0;
mat3 TBN = mat3(v_Tangent, v_Bitangent, v_Normal);
vec3 normalTangent = normalize(TBN * normal);

// 计算光源对物体的影响
vec3 ambient = u_AmbientColor.rgb * u_AmbientIntensity;
vec3 diffuse = texture2D(u_ColorMap, v_TexCoord).rgb * max(dot(normalTangent, u_LightDirection), 0.0);

// 计算最终的颜色信息
gl_FragColor = vec4(ambient + diffuse, 1.0);
  1. 在JavaScript代码中加载ColorMap和NormalMap,并设置其值。
var colorMap = new Cesium.Texture({
    context: gl,
    source: "/textures/colorMap.png",
    flipY: false
});

var normalMap = new Cesium.Texture({
    context: gl,
    source: "/textures/normalMap.png",
    flipY: false
});

program.uniforms.u_ColorMap = colorMap;
program.uniforms.u_NormalMap = normalMap;

以上就是从光到Uniform的攻略及两个示例的具体实现。希望可以帮助你更好地了解CesiumJS中的Shader和Uniform的使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:CesiumJS源码杂谈之从光到 Uniform - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • 关于javascript模块加载技术的一些思考

    关于 JavaScript 模块加载技术的一些思考 什么是模块加载技术? JavaScript 作为一门基于对象的语言,可以使用函数和对象等抽象概念来组织代码。在应用程序越来越庞大的情况下,我们需要将代码分割成多个模块,这样既方便代码管理,也有利于代码的可重用性。模块加载技术就是将模块引入到应用程序中,以便让应用程序能够使用模块提供的功能。 JavaScri…

    JavaScript 2023年6月11日
    00
  • Javascript入门学习第五篇 js函数第1/2页

    下面是“Javascript入门学习第五篇 js函数第1/2页”的完整攻略: 什么是函数 函数是对一段可复用代码的封装。函数接收输入(称为参数),并在结构化的语句块内执行特定操作。函数可以返回值(也可以不返回)作为输出。 在JavaScript中,我们可以使用function关键字来定义一个函数。一个函数定义通常由以下部分组成: 关键字function 函数…

    JavaScript 2023年5月18日
    00
  • JavaScript 中有关数组对象的方法(详解)

    JavaScript 中有关数组对象的方法(详解) 数组是 JavaScript 中非常常用的数据结构。在 JavaScript 中,数组对象有许多方法可以使用,比如添加元素、删除元素、查找元素等等。本文将详细介绍 JavaScript 中有关数组对象的方法。 数组的创建 在 JavaScript 中创建一个数组对象有多种方法: 使用字面量表达式 const…

    JavaScript 2023年5月27日
    00
  • JS正则表达式常见用法实例详解

    当然,下面是关于“JS正则表达式常见用法实例详解”的完整攻略: JS正则表达式常见用法实例详解 什么是正则表达式 正则表达式是一种用于匹配字符串的强大工具,可以应用于许多语言和数据处理工具中,包括JavaScript、Python、Perl、sed等。 正则表达式由一些字符和操作符构成,用于定义搜索模式。你可以使用正则表达式来搜索文本中的模式、替换文本中的模…

    JavaScript 2023年5月28日
    00
  • JS定时器如何实现提交成功提示功能

    JS定时器可以通过setInterval()函数来实现提交成功提示功能。函数setInterval()可用于定时重复执行指定的代码段,其语法如下: setInterval(function, interval); 其中,function参数指定需要重复执行的代码段,interval参数指定执行函数的时间间隔,单位为毫秒。 下面是一个简单的示例代码,点击按钮后…

    JavaScript 2023年6月11日
    00
  • JavaScript中的标签语句用法分析

    接下来我分享一下“JavaScript中的标签语句用法分析”的完整攻略: 什么是标签语句 在JavaScript中,标签语句是一种向代码块添加标记的机制。它使用标签来标识某个特定的代码块,从而使我们能够在代码中方便地跳转和执行特定的代码块。常见的标签语句可以使用break和continue语句来使用。 标签语句的基本语法如下: label : stateme…

    JavaScript 2023年5月18日
    00
  • JS实现unicode和UTF-8之间的互相转换互转

    JS实现unicode和UTF-8之间的互相转换,需要借助一些内置的函数和方法来完成。下面给出一些示例来说明具体的实现方法。 1. Unicode转UTF-8 Unicode是一种宽字符集,而UTF-8是一种字节编码方式,它们之间需要做转换。下面的代码演示了如何将一个Unicode字符串转换成UTF-8格式的字节: function unicodeToUtf…

    JavaScript 2023年5月19日
    00
  • JavaScript你不知道的一些数组方法

    下面是详细讲解“JavaScript你不知道的一些数组方法”的完整攻略。 一、前言 JavaScript 中数组是非常常用的数据结构,JS 对数组的操作也非常丰富。其中一些方法在日常的开发中比较常见,比如push、pop、shift和unshift等等,但是还有一些方法很少被知道或使用,这些方法不仅可以提高效率,还可以让代码更加优美。 本篇攻略主要介绍 Ja…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部