我第一次尝试在 WebGL 场景中实现阴影,据我所知,最直接的方法是使用阴影贴图,但我找不到解释这个概念的教程,那是既不是关于 OpenGL,也不是包含一些像 Three.js 这样的库。
但是,我读过,我必须编写两对着色器。第一对着色器用于构建阴影贴图,它必须以某种方式存储在帧缓冲区对象中。然后我必须从帧缓冲区中获取存储的阴影贴图并将其传递给第二对着色器,用于绘制我的场景对象。
阴影贴图必须包含信息,光线在撞击对象之前可以从其源头传播的距离,并将此信息传递给用于绘制对象的着色器,可以指定哪些部分是由光源发出的光和哪些部分仅由环境光照亮。
理论就这么多,但我不知道如何让这个工作......
为了进行实验,我设置了一个非常简单的场景,渲染由单个点光源照亮的两个球体,如下所示:
两个球体都是以它们的中心[0.0, 0.0, 0.0]和半径创建的1.0。
较大球体的矩阵由 平移[-2.0, 0.0, -2.0]和缩放[2.0, 2.0, 2.0]。
较小球体的矩阵由 平移[2.0, 0.0, 2.0]和缩放[0.5, 0.5, 0.5]。
点光源的位置是[4.0, 0.0, 4.0]。
因此,较小的球体现在正好位于较大的球体和光源之间,因此在较大的球体的表面上应该有一个不被直接照亮的区域。
我用于此场景的两个着色器如下所示:
顶点着色器
attribute vec4 aPosition;
attribute vec3 aNormal;
uniform mat4 uProjectionMatrix;
uniform mat4 uModelViewMatrix;
uniform mat3 uNormalMatrix;
varying vec4 vPosition;
varying vec3 vTransformedNormal;
void main ( ) {
vTransformedNormal = uNormalMatrix * aNormal;
vPosition = uModelViewMatrix * …Run Code Online (Sandbox Code Playgroud) 现在,这似乎是一个愚蠢的问题,但我如何计算曲线的法线?
为了计算表面的法线,我前段时间写了下面的函数,而不是在此期间考虑这个问题......
function calcNormals (source, destination) {
var subtract = function (a, b) {
var vec3 = new Array(3);
vec3[0] = a[0] - b[0],
vec3[1] = a[1] - b[1],
vec3[2] = a[2] - b[2];
return vec3;
}
var crossProduct = function (a, b) {
var vec3 = new Array(3);
vec3[0] = a[1] * b[2] - a[2] * b[1];
vec3[1] = a[2] * b[0] - a[0] * b[2];
vec3[2] = a[0] * b[1] - a[1] …Run Code Online (Sandbox Code Playgroud)