首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Threejs 着色器GLSL材质常用定义

最近继续学习了大量的着色器语言,整理如下:

#define PHYSICAL

uniform vec3 diffuse; // 漫反射颜色

uniform vec3 emissive; // 自发光颜色

uniform float roughness; // 粗糙度

uniform float metalness; // 金属性

uniform float opacity;  // 透明度

#ifndef STANDARD

uniform float clearCoat;  //

uniform float clearCoatRoughness;

#endif

varying vec3 vViewPosition; // 摄像机空间的坐标

#ifndef FLAT_SHADED

varying vec3 vNormal; // 摄像机空间的法线

#endif

#include            //  包含着色器公共模块(包含常用的数学工具函数以及一些常量定义什么的)

#include           // 数据编码解码功能函数

#include   // 抖动处理的定义

#include       // 颜色处理的定义

#include          // uv相关处理的定义

#include         // uv2相关处理的定义

#include         // map贴图相关处理的定义

#include    // alphamap贴图的处理定义

#include       // aomap贴图的处理定义

#include    // lighmap贴图处理定义

#include     // emissivemap贴图处理的定义

#include  // envmap贴图处理的定义

#include     // 雾化需要的定义

#include                     // brdf相关的功能函数

#include   // cubemap反射相关

#include         // 灯光相关定义

#include          // 灯光贴图相关

#include // 灯光相关物理运算

#include   // shadowmap影子相关运算定义

#include         // bumpmap相关运算的定义

#include       // normalmap相关运算的定义

#include        // roughnessmap相关运算的定义

#include        // metalnessmap相关运算的定义

#include         // logdepth相关运算的定义

#include         // clipplane裁剪平面相关的定义

void main() {

#include // 裁剪平面裁剪

vec4 diffuseColor = vec4( diffuse, opacity );// 合成rgba四通道漫反射颜色

ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );

vec3 totalEmissiveRadiance = emissive;

#include // logdepth运算

#include          // map通道颜色采样

#include        // color参与计算

#include     // alphamap通道颜色采样

#include    // alpha测试

#include     // 粗糙贴图采样

#include     // 金属性贴图采样

#include     // 法线贴图基本运算

#include      // 法线通过法线贴图运算

#include      // 自发光贴图采样

// accumulation

#include  // 物理光照基础运算

#include // 计算各种灯光入射光和反射光信息

#include  // 从环境光和光照贴图获取辐射

#include   // 根据辐射光取得反射信息

// modulation

#include    // 根据AO贴图调整反射光照强度

// 反射光直接漫反射+间接漫反射+直接高光+间接高光+自发光 = 输出光照颜色

vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;

gl_FragColor = vec4( outgoingLight, diffuseColor.a );

#include // tonemap进行曝光

#include // 颜色编码

#include              // 雾化颜色运算

#include // 颜色预乘alpha

#include   // 颜色随机抖动

}

修改之后的代码:

// 由vertexshader传递过来的法线,位置,uv

varying vec3 vNormal;

varying vec3 vPosition;

varying vec2 vUv;

// 材质参数

uniform vec3 diffuse; // 漫反射

uniform float metallic; // 金属性

uniform float roughness; // 粗糙度

#if NUM_POINT_LIGHTS > 0

// 点光源信息

struct PointLight {

vec3 position;

vec3 color;

float distance;

float decay;

};

uniform PointLight pointLights[ NUM_POINT_LIGHTS ];

#endif

#if NUM_DIR_LIGHTS > 0

struct DirectionalLight {

vec3 direction;

vec3 color;

};

uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];

#endif

float pow2( const in float x ) { return x*x; }

const float PI = 3.14159265359;

#define EPSILON 1e-6

#define MAXIMUM_SPECULAR_COEFFICIENT 0.16

#define DEFAULT_SPECULAR_COEFFICIENT 0.04

#define RECIPROCAL_PI 0.31830988618

// 光照反射信息(直接光的漫反射和高光色)

struct ReflectedLight {

vec3 directDiffuse;

vec3 directSpecular;

vec3 indirectDiffuse;

};

// 入射光照信息(颜色和方向)

struct IncidentLight {

vec3 color;

vec3 direction;

};

// 几何信息(位置,法线,视角方向)

struct GeometricContext {

vec3 position;

vec3 normal;

vec3 viewDir;

};

// 物理材质信息

struct PhysicalMaterial {

vec3 diffuseColor;

float specularRoughness;

vec3 specularColor;

};

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_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {

float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );

const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );

const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );

vec4 r = roughness * c0 + c1;

float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;

vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;

return specularColor * AB.x + AB.y;

}

vec3 BRDF_Specular_GGX( in GeometricContext geometry, in IncidentLight directLight,const in vec3 specularColor, const in float roughness) {

float alpha = pow2( roughness );

vec3 halfDir = normalize( directLight.direction + geometry.viewDir );

float dotNL = saturate( dot( geometry.normal, directLight.direction ) );

float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );

float dotNH = saturate( dot( geometry.normal, halfDir ) );

float dotLH = saturate( dot( directLight.direction, halfDir ) );

vec3 F = F_Schlick( specularColor, dotLH );

float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );

float D = D_GGX( alpha, dotNH );

return F * ( G * D );

}

vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {

return RECIPROCAL_PI * diffuseColor;

}

float clearCoatDHRApprox( const in float roughness, const in float dotNL ) {

return DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );

}

void RE_Direct_Physical(in GeometricContext geometry,in PhysicalMaterial material, in IncidentLight directLight,inout ReflectedLight reflectedLight ) {

float dotNL = saturate( dot( geometry.normal,directLight.direction ) );// lambert漫反射因子

vec3 irradiance = dotNL * directLight.color; // 辐射

irradiance *= PI; // * PI

reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );

// 重点就是这里了,高光算法和blinn-phong差距巨大

reflectedLight.directSpecular += irradiance * BRDF_Specular_GGX( geometry,directLight,material.specularColor,material.specularRoughness);

}

void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {

reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );

}

vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {

vec3 irradiance = ambientLightColor;

irradiance *= PI;

return irradiance;

}

#define RE_IndirectDiffuse RE_IndirectDiffuse_Physical

void main() {

// 存放几何数据

GeometricContext geometry;

geometry.position = vPosition;

geometry.normal = normalize(vNormal);

geometry.viewDir = normalize(-vPosition); // 因为是相机空间只需要对位置坐标取反0-vPosition

// 存放物理材质信息

PhysicalMaterial material;

material.diffuseColor = diffuse * ( 1.0 - metallic ); // 金属性越强漫反射颜色越小

material.specularRoughness = clamp( roughness, 0.04, 1.0 ); // 粗燥度

material.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuse.rgb, metallic ); // 这里做了个mix 金属性为0高光颜色也不至于是黑色

// 初始化光照反射

ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ),vec3(0.0) );

IncidentLight directLight;// 直接入射光照

#if NUM_POINT_LIGHTS > 0

for(int i = 0; i < NUM_POINT_LIGHTS; ++i)

{

directLight.color = pointLights[i].color; // 入射光颜色

directLight.direction = normalize(pointLights[i].position - vPosition); // 入射光的方向

RE_Direct_Physical(geometry,material,directLight,reflectedLight); // 计算直接光产生的反射光信息

}

#endif

#if NUM_DIR_LIGHTS > 0

for(int i = 0; i < NUM_DIR_LIGHTS; ++i)

{

directLight.color = directionalLights[i].color; // 入射光颜色

directLight.direction = directionalLights[i].direction;

RE_Direct_Physical(geometry,material,directLight,reflectedLight); // 计算直接光产生的反射光信息

}

#endif

vec3 irradiance = getAmbientLightIrradiance( vec3(0.13) );

RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );

// 反射光信息加合为最后颜色

vec3 color = reflectedLight.directDiffuse + reflectedLight.directSpecular+reflectedLight.indirectDiffuse;

// HDR tonemapping

color = saturate(color/(color+vec3(1.0)));

// gamma correct

color = pow(color, vec3(1.0/2.0));

gl_FragColor = vec4(color, 1.0);

}

做一只爬的最久的乌龟,保持学习保持好奇,即使慢一点,遇到一点困难,只要最后能到达终点,又有什么关系呢。

毕竟人生没有白走的路,每一步都算数。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230209A06L8E00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券