1. three.js 中 meshbasic.glsl 文件中的片源着色器的主函数解析
他的具体代码如下
void main() {
#include <uv_vertex>
#include <color_vertex>
#include <morphcolor_vertex>
#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )
#include <beginnormal_vertex>
#include <morphnormal_vertex>
#include <skinbase_vertex>
#include <skinnormal_vertex>
#include <defaultnormal_vertex>
#endif
#include <begin_vertex> // 对顶点数据进行处理,将 position 值,赋值给 vPosition 这个变量
#include <morphtarget_vertex> // 对顶点数据进行变形的处理
#include <skinning_vertex> // 对骨骼数据进行处理。
#include <project_vertex> // 顶点数据进行,投影转换,在这里,物体的位置就已经定下来了,下面的都是,对顶点数据处理,给片源着色器来使用
#include <logdepthbuf_vertex> // 对数深度缓冲区,来解决两个面,很近的时候,分不清那个是前面,那个是后面
#include <clipping_planes_vertex> // 裁剪平面
#include <worldpos_vertex>
#include <envmap_vertex> // 环境纹理,顶点
#include <fog_vertex>
}
`;
export const fragment = /* glsl */`
void main() {
#include <clipping_planes_fragment> // 裁剪空间
vec4 diffuseColor = vec4( diffuse, opacity ); // 漫反射
#include <logdepthbuf_fragment> // 对数缓冲区的计算,片源着色器的
#include <map_fragment>
#include <color_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>
#include <specularmap_fragment>
ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
// accumulation (baked indirect lighting only)
#ifdef USE_LIGHTMAP
vec4 lightMapTexel = texture2D( lightMap, vLightMapUv );
reflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;
#else
reflectedLight.indirectDiffuse += vec3( 1.0 );
#endif
// modulation
#include <aomap_fragment>
reflectedLight.indirectDiffuse *= diffuseColor.rgb;
vec3 outgoingLight = reflectedLight.indirectDiffuse;
#include <envmap_fragment>
#include <opaque_fragment>
#include <tonemapping_fragment>
#include <colorspace_fragment>
#include <fog_fragment>
#include <premultiplied_alpha_fragment>
#include <dithering_fragment>
}
`;
裁剪空间, 就是将不要的空间外的片源删除掉
#include <clipping_planes_fragment> // 裁剪空间
漫反射颜色
vec4 diffuseColor = vec4( diffuse, opacity ); // 漫反射
对片源进行对数缓冲区计算
#include <logdepthbuf_fragment> // 对数缓冲区的计算,片源着色器的
#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )
gl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;
// vIsPerspective 表示当前相机是不是透视投影相机
// 如果是就返回 log2( vFragDepth ) * logDepthBufFC * 0.5
// 如果不是 gl_FragCoord.z
#endif
纹理采样
#include <map_fragment>
#ifdef USE_MAP
vec4 sampledDiffuseColor = texture2D( map, vMapUv );
// 进行纹理采样, sampledDiffuseColor就是等到的结果
#ifdef DECODE_VIDEO_TEXTURE
// 如果使用的是视频纹理就,进行这样的操作
// use inline sRGB decode until browsers properly support SRGB8_APLHA8 with video textures
sampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w );
#endif
// 将得到的纹理颜色,跟漫反射的颜色,进行混合。
diffuseColor *= sampledDiffuseColor;
#endif
`;
片源顶点颜色处理
#include <color_fragment>
export default /* glsl */`
#if defined( USE_COLOR_ALPHA )
// 如果使用是顶点颜色,有透明度的
diffuseColor *= vColor;
#elif defined( USE_COLOR )
// 如果使用是顶点颜色,没有透明度的
diffuseColor.rgb *= vColor;
#endif
`;
透明纹理贴图
#include <alphamap_fragment>
export default /* glsl */`
#ifdef USE_ALPHAMAP
diffuseColor.a *= texture2D( alphaMap, vAlphaMapUv ).g;
#endif
`;
他会对alphaMap 纹理进行,采样然后获取他的一个 g 值,来表示一个 强度;
在 alphatest 纹理进行处理
export default /* glsl */`
#ifdef USE_ALPHATEST
if ( diffuseColor.a < alphaTest ) discard;
#endif
`;
如果这个强度值,小于 alphaTest,那么这个就会把删除掉
高光纹理贴图
export default /* glsl */`
float specularStrength;
#ifdef USE_SPECULARMAP
vec4 texelSpecular = texture2D( specularMap, vSpecularMapUv );
specularStrength = texelSpecular.r;
#else
specularStrength = 1.0;
#endif
`;
也是对高光纹理贴图进行采样,然后再获取一个值,作为高光的强度,没有使用的话,默认就是 1的强度