欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > THREE.JS Blinn–Phong反射模型 高光shader

THREE.JS Blinn–Phong反射模型 高光shader

2024/10/25 10:29:40 来源:https://blog.csdn.net/printf_hello/article/details/142681800  浏览:    关键词:THREE.JS Blinn–Phong反射模型 高光shader

Blinn–Phong reflection model

平滑着色平直着色
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
顶点
// 法线
vNormal = normalMatrix * normal;
vNormal = normalize( vNormal );
// 点光位置
vPointLightPosition = (viewMatrix * vec4( pointLightPosition, 1.0 )).xyz;
//顶点位置
vec3 transformed = vec3( position );
vec4 mvPosition = vec4( transformed, 1.0 );
mvPosition = modelViewMatrix * mvPosition;
vViewPosition = - mvPosition.xyz;

片元
不同着色方式法线设置

#ifdef FLAT_SHADEDvec3 fdx = dFdx( vViewPosition );vec3 fdy = dFdy( vViewPosition );vec3 normal = normalize( cross( fdx, fdy ) );#elsevec3 normal =  vNormal ;normal = normalize( vNormal );#endifvec3 geometryPosition = - vViewPosition;
vec3 geometryNormal = normal;
vec3 geometryViewDir = normalize( vViewPosition );//光线方向
vec3 lVector = vPointLightPosition - geometryPosition;
vec3 lightDirection = normalize( lVector );	
//直接反射高光颜色
vec3 phongColor = BRDF_BlinnPhong( lightDirection, geometryViewDir, geometryNormal, vec3(1), 30.);

全部代码

import * as THREE from "three";const bsdfs_glsl = /* glsl */ `float pow2( const in float x ) { return x*x; }vec3 pow2( const in vec3 x ) { return x*x; }float pow4( const in float x ) { float x2 = x*x; return x2*x2; }// 距离衰减float getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );if ( cutoffDistance > 0.0 ) {distanceFalloff *= pow2( clamp( 1.0 - pow4( lightDistance / cutoffDistance ) ,0. ,1.) );}return distanceFalloff;}// common.glsl.jsvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {// Original approximation by Christophe Schlick '94// float fresnel = pow( 1.0 - dotVH, 5.0 );// Optimized variant (presented by Epic at SIGGRAPH '13)// https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdffloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );}float F_Schlick( const in float f0, const in float f90, const in float dotVH ) {// Original approximation by Christophe Schlick '94// float fresnel = pow( 1.0 - dotVH, 5.0 );// Optimized variant (presented by Epic at SIGGRAPH '13)// https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdffloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );}// bsdfs.glsl.jsfloat G_BlinnPhong_Implicit( /* const in float dotNL, const in float dotNV */ ) {// geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v)return 0.25;}float D_BlinnPhong( const in float shininess, const in float dotNH ) {return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );}vec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {vec3 halfDir = normalize( lightDir + viewDir );float dotNH = clamp( dot( normal, halfDir ) ,0.,1.);float dotVH = clamp( dot( viewDir, halfDir ) ,0.,1.);vec3 F = F_Schlick( specularColor, 1.0, dotVH );float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ );float D = D_BlinnPhong( shininess, dotNH );return F * ( G * D );}
`;export class SpecularShaderMaterial extends THREE.ShaderMaterial {constructor(params?: ConstructorParameters<typeof THREE.ShaderMaterial>[0] & {pointLightPosition: THREE.Vector3;pointLightDistance: number;pointLightDecay: number;}) {super({uniforms: {pointLightPosition: {value: params!.pointLightPosition,},pointLightDistance: {value: params?.pointLightDistance ?? 100,},pointLightDecay: {value: params?.pointLightDecay ?? 2,},},defines: {RECIPROCAL_PI: 1 / Math.PI,// 平直着色 关闭则 平滑着色FLAT_SHADED: false,},vertexShader: /* glsl */ `varying vec3 vNormal;varying vec3 vertexPosition;uniform vec3 pointLightPosition;varying vec3 vPointLightPosition;varying vec3 vViewPosition;void main() {vNormal = normalMatrix * normal;vNormal = normalize( vNormal );vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);gl_Position = projectionMatrix * modelViewPosition;vertexPosition = modelViewPosition.xyz;vPointLightPosition = (viewMatrix * vec4( pointLightPosition, 1.0 )).xyz;vec3 transformed = vec3( position );vec4 mvPosition = vec4( transformed, 1.0 );mvPosition = modelViewMatrix * mvPosition;vViewPosition = - mvPosition.xyz;}`,fragmentShader: /* glsl */ `varying vec3 vNormal;               varying vec3 vertexPosition;varying vec3 vPointLightPosition;uniform vec3 pointLightPosition;uniform float pointLightDistance;uniform float pointLightDecay;varying vec3 vViewPosition;${bsdfs_glsl}void main() {#ifdef FLAT_SHADEDvec3 fdx = dFdx( vViewPosition );vec3 fdy = dFdy( vViewPosition );vec3 normal = normalize( cross( fdx, fdy ) );#elsevec3 normal =  vNormal ;normal = normalize( vNormal );#endifvec3 geometryPosition = - vViewPosition;vec3 geometryNormal = normal;vec3 geometryViewDir = normalize( vViewPosition );// 取自 getPointLightInfo// vec3 lVector = pointLightPosition - geometryPosition;vec3 lVector = vPointLightPosition - geometryPosition;vec3 lightDirection = normalize( lVector );float lightDistance = length( lVector );vec3 lightColor = vec3( 1. );lightColor *= getDistanceAttenuation( lightDistance, pointLightDistance, pointLightDecay );// 取自 RE_Direct_BlinnPhongfloat dotNL = clamp( dot( geometryNormal, lightDirection ) ,0. ,1. );vec3 irradiance = dotNL * lightColor;// vec3 reflectedLightDirectSpecular = irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;vec3 phongColor = BRDF_BlinnPhong( lightDirection, geometryViewDir, geometryNormal, vec3(1), 30.);// gl_FragColor = vec4(vec3( irradiance ) , 1. );gl_FragColor = vec4(vec3( phongColor ) , 1. );// gl_FragColor = vec4(vec3( lightDirection ) , 1. );// gl_FragColor = vec4(vec3( pointLightPosition ) , 1. );// gl_FragColor = vec4(vec3( vPointLightPosition ) , 1. );// gl_FragColor = vec4(vec3( normal ) , 1. );// gl_FragColor = vec4(vec3( lightColor ) , 1. );// gl_FragColor = vec4(vec3( irradiance ) , 1. );}`,});}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com