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中匿名函数、函数直接量和闭包的完整攻略 1. 匿名函数 匿名函数是指没有名字的函数。在JavaScript中,可以通过以下两种方式来定义匿名函数: 1.1 函数表达式 函数表达式是指将一个匿名函数赋值给一个变量,变量名就成了这个匿名函数的名字。示例代码如下: var add = function(x, y) { return x +…

    JavaScript 2023年5月27日
    00
  • javascript正则表达式和字符串RegExp and String(二)

    JavaScript正则表达式和字符串RegExp and String(二) 1. RegExp 对象 RegExp 对象是 JavaScript 的内置对象,用于支持正则表达式。 1.1 RegExp 对象的创建 字面量方式: var patt = /pattern/flags; 构造函数方式: var patt = new RegExp(pattern…

    JavaScript 2023年5月28日
    00
  • JS倒计时代码汇总

    以下是详细的“JS倒计时代码汇总”的攻略。 概述 倒计时在Web开发中非常有用,比如用于处理限时优惠促销,或者用于展示一些即将到来的重要事件。本文将介绍JS倒计时的一些常用代码,帮助开发者轻松地实现倒计时功能。 普通倒计时 普通倒计时的代码非常简单,在代码中设定截止时间,然后不断更新展示倒计时的信息即可。 const deadline = new Date(…

    JavaScript 2023年5月27日
    00
  • ASP.NET中使用GridView实现分级显示的代码

    ASP.NET中使用GridView实现分级显示可以通过绑定多个GridView控件来实现。以下是实现此功能的完整攻略: 步骤一:创建GridView控件 首先,在HTML中,创建一个表格并添加GridView控件。GridView控件将显示第一级数据。例如: <table> <tr><td> <asp:GridVi…

    JavaScript 2023年6月10日
    00
  • 基于jQuery的ajax方法封装

    下面是基于jQuery的ajax方法封装的完整攻略,包含了示例说明。 什么是ajax? Ajax(Asynchronous JavaScript and XML)指一种创建交互式网页应用的网页开发技术,可以在不重新加载整个网页的情况下更新部分网页内容。通过ajax请求,可以获取服务器上的数据,也可以向服务器发送数据。 为何要封装ajax方法? 基于jQuer…

    JavaScript 2023年6月11日
    00
  • JavaScript的document对象和window对象详解

    来详细讲解一下“JavaScript的document对象和window对象详解”。 1. 什么是document对象和window对象 在JavaScript中,document对象和window对象都是很重要的全局对象,它们都是DOM( Document Object Model,文档对象模型)的一部分,具有非常强的实用性。 1.1 document对象…

    JavaScript 2023年5月27日
    00
  • JavaScript学习小结(7)之JS RegExp

    JavaScript学习小结(7)之JS RegExp 简介 RegExp是JavaScript中的一个正则表达式对象,用于匹配字符串中的对应字符序列。使用正则表达式可以轻松地检索符合特定模式的字符串,同时也可以将文本内容替换为不同的字符。 创建RegExp对象 有两种创建RegExp对象的方法:字面量和构造函数。 字面量创建RegExp对象 使用字面量创建…

    JavaScript 2023年6月10日
    00
  • Javascript中的数据类型之旅

    好的。首先,“JavaScript中的数据类型之旅”是一篇介绍JavaScript数据类型的文章,可以帮助初学者更好地了解JavaScript数据类型。下面是我为你准备的完整攻略: JavaScript中的数据类型之旅 1. 基本数据类型 JavaScript中有6种基本数据类型:String(字符串)、Number(数字)、Boolean(布尔)、Null…

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