添加关照、全局等高线、修改图层问题

This commit is contained in:
2025-07-17 18:54:05 +08:00
parent c781d38c0c
commit b274b62671
4594 changed files with 791769 additions and 4921 deletions

View File

@ -0,0 +1,59 @@
import F_Schlick from './F_Schlick.js';
import V_GGX_SmithCorrelated from './V_GGX_SmithCorrelated.js';
import V_GGX_SmithCorrelated_Anisotropic from './V_GGX_SmithCorrelated_Anisotropic.js';
import D_GGX from './D_GGX.js';
import D_GGX_Anisotropic from './D_GGX_Anisotropic.js';
import { transformedNormalView } from '../../accessors/NormalNode.js';
import { positionViewDirection } from '../../accessors/PositionNode.js';
import { iridescence, alphaT, anisotropyT, anisotropyB } from '../../core/PropertyNode.js';
import { tslFn, defined } from '../../shadernode/ShaderNode.js';
// GGX Distribution, Schlick Fresnel, GGX_SmithCorrelated Visibility
const BRDF_GGX = tslFn( ( inputs ) => {
const { lightDirection, f0, f90, roughness, f, USE_IRIDESCENCE, USE_ANISOTROPY } = inputs;
const normalView = inputs.normalView || transformedNormalView;
const alpha = roughness.pow2(); // UE4's roughness
const halfDir = lightDirection.add( positionViewDirection ).normalize();
const dotNL = normalView.dot( lightDirection ).clamp();
const dotNV = normalView.dot( positionViewDirection ).clamp(); // @ TODO: Move to core dotNV
const dotNH = normalView.dot( halfDir ).clamp();
const dotVH = positionViewDirection.dot( halfDir ).clamp();
let F = F_Schlick( { f0, f90, dotVH } );
let V, D;
if ( defined( USE_IRIDESCENCE ) ) {
F = iridescence.mix( F, f );
}
if ( defined( USE_ANISOTROPY ) ) {
const dotTL = anisotropyT.dot( lightDirection );
const dotTV = anisotropyT.dot( positionViewDirection );
const dotTH = anisotropyT.dot( halfDir );
const dotBL = anisotropyB.dot( lightDirection );
const dotBV = anisotropyB.dot( positionViewDirection );
const dotBH = anisotropyB.dot( halfDir );
V = V_GGX_SmithCorrelated_Anisotropic( { alphaT, alphaB: alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL } );
D = D_GGX_Anisotropic( { alphaT, alphaB: alpha, dotNH, dotTH, dotBH } );
} else {
V = V_GGX_SmithCorrelated( { alpha, dotNL, dotNV } );
D = D_GGX( { alpha, dotNH } );
}
return F.mul( V ).mul( D );
} ); // validated
export default BRDF_GGX;

View File

@ -0,0 +1,9 @@
import { tslFn } from '../../shadernode/ShaderNode.js';
const BRDF_Lambert = tslFn( ( inputs ) => {
return inputs.diffuseColor.mul( 1 / Math.PI ); // punctual light
} ); // validated
export default BRDF_Lambert;

View File

@ -0,0 +1,57 @@
import { transformedNormalView } from '../../accessors/NormalNode.js';
import { positionViewDirection } from '../../accessors/PositionNode.js';
import { sheen, sheenRoughness } from '../../core/PropertyNode.js';
import { tslFn, float } from '../../shadernode/ShaderNode.js';
// https://github.com/google/filament/blob/master/shaders/src/brdf.fs
const D_Charlie = tslFn( ( { roughness, dotNH } ) => {
const alpha = roughness.pow2();
// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
const invAlpha = float( 1.0 ).div( alpha );
const cos2h = dotNH.pow2();
const sin2h = cos2h.oneMinus().max( 0.0078125 ); // 2^(-14/2), so sin2h^2 > 0 in fp16
return float( 2.0 ).add( invAlpha ).mul( sin2h.pow( invAlpha.mul( 0.5 ) ) ).div( 2.0 * Math.PI );
} ).setLayout( {
name: 'D_Charlie',
type: 'float',
inputs: [
{ name: 'roughness', type: 'float' },
{ name: 'dotNH', type: 'float' }
]
} );
// https://github.com/google/filament/blob/master/shaders/src/brdf.fs
const V_Neubelt = tslFn( ( { dotNV, dotNL } ) => {
// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
return float( 1.0 ).div( float( 4.0 ).mul( dotNL.add( dotNV ).sub( dotNL.mul( dotNV ) ) ) );
} ).setLayout( {
name: 'V_Neubelt',
type: 'float',
inputs: [
{ name: 'dotNV', type: 'float' },
{ name: 'dotNL', type: 'float' }
]
} );
const BRDF_Sheen = tslFn( ( { lightDirection } ) => {
const halfDir = lightDirection.add( positionViewDirection ).normalize();
const dotNL = transformedNormalView.dot( lightDirection ).clamp();
const dotNV = transformedNormalView.dot( positionViewDirection ).clamp();
const dotNH = transformedNormalView.dot( halfDir ).clamp();
const D = D_Charlie( { roughness: sheenRoughness, dotNH } );
const V = V_Neubelt( { dotNV, dotNL } );
return sheen.mul( D ).mul( V );
} );
export default BRDF_Sheen;

View File

@ -0,0 +1,30 @@
import { tslFn, vec2, vec4 } from '../../shadernode/ShaderNode.js';
// Analytical approximation of the DFG LUT, one half of the
// split-sum approximation used in indirect specular lighting.
// via 'environmentBRDF' from "Physically Based Shading on Mobile"
// https://www.unrealengine.com/blog/physically-based-shading-on-mobile
const DFGApprox = tslFn( ( { roughness, dotNV } ) => {
const c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );
const c1 = vec4( 1, 0.0425, 1.04, - 0.04 );
const r = roughness.mul( c0 ).add( c1 );
const a004 = r.x.mul( r.x ).min( dotNV.mul( - 9.28 ).exp2() ).mul( r.x ).add( r.y );
const fab = vec2( - 1.04, 1.04 ).mul( a004 ).add( r.zw );
return fab;
} ).setLayout( {
name: 'DFGApprox',
type: 'vec2',
inputs: [
{ name: 'roughness', type: 'float' },
{ name: 'dotNV', type: 'vec3' }
]
} );
export default DFGApprox;

View File

@ -0,0 +1,23 @@
import { tslFn } from '../../shadernode/ShaderNode.js';
// Microfacet Models for Refraction through Rough Surfaces - equation (33)
// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
// alpha is "roughness squared" in Disneys reparameterization
const D_GGX = tslFn( ( { alpha, dotNH } ) => {
const a2 = alpha.pow2();
const denom = dotNH.pow2().mul( a2.oneMinus() ).oneMinus(); // avoid alpha = 0 with dotNH = 1
return a2.div( denom.pow2() ).mul( 1 / Math.PI );
} ).setLayout( {
name: 'D_GGX',
type: 'float',
inputs: [
{ name: 'alpha', type: 'float' },
{ name: 'dotNH', type: 'float' }
]
} ); // validated
export default D_GGX;

View File

@ -0,0 +1,28 @@
import { tslFn, float, vec3 } from '../../shadernode/ShaderNode.js';
const RECIPROCAL_PI = float( 1 / Math.PI );
// https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel/anisotropicspecularbrdf
const D_GGX_Anisotropic = tslFn( ( { alphaT, alphaB, dotNH, dotTH, dotBH } ) => {
const a2 = alphaT.mul( alphaB );
const v = vec3( alphaB.mul( dotTH ), alphaT.mul( dotBH ), a2.mul( dotNH ) );
const v2 = v.dot( v );
const w2 = a2.div( v2 );
return RECIPROCAL_PI.mul( a2.mul( w2.pow2() ) );
} ).setLayout( {
name: 'D_GGX_Anisotropic',
type: 'float',
inputs: [
{ name: 'alphaT', type: 'float', qualifier: 'in' },
{ name: 'alphaB', type: 'float', qualifier: 'in' },
{ name: 'dotNH', type: 'float', qualifier: 'in' },
{ name: 'dotTH', type: 'float', qualifier: 'in' },
{ name: 'dotBH', type: 'float', qualifier: 'in' }
]
} );
export default D_GGX_Anisotropic;

View File

@ -0,0 +1,13 @@
import DFGApprox from './DFGApprox.js';
import { tslFn } from '../../shadernode/ShaderNode.js';
const EnvironmentBRDF = tslFn( ( inputs ) => {
const { dotNV, specularColor, specularF90, roughness } = inputs;
const fab = DFGApprox( { dotNV, roughness } );
return specularColor.mul( fab.x ).add( specularF90.mul( fab.y ) );
} );
export default EnvironmentBRDF;

View File

@ -0,0 +1,16 @@
import { tslFn } from '../../shadernode/ShaderNode.js';
const F_Schlick = tslFn( ( { f0, f90, 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.pdf
const fresnel = dotVH.mul( - 5.55473 ).sub( 6.98316 ).mul( dotVH ).exp2();
return f0.mul( fresnel.oneMinus() ).add( f90.mul( fresnel ) );
} ); // validated
export default F_Schlick;

View File

@ -0,0 +1,21 @@
import { tslFn, vec3 } from '../../shadernode/ShaderNode.js';
const Schlick_to_F0 = tslFn( ( { f, f90, dotVH } ) => {
const x = dotVH.oneMinus().saturate();
const x2 = x.mul( x );
const x5 = x.mul( x2, x2 ).clamp( 0, .9999 );
return f.sub( vec3( f90 ).mul( x5 ) ).div( x5.oneMinus() );
} ).setLayout( {
name: 'Schlick_to_F0',
type: 'vec3',
inputs: [
{ name: 'f', type: 'vec3' },
{ name: 'f90', type: 'float' },
{ name: 'dotVH', type: 'float' }
]
} );
export default Schlick_to_F0;

View File

@ -0,0 +1,26 @@
import { div } from '../../math/OperatorNode.js';
import { EPSILON } from '../../math/MathNode.js';
import { tslFn } from '../../shadernode/ShaderNode.js';
// Moving Frostbite to Physically Based Rendering 3.0 - page 12, listing 2
// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
const V_GGX_SmithCorrelated = tslFn( ( { alpha, dotNL, dotNV } ) => {
const a2 = alpha.pow2();
const gv = dotNL.mul( a2.add( a2.oneMinus().mul( dotNV.pow2() ) ).sqrt() );
const gl = dotNV.mul( a2.add( a2.oneMinus().mul( dotNL.pow2() ) ).sqrt() );
return div( 0.5, gv.add( gl ).max( EPSILON ) );
} ).setLayout( {
name: 'V_GGX_SmithCorrelated',
type: 'float',
inputs: [
{ name: 'alpha', type: 'float' },
{ name: 'dotNL', type: 'float' },
{ name: 'dotNV', type: 'float' }
]
} ); // validated
export default V_GGX_SmithCorrelated;

View File

@ -0,0 +1,29 @@
import { div } from '../../math/OperatorNode.js';
import { tslFn, vec3 } from '../../shadernode/ShaderNode.js';
// https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel/anisotropicspecularbrdf
const V_GGX_SmithCorrelated_Anisotropic = tslFn( ( { alphaT, alphaB, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL } ) => {
const gv = dotNL.mul( vec3( alphaT.mul( dotTV ), alphaB.mul( dotBV ), dotNV ).length() );
const gl = dotNV.mul( vec3( alphaT.mul( dotTL ), alphaB.mul( dotBL ), dotNL ).length() );
const v = div( 0.5, gv.add( gl ) );
return v.saturate();
} ).setLayout( {
name: 'V_GGX_SmithCorrelated_Anisotropic',
type: 'float',
inputs: [
{ name: 'alphaT', type: 'float', qualifier: 'in' },
{ name: 'alphaB', type: 'float', qualifier: 'in' },
{ name: 'dotTV', type: 'float', qualifier: 'in' },
{ name: 'dotBV', type: 'float', qualifier: 'in' },
{ name: 'dotTL', type: 'float', qualifier: 'in' },
{ name: 'dotBL', type: 'float', qualifier: 'in' },
{ name: 'dotNV', type: 'float', qualifier: 'in' },
{ name: 'dotNL', type: 'float', qualifier: 'in' }
]
} );
export default V_GGX_SmithCorrelated_Anisotropic;