three.js各种材质的实现源码

更新时间:2023-07-28 05:27:18 阅读: 评论:0

three.js各种材质的实现源码three.js常⽤材质:基本材质、兰伯特材质、冯⽒材质、标准材质。
我们可以⾃⼰使⽤着⾊器实现这些材质,⽤于批量渲染等⽤途。
为了简单,假设物体只有⼀张漫反射贴图,场景中只存在⼀个环境光和⼀个平⾏光。
⼀、基本材质(MeshBasicMaterial)
基本材质不对光源产⽣反应。
顶点着⾊器
varying vec2 vUv;
void main() {
vUv = uv;
vec3 transformed = vec3( position );
vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
⽚源着⾊器
uniform vec3 diffu;
uniform float opacity;
uniform sampler2D map;
varying vec2 vUv;
void main() {
vec4 diffuColor = vec4( diffu, opacity );
vec4 texelColor = texture2D( map, vUv );
diffuColor *= texelColor;
gl_FragColor = diffuColor;
}
⼆、兰伯特材质(MeshLambertMaterial)
兰伯特材质只有漫反射,没有⾼光。
顶点着⾊器
uniform vec3 directColor; // 平⾏光颜⾊
uniform vec3 directDirection; // 平⾏光⽅向
#define PI 3.14159265359
varying vec2 vUv;
varying vec3 vLightFront;
void main() {
vUv = uv;
vec3 transformedNormal = normalMatrix * vec3( normal );
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
float dotNL = dot( normalize( transformedNormal ), directDirection );
最火男明星vLightFront = clamp( dotNL, 0.0, 1.0 ) * PI * directColor;
}
⽚源着⾊器
uniform vec3 diffu; // 物体颜⾊
uniform float opacity; // 透明度
uniform sampler2D map;
uniform vec3 ambientColor; // 漫反射光颜⾊
varying vec2 vUv;
varying vec3 vLightFront;
// 双向反射PI
#define RECIPROCAL_PI 0.31830988618
void main() {
vec4 diffuColor = vec4( diffu, opacity );
vec4 texelColor = texture2D( map, vUv );
diffuColor *= texelColor;
// 出射光 = 直接漫反射 + 间接漫反射
vec3 outgoingLight = vLightFront + ambientColor * RECIPROCAL_PI * b;
gl_FragColor = vec4( outgoingLight, diffuColor.a );
}
三、冯⽒材质(MeshPhongMaterial)
冯⽒材质很重要的两个属性是⾼光颜⾊(specular)和光亮度(shininess)。
顶点着⾊器
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vViewPosition;
void main() {
vUv = uv;
vNormal = normalize( normalMatrix * normal );
vec3 transformed = vec3( position );
vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );
vViewPosition = - ;
gl_Position = projectionMatrix * mvPosition;
}
⽚源着⾊器
// 参考资料:
// BRDF-双向反射分布函数:/item/双向反射分布函数/22311036
// 常见的三个光照模型:Lambert,Phong,BlinnPhong:blog.csdn/taoqilin/article/details/52800702 // 菲涅尔公式:/item/菲涅⽿公式/9103788
// 菲涅尔折射率:/item/菲涅尔折射率/2712906
uniform vec3 diffu; // 物体颜⾊
uniform float opacity; // 透明度
uniform vec3 specular; // ⾼光颜⾊
uniform float shininess; // 光亮度
uniform sampler2D map;
uniform vec3 ambientColor; // 漫反射光颜⾊
uniform vec3 directColor; // 平⾏光颜⾊
uniform vec3 directDirection; // 平⾏光⽅向
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vViewPosition;
/
/ 双向反射PI
#define RECIPROCAL_PI 0.31830988618
// 菲涅尔反射
vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {
float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );
return ( 1.0 - specularColor ) * fresnel + specularColor;
}
// Blinn-Phong光照模型
float D_BlinnPhong( const in float shininess, const in float dotNH ) {
return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );
}
void main() {
// 物体颜⾊
vec4 diffuColor = vec4( diffu, opacity );
vec4 texelColor = texture2D( map, vUv );
diffuColor *= texelColor;
// 环境光漫反射(BRDF兰伯特漫反射)
vec3 indirectDiffu = ambientColor * RECIPROCAL_PI * b;
// 法线
vec3 normal = normalize( vNormal );
// 平⾏光漫反射(BRDF兰伯特漫反射)
float dotNL = clamp( dot( normal, directDirection ), 0.0, 1.0 );
vec3 irradiance = dotNL * directColor;
vec3 directDiffu = irradiance * RECIPROCAL_PI * b;
// 平⾏光镜⾯反射
vec3 halfDir = normalize( directDirection + normalize( vViewPosition ) ); // 半⾓向量
float dotNH = clamp( dot( normal, halfDir ), 0.0, 1.0 );
float dotLH = clamp( dot( directDirection, halfDir ), 0.0, 1.0 );
vec3 F = F_Schlick( specular, dotLH ); // 菲涅尔反射
float D = D_BlinnPhong( shininess, dotNH ); // Blinn-Phong光照模型
vec3 directSpecular = F * ( 0.25 * D );
// 出射光 = 环境光漫反射 + 平⾏光漫反射 + 平⾏光镜⾯反射
vec3 outgoingLight = indirectDiffu + directDiffu + directSpecular;
gl_FragColor = vec4( outgoingLight, diffuColor.a );
}
四、标准材质(MeshStandardMaterial)
标准材质也叫物理材质或pbr材质,很重要的两个属性是⾦属度(metalness)和粗糙度(roughness)。
顶点着⾊器
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vViewPosition;
void main() {
vUv = uv;
vNormal = normalize( normalMatrix * vec3( normal ) );
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vViewPosition = - ;
gl_Position = projectionMatrix * mvPosition;
}
⽚源着⾊器
// 参考资料:
// BRDF-双向反射分布函数:/item/双向反射分布函数/22311036
放风筝的// 基于物理的渲染—更精确的微表⾯分布函数GGX: /p/be4f025aeb3c
// 菲涅尔公式:/item/菲涅⽿公式/9103788
// 菲涅尔折射率:/item/菲涅尔折射率/2712906
叫她欺负连// Moving Frostbite to Physically Bad Rendering 3.0: blog.csdn/wodownload2/article/details/103126247 uniform vec3 diffu; // 物体颜⾊
uniform float opacity; // 透明度
uniform float metalness; // ⾦属度
uniform float roughness; // 粗糙度
uniform sampler2D map;
uniform vec3 ambientColor; // 漫反射光颜⾊
uniform vec3 directColor; // 平⾏光颜⾊
uniform vec3 directDirection; // 平⾏光⽅向
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vViewPosition;
// 双向反射PI
#define RECIPROCAL_PI 0.31830988618
中华大蟾蜍
// 菲涅尔反射
vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {
float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );
return ( 1.0 - specularColor ) * fresnel + specularColor;
}
季冠霖配音float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {
float a2 = pow2( alpha );
float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );
float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );
return 0.5 / max( gv + gl, EPSILON );
}
策士统领
// 微表⾯分布函数
float D_GGX( const in float alpha, const in float dotNH ) {
float a2 = pow2( alpha );
float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;
return RECIPROCAL_PI * a2 / pow2( denom );
}
vec3 BRDF_Specular_GGX( const in vec3 directDirection, const in vec3 normal, const in viewDir, const in vec3 specularColor, const in float roughness ) {
float alpha = pow2( roughness );
vec3 halfDir = normalize( directDirection + viewDir );
float dotNL = clamp( dot( normal, directDirection ), 0.0, 1.0 );
float dotNV = clamp( dot( normal, viewDir ), 0.0, 1.0 );
float dotNH = clamp( dot( normal, halfDir ), 0.0, 1.0 );
float dotLH = clamp( dot( directDirection, halfDir ), 0.0, 1.0 );
vec3 F = F_Schlick( specularColor, dotLH );
float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );
float D = D_GGX( alpha, dotNH );
return F * ( G * D );
}
void main() {追逐时间
vec4 diffuColor = vec4( diffu, opacity );
vec4 texelColor = texture2D( map, vUv );
diffuColor *= texelColor;
// 法线
vec3 normal = normalize( vNormal );
// 环境光
vec3 indirectDiffu = ambientColor * RECIPROCAL_PI * b * ( 1.0 - metalness ); // 间接漫反射
// 平⾏光
float dotNL = clamp( dot( normal, directDirection ), 0.0, 1.0 );
vec3 irradiance = dotNL * directColor;
vec3 specularColor = mix( vec3( 0.04 ), b, metalness );
vec3 directDiffu = irradiance * RECIPROCAL_PI * b * ( 1.0 - metalness ); // 直接漫反射
vec3 directSpecular = irradiance * BRDF_Specular_GGX( directDirection, normal, normalize( vViewPosition ), specularColor, clamp( roughness, 0.04, 1.0 ) ); // 直接镜⾯反射// 出射光 = 间接漫反射光 + 直接漫反射 + 直接镜⾯反射光
vec3 outgoingLight = indirectDiffu + directDiffu + directSpecular;
gl_FragColor = vec4( outgoingLight, diffuColor.a );
}
四种材质完整实现源码:
参考资料
1. 基于three.js的开源三维场景编辑器:
谷文昌精神2. BRDF-双向反射分布函数:
3. 常见的三个光照模型:
4. 菲涅尔公式:
5. 菲涅尔折射率:
6. 基于物理的渲染—更精确的微表⾯分布函数GGX:
7. Moving Frostbite to Physically Bad Rendering 3.0:

本文发布于:2023-07-28 05:27:18,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1099554.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:材质   场景   反射   分布   函数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图