添加关照、全局等高线、修改图层问题
This commit is contained in:
201
dist/electron/static/sdk/three/jsm/nodes/Nodes.js
vendored
Normal file
201
dist/electron/static/sdk/three/jsm/nodes/Nodes.js
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
// @TODO: We can simplify "export { default as SomeNode, other, exports } from '...'" to just "export * from '...'" if we will use only named exports
|
||||
// this will also solve issues like "import TempNode from '../core/Node.js'"
|
||||
|
||||
// constants
|
||||
export * from './core/constants.js';
|
||||
|
||||
// core
|
||||
export { default as AssignNode, assign } from './core/AssignNode.js';
|
||||
export { default as AttributeNode, attribute } from './core/AttributeNode.js';
|
||||
export { default as BypassNode, bypass } from './core/BypassNode.js';
|
||||
export { default as CacheNode, cache } from './core/CacheNode.js';
|
||||
export { default as ConstNode } from './core/ConstNode.js';
|
||||
export { default as ContextNode, context, label } from './core/ContextNode.js';
|
||||
export { default as IndexNode, vertexIndex, instanceIndex } from './core/IndexNode.js';
|
||||
export { default as LightingModel } from './core/LightingModel.js';
|
||||
export { default as Node, addNodeClass, createNodeFromType } from './core/Node.js';
|
||||
export { default as VarNode, temp } from './core/VarNode.js';
|
||||
export { default as NodeAttribute } from './core/NodeAttribute.js';
|
||||
export { default as NodeBuilder } from './core/NodeBuilder.js';
|
||||
export { default as NodeCache } from './core/NodeCache.js';
|
||||
export { default as NodeCode } from './core/NodeCode.js';
|
||||
export { default as NodeFrame } from './core/NodeFrame.js';
|
||||
export { default as NodeFunctionInput } from './core/NodeFunctionInput.js';
|
||||
export { default as NodeKeywords } from './core/NodeKeywords.js';
|
||||
export { default as NodeUniform } from './core/NodeUniform.js';
|
||||
export { default as NodeVar } from './core/NodeVar.js';
|
||||
export { default as NodeVarying } from './core/NodeVarying.js';
|
||||
export { default as ParameterNode, parameter } from './core/ParameterNode.js';
|
||||
export { default as PropertyNode, property, varyingProperty, output, diffuseColor, roughness, metalness, clearcoat, clearcoatRoughness, sheen, sheenRoughness, iridescence, iridescenceIOR, iridescenceThickness, specularColor, shininess, dashSize, gapSize, pointWidth, alphaT, anisotropy, anisotropyB, anisotropyT } from './core/PropertyNode.js';
|
||||
export { default as StackNode, stack } from './core/StackNode.js';
|
||||
export { default as TempNode } from './core/TempNode.js';
|
||||
export { default as UniformGroupNode, uniformGroup, objectGroup, renderGroup, frameGroup } from './core/UniformGroupNode.js';
|
||||
export { default as UniformNode, uniform } from './core/UniformNode.js';
|
||||
export { default as VaryingNode, varying } from './core/VaryingNode.js';
|
||||
export { default as OutputStructNode, outputStruct } from './core/OutputStructNode.js';
|
||||
|
||||
import * as NodeUtils from './core/NodeUtils.js';
|
||||
export { NodeUtils };
|
||||
|
||||
// math
|
||||
export { default as MathNode, PI, PI2, EPSILON, INFINITY, radians, degrees, exp, exp2, log, log2, sqrt, inverseSqrt, floor, ceil, normalize, fract, sin, cos, tan, asin, acos, atan, abs, sign, length, lengthSq, negate, oneMinus, dFdx, dFdy, round, reciprocal, trunc, fwidth, bitcast, atan2, min, max, mod, step, reflect, distance, difference, dot, cross, pow, pow2, pow3, pow4, transformDirection, mix, clamp, saturate, refract, smoothstep, faceForward, cbrt, all, any, equals } from './math/MathNode.js';
|
||||
|
||||
export { default as OperatorNode, add, sub, mul, div, remainder, equal, lessThan, greaterThan, lessThanEqual, greaterThanEqual, and, or, not, xor, bitAnd, bitNot, bitOr, bitXor, shiftLeft, shiftRight } from './math/OperatorNode.js';
|
||||
export { default as CondNode, cond } from './math/CondNode.js';
|
||||
export { default as HashNode, hash } from './math/HashNode.js';
|
||||
|
||||
// math utils
|
||||
export { parabola, gain, pcurve, sinc } from './math/MathUtils.js';
|
||||
export { triNoise3D } from './math/TriNoise3D.js';
|
||||
|
||||
// utils
|
||||
export { default as ArrayElementNode } from './utils/ArrayElementNode.js';
|
||||
export { default as ConvertNode } from './utils/ConvertNode.js';
|
||||
export { default as DiscardNode, discard } from './utils/DiscardNode.js';
|
||||
export { default as EquirectUVNode, equirectUV } from './utils/EquirectUVNode.js';
|
||||
export { default as FunctionOverloadingNode, overloadingFn } from './utils/FunctionOverloadingNode.js';
|
||||
export { default as JoinNode } from './utils/JoinNode.js';
|
||||
export { default as LoopNode, loop, Continue, Break } from './utils/LoopNode.js';
|
||||
export { default as MatcapUVNode, matcapUV } from './utils/MatcapUVNode.js';
|
||||
export { default as MaxMipLevelNode, maxMipLevel } from './utils/MaxMipLevelNode.js';
|
||||
export { default as OscNode, oscSine, oscSquare, oscTriangle, oscSawtooth } from './utils/OscNode.js';
|
||||
export { default as PackingNode, directionToColor, colorToDirection } from './utils/PackingNode.js';
|
||||
export { default as RemapNode, remap, remapClamp } from './utils/RemapNode.js';
|
||||
export { default as RotateUVNode, rotateUV } from './utils/RotateUVNode.js';
|
||||
export { default as RotateNode, rotate } from './utils/RotateNode.js';
|
||||
export { default as SetNode } from './utils/SetNode.js';
|
||||
export { default as SplitNode } from './utils/SplitNode.js';
|
||||
export { default as SpriteSheetUVNode, spritesheetUV } from './utils/SpriteSheetUVNode.js';
|
||||
export { default as StorageArrayElementNode } from './utils/StorageArrayElementNode.js';
|
||||
export { default as TimerNode, timerLocal, timerGlobal, timerDelta, frameId } from './utils/TimerNode.js';
|
||||
export { default as TriplanarTexturesNode, triplanarTextures, triplanarTexture } from './utils/TriplanarTexturesNode.js';
|
||||
export { default as ReflectorNode, reflector } from './utils/ReflectorNode.js';
|
||||
|
||||
// shadernode
|
||||
export * from './shadernode/ShaderNode.js';
|
||||
|
||||
// accessors
|
||||
export { TBNViewMatrix, parallaxDirection, parallaxUV, transformedBentNormalView } from './accessors/AccessorsUtils.js';
|
||||
export { default as UniformsNode, uniforms } from './accessors/UniformsNode.js';
|
||||
export { default as BitangentNode, bitangentGeometry, bitangentLocal, bitangentView, bitangentWorld, transformedBitangentView, transformedBitangentWorld } from './accessors/BitangentNode.js';
|
||||
export { default as BufferAttributeNode, bufferAttribute, dynamicBufferAttribute, instancedBufferAttribute, instancedDynamicBufferAttribute } from './accessors/BufferAttributeNode.js';
|
||||
export { default as BufferNode, buffer } from './accessors/BufferNode.js';
|
||||
export { default as CameraNode, cameraProjectionMatrix, cameraProjectionMatrixInverse, cameraViewMatrix, cameraNormalMatrix, cameraWorldMatrix, cameraPosition, cameraNear, cameraFar, cameraLogDepth } from './accessors/CameraNode.js';
|
||||
export { default as VertexColorNode, vertexColor } from './accessors/VertexColorNode.js';
|
||||
export { default as CubeTextureNode, cubeTexture } from './accessors/CubeTextureNode.js';
|
||||
export { default as InstanceNode, instance } from './accessors/InstanceNode.js';
|
||||
export { default as BatchNode, batch } from './accessors/BatchNode.js';
|
||||
export { default as MaterialNode, materialAlphaTest, materialColor, materialShininess, materialEmissive, materialOpacity, materialSpecular, materialSpecularStrength, materialReflectivity, materialRoughness, materialMetalness, materialNormal, materialClearcoat, materialClearcoatRoughness, materialClearcoatNormal, materialRotation, materialSheen, materialSheenRoughness, materialIridescence, materialIridescenceIOR, materialIridescenceThickness, materialLineScale, materialLineDashSize, materialLineGapSize, materialLineWidth, materialLineDashOffset, materialPointWidth, materialAnisotropy, materialAnisotropyVector } from './accessors/MaterialNode.js';
|
||||
export { default as MaterialReferenceNode, materialReference } from './accessors/MaterialReferenceNode.js';
|
||||
export { default as RendererReferenceNode, rendererReference } from './accessors/RendererReferenceNode.js';
|
||||
export { default as MorphNode, morphReference } from './accessors/MorphNode.js';
|
||||
export { default as TextureBicubicNode, textureBicubic } from './accessors/TextureBicubicNode.js';
|
||||
export { default as ModelNode, modelDirection, modelViewMatrix, modelNormalMatrix, modelWorldMatrix, modelPosition, modelViewPosition, modelScale } from './accessors/ModelNode.js';
|
||||
export { default as ModelViewProjectionNode, modelViewProjection } from './accessors/ModelViewProjectionNode.js';
|
||||
export { default as NormalNode, normalGeometry, normalLocal, normalView, normalWorld, transformedNormalView, transformedNormalWorld, transformedClearcoatNormalView } from './accessors/NormalNode.js';
|
||||
export { default as Object3DNode, objectDirection, objectViewMatrix, objectNormalMatrix, objectWorldMatrix, objectPosition, objectScale, objectViewPosition } from './accessors/Object3DNode.js';
|
||||
export { default as PointUVNode, pointUV } from './accessors/PointUVNode.js';
|
||||
export { default as PositionNode, positionGeometry, positionLocal, positionWorld, positionWorldDirection, positionView, positionViewDirection } from './accessors/PositionNode.js';
|
||||
export { default as ReferenceNode, reference, referenceBuffer } from './accessors/ReferenceNode.js';
|
||||
export { default as ReflectVectorNode, reflectVector } from './accessors/ReflectVectorNode.js';
|
||||
export { default as SkinningNode, skinning } from './accessors/SkinningNode.js';
|
||||
export { default as SceneNode, backgroundBlurriness, backgroundIntensity } from './accessors/SceneNode.js';
|
||||
export { default as StorageBufferNode, storage, storageObject } from './accessors/StorageBufferNode.js';
|
||||
export { default as TangentNode, tangentGeometry, tangentLocal, tangentView, tangentWorld, transformedTangentView, transformedTangentWorld } from './accessors/TangentNode.js';
|
||||
export { default as TextureNode, texture, textureLoad, /*textureLevel,*/ sampler } from './accessors/TextureNode.js';
|
||||
export { default as TextureStoreNode, textureStore } from './accessors/TextureStoreNode.js';
|
||||
export { default as UVNode, uv } from './accessors/UVNode.js';
|
||||
export { default as UserDataNode, userData } from './accessors/UserDataNode.js';
|
||||
|
||||
// display
|
||||
export { default as BlendModeNode, burn, dodge, overlay, screen } from './display/BlendModeNode.js';
|
||||
export { default as BumpMapNode, bumpMap } from './display/BumpMapNode.js';
|
||||
export { default as ColorAdjustmentNode, saturation, vibrance, hue, lumaCoeffs, luminance, threshold } from './display/ColorAdjustmentNode.js';
|
||||
export { default as ColorSpaceNode, linearToColorSpace, colorSpaceToLinear, linearTosRGB, sRGBToLinear } from './display/ColorSpaceNode.js';
|
||||
export { default as FrontFacingNode, frontFacing, faceDirection } from './display/FrontFacingNode.js';
|
||||
export { default as NormalMapNode, normalMap } from './display/NormalMapNode.js';
|
||||
export { default as PosterizeNode, posterize } from './display/PosterizeNode.js';
|
||||
export { default as ToneMappingNode, toneMapping } from './display/ToneMappingNode.js';
|
||||
export { default as ViewportNode, viewport, viewportCoordinate, viewportResolution, viewportTopLeft, viewportBottomLeft, viewportTopRight, viewportBottomRight } from './display/ViewportNode.js';
|
||||
export { default as ViewportTextureNode, viewportTexture, viewportMipTexture } from './display/ViewportTextureNode.js';
|
||||
export { default as ViewportSharedTextureNode, viewportSharedTexture } from './display/ViewportSharedTextureNode.js';
|
||||
export { default as ViewportDepthTextureNode, viewportDepthTexture } from './display/ViewportDepthTextureNode.js';
|
||||
export { default as ViewportDepthNode, viewZToOrthographicDepth, orthographicDepthToViewZ, viewZToPerspectiveDepth, perspectiveDepthToViewZ, depth, depthTexture, depthPixel } from './display/ViewportDepthNode.js';
|
||||
export { default as GaussianBlurNode, gaussianBlur } from './display/GaussianBlurNode.js';
|
||||
export { default as AfterImageNode, afterImage } from './display/AfterImageNode.js';
|
||||
export { default as AnamorphicNode, anamorphic } from './display/AnamorphicNode.js';
|
||||
|
||||
export { default as PassNode, pass, depthPass } from './display/PassNode.js';
|
||||
|
||||
// code
|
||||
export { default as ExpressionNode, expression } from './code/ExpressionNode.js';
|
||||
export { default as CodeNode, code, js, wgsl, glsl } from './code/CodeNode.js';
|
||||
export { default as FunctionCallNode, call } from './code/FunctionCallNode.js';
|
||||
export { default as FunctionNode, wgslFn, glslFn } from './code/FunctionNode.js';
|
||||
export { default as ScriptableNode, scriptable, global } from './code/ScriptableNode.js';
|
||||
export { default as ScriptableValueNode, scriptableValue } from './code/ScriptableValueNode.js';
|
||||
|
||||
// fog
|
||||
export { default as FogNode, fog } from './fog/FogNode.js';
|
||||
export { default as FogRangeNode, rangeFog } from './fog/FogRangeNode.js';
|
||||
export { default as FogExp2Node, densityFog } from './fog/FogExp2Node.js';
|
||||
|
||||
// geometry
|
||||
export { default as RangeNode, range } from './geometry/RangeNode.js';
|
||||
|
||||
// gpgpu
|
||||
export { default as ComputeNode, compute } from './gpgpu/ComputeNode.js';
|
||||
|
||||
// lighting
|
||||
export { default as LightNode, lightTargetDirection } from './lighting/LightNode.js';
|
||||
export { default as PointLightNode } from './lighting/PointLightNode.js';
|
||||
export { default as DirectionalLightNode } from './lighting/DirectionalLightNode.js';
|
||||
export { default as SpotLightNode } from './lighting/SpotLightNode.js';
|
||||
export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js';
|
||||
export { default as AmbientLightNode } from './lighting/AmbientLightNode.js';
|
||||
export { default as LightsNode, lights, lightsNode, addLightNode } from './lighting/LightsNode.js';
|
||||
export { default as LightingNode /* @TODO: lighting (abstract), light */ } from './lighting/LightingNode.js';
|
||||
export { default as LightingContextNode, lightingContext } from './lighting/LightingContextNode.js';
|
||||
export { default as HemisphereLightNode } from './lighting/HemisphereLightNode.js';
|
||||
export { default as EnvironmentNode } from './lighting/EnvironmentNode.js';
|
||||
export { default as IrradianceNode } from './lighting/IrradianceNode.js';
|
||||
export { default as AONode } from './lighting/AONode.js';
|
||||
export { default as AnalyticLightNode } from './lighting/AnalyticLightNode.js';
|
||||
|
||||
// pmrem
|
||||
export { default as PMREMNode, pmremTexture } from './pmrem/PMREMNode.js';
|
||||
export * as PMREMUtils from './pmrem/PMREMUtils.js';
|
||||
|
||||
// procedural
|
||||
export { default as CheckerNode, checker } from './procedural/CheckerNode.js';
|
||||
|
||||
// loaders
|
||||
export { default as NodeLoader } from './loaders/NodeLoader.js';
|
||||
export { default as NodeObjectLoader } from './loaders/NodeObjectLoader.js';
|
||||
export { default as NodeMaterialLoader } from './loaders/NodeMaterialLoader.js';
|
||||
|
||||
// parsers
|
||||
export { default as GLSLNodeParser } from './parsers/GLSLNodeParser.js'; // @TODO: Move to jsm/renderers/webgl.
|
||||
|
||||
// materials
|
||||
export * from './materials/Materials.js';
|
||||
|
||||
// materialX
|
||||
export * from './materialx/MaterialXNodes.js';
|
||||
|
||||
// functions
|
||||
export { default as BRDF_GGX } from './functions/BSDF/BRDF_GGX.js';
|
||||
export { default as BRDF_Lambert } from './functions/BSDF/BRDF_Lambert.js';
|
||||
export { default as D_GGX } from './functions/BSDF/D_GGX.js';
|
||||
export { default as DFGApprox } from './functions/BSDF/DFGApprox.js';
|
||||
export { default as F_Schlick } from './functions/BSDF/F_Schlick.js';
|
||||
export { default as Schlick_to_F0 } from './functions/BSDF/Schlick_to_F0.js';
|
||||
export { default as V_GGX_SmithCorrelated } from './functions/BSDF/V_GGX_SmithCorrelated.js';
|
||||
|
||||
export { getDistanceAttenuation } from './lighting/LightUtils.js';
|
||||
|
||||
export { default as getGeometryRoughness } from './functions/material/getGeometryRoughness.js';
|
||||
export { default as getRoughness } from './functions/material/getRoughness.js';
|
||||
|
||||
export { default as PhongLightingModel } from './functions/PhongLightingModel.js';
|
||||
export { default as PhysicalLightingModel } from './functions/PhysicalLightingModel.js';
|
25
dist/electron/static/sdk/three/jsm/nodes/accessors/AccessorsUtils.js
vendored
Normal file
25
dist/electron/static/sdk/three/jsm/nodes/accessors/AccessorsUtils.js
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
import { bitangentView } from './BitangentNode.js';
|
||||
import { normalView, transformedNormalView } from './NormalNode.js';
|
||||
import { tangentView } from './TangentNode.js';
|
||||
import { mat3 } from '../shadernode/ShaderNode.js';
|
||||
import { mix } from '../math/MathNode.js';
|
||||
import { anisotropy, anisotropyB, roughness } from '../core/PropertyNode.js';
|
||||
import { positionViewDirection } from './PositionNode.js';
|
||||
|
||||
export const TBNViewMatrix = mat3( tangentView, bitangentView, normalView );
|
||||
|
||||
export const parallaxDirection = positionViewDirection.mul( TBNViewMatrix )/*.normalize()*/;
|
||||
export const parallaxUV = ( uv, scale ) => uv.sub( parallaxDirection.mul( scale ) );
|
||||
|
||||
export const transformedBentNormalView = ( () => {
|
||||
|
||||
// https://google.github.io/filament/Filament.md.html#lighting/imagebasedlights/anisotropy
|
||||
|
||||
let bentNormal = anisotropyB.cross( positionViewDirection );
|
||||
bentNormal = bentNormal.cross( anisotropyB ).normalize();
|
||||
bentNormal = mix( bentNormal, transformedNormalView, anisotropy.mul( roughness.oneMinus() ).oneMinus().pow2().pow2() ).normalize();
|
||||
|
||||
return bentNormal;
|
||||
|
||||
|
||||
} )();
|
78
dist/electron/static/sdk/three/jsm/nodes/accessors/BatchNode.js
vendored
Normal file
78
dist/electron/static/sdk/three/jsm/nodes/accessors/BatchNode.js
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { normalLocal } from './NormalNode.js';
|
||||
import { positionLocal } from './PositionNode.js';
|
||||
import { nodeProxy, vec3, mat3, mat4, int, ivec2, float } from '../shadernode/ShaderNode.js';
|
||||
import { textureLoad } from './TextureNode.js';
|
||||
import { textureSize } from './TextureSizeNode.js';
|
||||
import { attribute } from '../core/AttributeNode.js';
|
||||
import { tangentLocal } from './TangentNode.js';
|
||||
|
||||
class BatchNode extends Node {
|
||||
|
||||
constructor( batchMesh ) {
|
||||
|
||||
super( 'void' );
|
||||
|
||||
this.batchMesh = batchMesh;
|
||||
|
||||
|
||||
this.instanceColorNode = null;
|
||||
|
||||
this.batchingIdNode = null;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
// POSITION
|
||||
|
||||
if ( this.batchingIdNode === null ) {
|
||||
|
||||
this.batchingIdNode = attribute( 'batchId' );
|
||||
|
||||
}
|
||||
|
||||
const matriceTexture = this.batchMesh._matricesTexture;
|
||||
|
||||
const size = textureSize( textureLoad( matriceTexture ), 0 );
|
||||
const j = float( int( this.batchingIdNode ) ).mul( 4 ).toVar();
|
||||
|
||||
const x = int( j.mod( size ) );
|
||||
const y = int( j ).div( int( size ) );
|
||||
const batchingMatrix = mat4(
|
||||
textureLoad( matriceTexture, ivec2( x, y ) ),
|
||||
textureLoad( matriceTexture, ivec2( x.add( 1 ), y ) ),
|
||||
textureLoad( matriceTexture, ivec2( x.add( 2 ), y ) ),
|
||||
textureLoad( matriceTexture, ivec2( x.add( 3 ), y ) )
|
||||
);
|
||||
|
||||
|
||||
const bm = mat3(
|
||||
batchingMatrix[ 0 ].xyz,
|
||||
batchingMatrix[ 1 ].xyz,
|
||||
batchingMatrix[ 2 ].xyz
|
||||
);
|
||||
|
||||
positionLocal.assign( batchingMatrix.mul( positionLocal ) );
|
||||
|
||||
const transformedNormal = normalLocal.div( vec3( bm[ 0 ].dot( bm[ 0 ] ), bm[ 1 ].dot( bm[ 1 ] ), bm[ 2 ].dot( bm[ 2 ] ) ) );
|
||||
|
||||
const batchingNormal = bm.mul( transformedNormal ).xyz;
|
||||
|
||||
normalLocal.assign( batchingNormal );
|
||||
|
||||
if ( builder.hasGeometryAttribute( 'tangent' ) ) {
|
||||
|
||||
tangentLocal.mulAssign( bm );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BatchNode;
|
||||
|
||||
export const batch = nodeProxy( BatchNode );
|
||||
|
||||
addNodeClass( 'batch', BatchNode );
|
89
dist/electron/static/sdk/three/jsm/nodes/accessors/BitangentNode.js
vendored
Normal file
89
dist/electron/static/sdk/three/jsm/nodes/accessors/BitangentNode.js
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { varying } from '../core/VaryingNode.js';
|
||||
import { normalize } from '../math/MathNode.js';
|
||||
import { cameraViewMatrix } from './CameraNode.js';
|
||||
import { normalGeometry, normalLocal, normalView, normalWorld, transformedNormalView } from './NormalNode.js';
|
||||
import { tangentGeometry, tangentLocal, tangentView, tangentWorld, transformedTangentView } from './TangentNode.js';
|
||||
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class BitangentNode extends Node {
|
||||
|
||||
constructor( scope = BitangentNode.LOCAL ) {
|
||||
|
||||
super( 'vec3' );
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
}
|
||||
|
||||
getHash( /*builder*/ ) {
|
||||
|
||||
return `bitangent-${this.scope}`;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const scope = this.scope;
|
||||
|
||||
let crossNormalTangent;
|
||||
|
||||
if ( scope === BitangentNode.GEOMETRY ) {
|
||||
|
||||
crossNormalTangent = normalGeometry.cross( tangentGeometry );
|
||||
|
||||
} else if ( scope === BitangentNode.LOCAL ) {
|
||||
|
||||
crossNormalTangent = normalLocal.cross( tangentLocal );
|
||||
|
||||
} else if ( scope === BitangentNode.VIEW ) {
|
||||
|
||||
crossNormalTangent = normalView.cross( tangentView );
|
||||
|
||||
} else if ( scope === BitangentNode.WORLD ) {
|
||||
|
||||
crossNormalTangent = normalWorld.cross( tangentWorld );
|
||||
|
||||
}
|
||||
|
||||
const vertexNode = crossNormalTangent.mul( tangentGeometry.w ).xyz;
|
||||
|
||||
const outputNode = normalize( varying( vertexNode ) );
|
||||
|
||||
return outputNode.build( builder, this.getNodeType( builder ) );
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.scope = this.scope;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.scope = data.scope;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BitangentNode.GEOMETRY = 'geometry';
|
||||
BitangentNode.LOCAL = 'local';
|
||||
BitangentNode.VIEW = 'view';
|
||||
BitangentNode.WORLD = 'world';
|
||||
|
||||
export default BitangentNode;
|
||||
|
||||
export const bitangentGeometry = nodeImmutable( BitangentNode, BitangentNode.GEOMETRY );
|
||||
export const bitangentLocal = nodeImmutable( BitangentNode, BitangentNode.LOCAL );
|
||||
export const bitangentView = nodeImmutable( BitangentNode, BitangentNode.VIEW );
|
||||
export const bitangentWorld = nodeImmutable( BitangentNode, BitangentNode.WORLD );
|
||||
export const transformedBitangentView = normalize( transformedNormalView.cross( transformedTangentView ).mul( tangentGeometry.w ) );
|
||||
export const transformedBitangentWorld = normalize( transformedBitangentView.transformDirection( cameraViewMatrix ) );
|
||||
|
||||
addNodeClass( 'BitangentNode', BitangentNode );
|
127
dist/electron/static/sdk/three/jsm/nodes/accessors/BufferAttributeNode.js
vendored
Normal file
127
dist/electron/static/sdk/three/jsm/nodes/accessors/BufferAttributeNode.js
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
import InputNode from '../core/InputNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { varying } from '../core/VaryingNode.js';
|
||||
import { nodeObject, addNodeElement } from '../shadernode/ShaderNode.js';
|
||||
import { InterleavedBufferAttribute, InterleavedBuffer, StaticDrawUsage, DynamicDrawUsage } from 'three';
|
||||
|
||||
class BufferAttributeNode extends InputNode {
|
||||
|
||||
constructor( value, bufferType = null, bufferStride = 0, bufferOffset = 0 ) {
|
||||
|
||||
super( value, bufferType );
|
||||
|
||||
this.isBufferNode = true;
|
||||
|
||||
this.bufferType = bufferType;
|
||||
this.bufferStride = bufferStride;
|
||||
this.bufferOffset = bufferOffset;
|
||||
|
||||
this.usage = StaticDrawUsage;
|
||||
this.instanced = false;
|
||||
|
||||
this.attribute = null;
|
||||
|
||||
if ( value && value.isBufferAttribute === true ) {
|
||||
|
||||
this.attribute = value;
|
||||
this.usage = value.usage;
|
||||
this.instanced = value.isInstancedBufferAttribute;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
if ( this.bufferType === null ) {
|
||||
|
||||
this.bufferType = builder.getTypeFromAttribute( this.attribute );
|
||||
|
||||
}
|
||||
|
||||
return this.bufferType;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
if ( this.attribute !== null ) return;
|
||||
|
||||
const type = this.getNodeType( builder );
|
||||
const array = this.value;
|
||||
const itemSize = builder.getTypeLength( type );
|
||||
const stride = this.bufferStride || itemSize;
|
||||
const offset = this.bufferOffset;
|
||||
|
||||
const buffer = array.isInterleavedBuffer === true ? array : new InterleavedBuffer( array, stride );
|
||||
const bufferAttribute = new InterleavedBufferAttribute( buffer, itemSize, offset );
|
||||
|
||||
buffer.setUsage( this.usage );
|
||||
|
||||
this.attribute = bufferAttribute;
|
||||
this.attribute.isInstancedBufferAttribute = this.instanced; // @TODO: Add a possible: InstancedInterleavedBufferAttribute
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const nodeType = this.getNodeType( builder );
|
||||
|
||||
const nodeAttribute = builder.getBufferAttributeFromNode( this, nodeType );
|
||||
const propertyName = builder.getPropertyName( nodeAttribute );
|
||||
|
||||
let output = null;
|
||||
|
||||
if ( builder.shaderStage === 'vertex' || builder.shaderStage === 'compute' ) {
|
||||
|
||||
this.name = propertyName;
|
||||
|
||||
output = propertyName;
|
||||
|
||||
} else {
|
||||
|
||||
const nodeVarying = varying( this );
|
||||
|
||||
output = nodeVarying.build( builder, nodeType );
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
getInputType( /*builder*/ ) {
|
||||
|
||||
return 'bufferAttribute';
|
||||
|
||||
}
|
||||
|
||||
setUsage( value ) {
|
||||
|
||||
this.usage = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setInstanced( value ) {
|
||||
|
||||
this.instanced = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BufferAttributeNode;
|
||||
|
||||
export const bufferAttribute = ( array, type, stride, offset ) => nodeObject( new BufferAttributeNode( array, type, stride, offset ) );
|
||||
export const dynamicBufferAttribute = ( array, type, stride, offset ) => bufferAttribute( array, type, stride, offset ).setUsage( DynamicDrawUsage );
|
||||
|
||||
export const instancedBufferAttribute = ( array, type, stride, offset ) => bufferAttribute( array, type, stride, offset ).setInstanced( true );
|
||||
export const instancedDynamicBufferAttribute = ( array, type, stride, offset ) => dynamicBufferAttribute( array, type, stride, offset ).setInstanced( true );
|
||||
|
||||
addNodeElement( 'toAttribute', ( bufferNode ) => bufferAttribute( bufferNode.value ) );
|
||||
|
||||
addNodeClass( 'BufferAttributeNode', BufferAttributeNode );
|
30
dist/electron/static/sdk/three/jsm/nodes/accessors/BufferNode.js
vendored
Normal file
30
dist/electron/static/sdk/three/jsm/nodes/accessors/BufferNode.js
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
import UniformNode from '../core/UniformNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class BufferNode extends UniformNode {
|
||||
|
||||
constructor( value, bufferType, bufferCount = 0 ) {
|
||||
|
||||
super( value, bufferType );
|
||||
|
||||
this.isBufferNode = true;
|
||||
|
||||
this.bufferType = bufferType;
|
||||
this.bufferCount = bufferCount;
|
||||
|
||||
}
|
||||
|
||||
getInputType( /*builder*/ ) {
|
||||
|
||||
return 'buffer';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BufferNode;
|
||||
|
||||
export const buffer = ( value, type, count ) => nodeObject( new BufferNode( value, type, count ) );
|
||||
|
||||
addNodeClass( 'BufferNode', BufferNode );
|
119
dist/electron/static/sdk/three/jsm/nodes/accessors/CameraNode.js
vendored
Normal file
119
dist/electron/static/sdk/three/jsm/nodes/accessors/CameraNode.js
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
import Object3DNode from './Object3DNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
//import { sharedUniformGroup } from '../core/UniformGroupNode.js';
|
||||
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
||||
|
||||
//const cameraGroup = sharedUniformGroup( 'camera' );
|
||||
|
||||
class CameraNode extends Object3DNode {
|
||||
|
||||
constructor( scope = CameraNode.POSITION ) {
|
||||
|
||||
super( scope );
|
||||
|
||||
this.updateType = NodeUpdateType.RENDER;
|
||||
|
||||
//this._uniformNode.groupNode = cameraGroup;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
const scope = this.scope;
|
||||
|
||||
if ( scope === CameraNode.PROJECTION_MATRIX || scope === CameraNode.PROJECTION_MATRIX_INVERSE ) {
|
||||
|
||||
return 'mat4';
|
||||
|
||||
} else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR || scope === CameraNode.LOG_DEPTH ) {
|
||||
|
||||
return 'float';
|
||||
|
||||
}
|
||||
|
||||
return super.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
update( frame ) {
|
||||
|
||||
const camera = frame.camera;
|
||||
const uniformNode = this._uniformNode;
|
||||
const scope = this.scope;
|
||||
|
||||
//cameraGroup.needsUpdate = true;
|
||||
|
||||
if ( scope === CameraNode.VIEW_MATRIX ) {
|
||||
|
||||
uniformNode.value = camera.matrixWorldInverse;
|
||||
|
||||
} else if ( scope === CameraNode.PROJECTION_MATRIX ) {
|
||||
|
||||
uniformNode.value = camera.projectionMatrix;
|
||||
|
||||
} else if ( scope === CameraNode.PROJECTION_MATRIX_INVERSE ) {
|
||||
|
||||
uniformNode.value = camera.projectionMatrixInverse;
|
||||
|
||||
} else if ( scope === CameraNode.NEAR ) {
|
||||
|
||||
uniformNode.value = camera.near;
|
||||
|
||||
} else if ( scope === CameraNode.FAR ) {
|
||||
|
||||
uniformNode.value = camera.far;
|
||||
|
||||
} else if ( scope === CameraNode.LOG_DEPTH ) {
|
||||
|
||||
uniformNode.value = 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 );
|
||||
|
||||
} else {
|
||||
|
||||
this.object3d = camera;
|
||||
|
||||
super.update( frame );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const scope = this.scope;
|
||||
|
||||
if ( scope === CameraNode.PROJECTION_MATRIX || scope === CameraNode.PROJECTION_MATRIX_INVERSE ) {
|
||||
|
||||
this._uniformNode.nodeType = 'mat4';
|
||||
|
||||
} else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR || scope === CameraNode.LOG_DEPTH ) {
|
||||
|
||||
this._uniformNode.nodeType = 'float';
|
||||
|
||||
}
|
||||
|
||||
return super.generate( builder );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CameraNode.PROJECTION_MATRIX = 'projectionMatrix';
|
||||
CameraNode.PROJECTION_MATRIX_INVERSE = 'projectionMatrixInverse';
|
||||
CameraNode.NEAR = 'near';
|
||||
CameraNode.FAR = 'far';
|
||||
CameraNode.LOG_DEPTH = 'logDepth';
|
||||
|
||||
export default CameraNode;
|
||||
|
||||
export const cameraProjectionMatrix = nodeImmutable( CameraNode, CameraNode.PROJECTION_MATRIX );
|
||||
export const cameraProjectionMatrixInverse = nodeImmutable( CameraNode, CameraNode.PROJECTION_MATRIX_INVERSE );
|
||||
export const cameraNear = nodeImmutable( CameraNode, CameraNode.NEAR );
|
||||
export const cameraFar = nodeImmutable( CameraNode, CameraNode.FAR );
|
||||
export const cameraLogDepth = nodeImmutable( CameraNode, CameraNode.LOG_DEPTH );
|
||||
export const cameraViewMatrix = nodeImmutable( CameraNode, CameraNode.VIEW_MATRIX );
|
||||
export const cameraNormalMatrix = nodeImmutable( CameraNode, CameraNode.NORMAL_MATRIX );
|
||||
export const cameraWorldMatrix = nodeImmutable( CameraNode, CameraNode.WORLD_MATRIX );
|
||||
export const cameraPosition = nodeImmutable( CameraNode, CameraNode.POSITION );
|
||||
|
||||
addNodeClass( 'CameraNode', CameraNode );
|
145
dist/electron/static/sdk/three/jsm/nodes/accessors/ClippingNode.js
vendored
Normal file
145
dist/electron/static/sdk/three/jsm/nodes/accessors/ClippingNode.js
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
|
||||
import Node from '../core/Node.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
import { positionView } from './PositionNode.js';
|
||||
import { diffuseColor, property } from '../core/PropertyNode.js';
|
||||
import { tslFn } from '../shadernode/ShaderNode.js';
|
||||
import { loop } from '../utils/LoopNode.js';
|
||||
import { smoothstep } from '../math/MathNode.js';
|
||||
import { uniforms } from './UniformsNode.js';
|
||||
|
||||
class ClippingNode extends Node {
|
||||
|
||||
constructor( scope = ClippingNode.DEFAULT ) {
|
||||
|
||||
super();
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
super.setup( builder );
|
||||
|
||||
const clippingContext = builder.clippingContext;
|
||||
const { localClipIntersection, localClippingCount, globalClippingCount } = clippingContext;
|
||||
|
||||
const numClippingPlanes = globalClippingCount + localClippingCount;
|
||||
const numUnionClippingPlanes = localClipIntersection ? numClippingPlanes - localClippingCount : numClippingPlanes;
|
||||
|
||||
if ( this.scope === ClippingNode.ALPHA_TO_COVERAGE ) {
|
||||
|
||||
return this.setupAlphaToCoverage( clippingContext.planes, numClippingPlanes, numUnionClippingPlanes );
|
||||
|
||||
} else {
|
||||
|
||||
return this.setupDefault( clippingContext.planes, numClippingPlanes, numUnionClippingPlanes );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setupAlphaToCoverage( planes, numClippingPlanes, numUnionClippingPlanes ) {
|
||||
|
||||
return tslFn( () => {
|
||||
|
||||
const clippingPlanes = uniforms( planes );
|
||||
|
||||
const distanceToPlane = property( 'float', 'distanceToPlane' );
|
||||
const distanceGradient = property( 'float', 'distanceToGradient' );
|
||||
|
||||
const clipOpacity = property( 'float', 'clipOpacity' );
|
||||
|
||||
clipOpacity.assign( 1 );
|
||||
|
||||
let plane;
|
||||
|
||||
loop( numUnionClippingPlanes, ( { i } ) => {
|
||||
|
||||
plane = clippingPlanes.element( i );
|
||||
|
||||
distanceToPlane.assign( positionView.dot( plane.xyz ).negate().add( plane.w ) );
|
||||
distanceGradient.assign( distanceToPlane.fwidth().div( 2.0 ) );
|
||||
|
||||
clipOpacity.mulAssign( smoothstep( distanceGradient.negate(), distanceGradient, distanceToPlane ) );
|
||||
|
||||
clipOpacity.equal( 0.0 ).discard();
|
||||
|
||||
} );
|
||||
|
||||
if ( numUnionClippingPlanes < numClippingPlanes ) {
|
||||
|
||||
const unionClipOpacity = property( 'float', 'unionclipOpacity' );
|
||||
|
||||
unionClipOpacity.assign( 1 );
|
||||
|
||||
loop( { start: numUnionClippingPlanes, end: numClippingPlanes }, ( { i } ) => {
|
||||
|
||||
plane = clippingPlanes.element( i );
|
||||
|
||||
distanceToPlane.assign( positionView.dot( plane.xyz ).negate().add( plane.w ) );
|
||||
distanceGradient.assign( distanceToPlane.fwidth().div( 2.0 ) );
|
||||
|
||||
unionClipOpacity.mulAssign( smoothstep( distanceGradient.negate(), distanceGradient, distanceToPlane ).oneMinus() );
|
||||
|
||||
} );
|
||||
|
||||
clipOpacity.mulAssign( unionClipOpacity.oneMinus() );
|
||||
|
||||
}
|
||||
|
||||
diffuseColor.a.mulAssign( clipOpacity );
|
||||
|
||||
diffuseColor.a.equal( 0.0 ).discard();
|
||||
|
||||
} )();
|
||||
|
||||
}
|
||||
|
||||
setupDefault( planes, numClippingPlanes, numUnionClippingPlanes ) {
|
||||
|
||||
return tslFn( () => {
|
||||
|
||||
const clippingPlanes = uniforms( planes );
|
||||
|
||||
let plane;
|
||||
|
||||
loop( numUnionClippingPlanes, ( { i } ) => {
|
||||
|
||||
plane = clippingPlanes.element( i );
|
||||
positionView.dot( plane.xyz ).greaterThan( plane.w ).discard();
|
||||
|
||||
} );
|
||||
|
||||
if ( numUnionClippingPlanes < numClippingPlanes ) {
|
||||
|
||||
const clipped = property( 'bool', 'clipped' );
|
||||
|
||||
clipped.assign( true );
|
||||
|
||||
loop( { start: numUnionClippingPlanes, end: numClippingPlanes }, ( { i } ) => {
|
||||
|
||||
plane = clippingPlanes.element( i );
|
||||
clipped.assign( positionView.dot( plane.xyz ).greaterThan( plane.w ).and( clipped ) );
|
||||
|
||||
} );
|
||||
|
||||
clipped.discard();
|
||||
|
||||
}
|
||||
|
||||
} )();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ClippingNode.ALPHA_TO_COVERAGE = 'alphaToCoverage';
|
||||
ClippingNode.DEFAULT = 'default';
|
||||
|
||||
export default ClippingNode;
|
||||
|
||||
export const clipping = () => nodeObject( new ClippingNode() );
|
||||
|
||||
export const clippingAlpha = () => nodeObject( new ClippingNode( ClippingNode.ALPHA_TO_COVERAGE ) );
|
61
dist/electron/static/sdk/three/jsm/nodes/accessors/CubeTextureNode.js
vendored
Normal file
61
dist/electron/static/sdk/three/jsm/nodes/accessors/CubeTextureNode.js
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
import TextureNode from './TextureNode.js';
|
||||
import { reflectVector } from './ReflectVectorNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
|
||||
import { WebGPUCoordinateSystem } from 'three';
|
||||
|
||||
class CubeTextureNode extends TextureNode {
|
||||
|
||||
constructor( value, uvNode = null, levelNode = null ) {
|
||||
|
||||
super( value, uvNode, levelNode );
|
||||
|
||||
this.isCubeTextureNode = true;
|
||||
|
||||
}
|
||||
|
||||
getInputType( /*builder*/ ) {
|
||||
|
||||
return 'cubeTexture';
|
||||
|
||||
}
|
||||
|
||||
getDefaultUV() {
|
||||
|
||||
return reflectVector;
|
||||
|
||||
}
|
||||
|
||||
setUpdateMatrix( /*updateMatrix*/ ) { } // Ignore .updateMatrix for CubeTextureNode
|
||||
|
||||
setupUV( builder, uvNode ) {
|
||||
|
||||
const texture = this.value;
|
||||
|
||||
if ( builder.renderer.coordinateSystem === WebGPUCoordinateSystem || ! texture.isRenderTargetTexture ) {
|
||||
|
||||
return vec3( uvNode.x.negate(), uvNode.yz );
|
||||
|
||||
} else {
|
||||
|
||||
return uvNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
generateUV( builder, cubeUV ) {
|
||||
|
||||
return cubeUV.build( builder, 'vec3' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CubeTextureNode;
|
||||
|
||||
export const cubeTexture = nodeProxy( CubeTextureNode );
|
||||
|
||||
addNodeElement( 'cubeTexture', cubeTexture );
|
||||
|
||||
addNodeClass( 'CubeTextureNode', CubeTextureNode );
|
94
dist/electron/static/sdk/three/jsm/nodes/accessors/InstanceNode.js
vendored
Normal file
94
dist/electron/static/sdk/three/jsm/nodes/accessors/InstanceNode.js
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { varyingProperty } from '../core/PropertyNode.js';
|
||||
import { instancedBufferAttribute, instancedDynamicBufferAttribute } from './BufferAttributeNode.js';
|
||||
import { normalLocal } from './NormalNode.js';
|
||||
import { positionLocal } from './PositionNode.js';
|
||||
import { nodeProxy, vec3, mat3, mat4 } from '../shadernode/ShaderNode.js';
|
||||
import { DynamicDrawUsage, InstancedInterleavedBuffer, InstancedBufferAttribute } from 'three';
|
||||
|
||||
class InstanceNode extends Node {
|
||||
|
||||
constructor( instanceMesh ) {
|
||||
|
||||
super( 'void' );
|
||||
|
||||
this.instanceMesh = instanceMesh;
|
||||
|
||||
this.instanceMatrixNode = null;
|
||||
|
||||
this.instanceColorNode = null;
|
||||
|
||||
}
|
||||
|
||||
setup( /*builder*/ ) {
|
||||
|
||||
let instanceMatrixNode = this.instanceMatrixNode;
|
||||
|
||||
const instanceMesh = this.instanceMesh;
|
||||
|
||||
if ( instanceMatrixNode === null ) {
|
||||
|
||||
const instanceAttribute = instanceMesh.instanceMatrix;
|
||||
const buffer = new InstancedInterleavedBuffer( instanceAttribute.array, 16, 1 );
|
||||
|
||||
const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
|
||||
|
||||
const instanceBuffers = [
|
||||
// F.Signature -> bufferAttribute( array, type, stride, offset )
|
||||
bufferFn( buffer, 'vec4', 16, 0 ),
|
||||
bufferFn( buffer, 'vec4', 16, 4 ),
|
||||
bufferFn( buffer, 'vec4', 16, 8 ),
|
||||
bufferFn( buffer, 'vec4', 16, 12 )
|
||||
];
|
||||
|
||||
instanceMatrixNode = mat4( ...instanceBuffers );
|
||||
|
||||
this.instanceMatrixNode = instanceMatrixNode;
|
||||
|
||||
}
|
||||
|
||||
const instanceColorAttribute = instanceMesh.instanceColor;
|
||||
|
||||
if ( instanceColorAttribute && this.instanceColorNode === null ) {
|
||||
|
||||
const buffer = new InstancedBufferAttribute( instanceColorAttribute.array, 3 );
|
||||
const bufferFn = instanceColorAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
|
||||
|
||||
this.instanceColorNode = vec3( bufferFn( buffer, 'vec3', 3, 0 ) );
|
||||
|
||||
}
|
||||
|
||||
// POSITION
|
||||
|
||||
const instancePosition = instanceMatrixNode.mul( positionLocal ).xyz;
|
||||
|
||||
// NORMAL
|
||||
|
||||
const m = mat3( instanceMatrixNode[ 0 ].xyz, instanceMatrixNode[ 1 ].xyz, instanceMatrixNode[ 2 ].xyz );
|
||||
|
||||
const transformedNormal = normalLocal.div( vec3( m[ 0 ].dot( m[ 0 ] ), m[ 1 ].dot( m[ 1 ] ), m[ 2 ].dot( m[ 2 ] ) ) );
|
||||
|
||||
const instanceNormal = m.mul( transformedNormal ).xyz;
|
||||
|
||||
// ASSIGNS
|
||||
|
||||
positionLocal.assign( instancePosition );
|
||||
normalLocal.assign( instanceNormal );
|
||||
|
||||
// COLOR
|
||||
|
||||
if ( this.instanceColorNode !== null ) {
|
||||
|
||||
varyingProperty( 'vec3', 'vInstanceColor' ).assign( this.instanceColorNode );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default InstanceNode;
|
||||
|
||||
export const instance = nodeProxy( InstanceNode );
|
||||
|
||||
addNodeClass( 'InstanceNode', InstanceNode );
|
21
dist/electron/static/sdk/three/jsm/nodes/accessors/InstancedPointsMaterialNode.js
vendored
Normal file
21
dist/electron/static/sdk/three/jsm/nodes/accessors/InstancedPointsMaterialNode.js
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import MaterialNode from './MaterialNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class InstancedPointsMaterialNode extends MaterialNode {
|
||||
|
||||
setup( /*builder*/ ) {
|
||||
|
||||
return this.getFloat( this.scope );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InstancedPointsMaterialNode.POINT_WIDTH = 'pointWidth';
|
||||
|
||||
export default InstancedPointsMaterialNode;
|
||||
|
||||
export const materialPointWidth = nodeImmutable( InstancedPointsMaterialNode, InstancedPointsMaterialNode.POINT_WIDTH );
|
||||
|
||||
addNodeClass( 'InstancedPointsMaterialNode', InstancedPointsMaterialNode );
|
418
dist/electron/static/sdk/three/jsm/nodes/accessors/MaterialNode.js
vendored
Normal file
418
dist/electron/static/sdk/three/jsm/nodes/accessors/MaterialNode.js
vendored
Normal file
@ -0,0 +1,418 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { reference } from './ReferenceNode.js';
|
||||
import { materialReference } from './MaterialReferenceNode.js';
|
||||
import { normalView } from './NormalNode.js';
|
||||
import { nodeImmutable, float, vec2, mat2 } from '../shadernode/ShaderNode.js';
|
||||
import { uniform } from '../core/UniformNode.js';
|
||||
import { Vector2 } from 'three';
|
||||
|
||||
const _propertyCache = new Map();
|
||||
|
||||
class MaterialNode extends Node {
|
||||
|
||||
constructor( scope ) {
|
||||
|
||||
super();
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
}
|
||||
|
||||
getCache( property, type ) {
|
||||
|
||||
let node = _propertyCache.get( property );
|
||||
|
||||
if ( node === undefined ) {
|
||||
|
||||
node = materialReference( property, type );
|
||||
|
||||
_propertyCache.set( property, node );
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
}
|
||||
|
||||
getFloat( property ) {
|
||||
|
||||
return this.getCache( property, 'float' );
|
||||
|
||||
}
|
||||
|
||||
getColor( property ) {
|
||||
|
||||
return this.getCache( property, 'color' );
|
||||
|
||||
}
|
||||
|
||||
getTexture( property ) {
|
||||
|
||||
return this.getCache( property === 'map' ? 'map' : property + 'Map', 'texture' );
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const material = builder.context.material;
|
||||
const scope = this.scope;
|
||||
|
||||
let node = null;
|
||||
|
||||
if ( scope === MaterialNode.COLOR ) {
|
||||
|
||||
const colorNode = this.getColor( scope );
|
||||
|
||||
if ( material.map && material.map.isTexture === true ) {
|
||||
|
||||
node = colorNode.mul( this.getTexture( 'map' ) );
|
||||
|
||||
} else {
|
||||
|
||||
node = colorNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.OPACITY ) {
|
||||
|
||||
const opacityNode = this.getFloat( scope );
|
||||
|
||||
if ( material.alphaMap && material.alphaMap.isTexture === true ) {
|
||||
|
||||
node = opacityNode.mul( this.getTexture( 'alpha' ) );
|
||||
|
||||
} else {
|
||||
|
||||
node = opacityNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.SPECULAR_STRENGTH ) {
|
||||
|
||||
if ( material.specularMap && material.specularMap.isTexture === true ) {
|
||||
|
||||
node = this.getTexture( 'specular' ).r;
|
||||
|
||||
} else {
|
||||
|
||||
node = float( 1 );
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.SPECULAR_INTENSITY ) {
|
||||
|
||||
const specularIntensity = this.getFloat( scope );
|
||||
|
||||
if ( material.specularMap ) {
|
||||
|
||||
node = specularIntensity.mul( this.getTexture( scope ).a );
|
||||
|
||||
} else {
|
||||
|
||||
node = specularIntensity;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.SPECULAR_COLOR ) {
|
||||
|
||||
const specularColorNode = this.getColor( scope );
|
||||
|
||||
if ( material.specularColorMap && material.specularColorMap.isTexture === true ) {
|
||||
|
||||
node = specularColorNode.mul( this.getTexture( scope ).rgb );
|
||||
|
||||
} else {
|
||||
|
||||
node = specularColorNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.ROUGHNESS ) { // TODO: cleanup similar branches
|
||||
|
||||
const roughnessNode = this.getFloat( scope );
|
||||
|
||||
if ( material.roughnessMap && material.roughnessMap.isTexture === true ) {
|
||||
|
||||
node = roughnessNode.mul( this.getTexture( scope ).g );
|
||||
|
||||
} else {
|
||||
|
||||
node = roughnessNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.METALNESS ) {
|
||||
|
||||
const metalnessNode = this.getFloat( scope );
|
||||
|
||||
if ( material.metalnessMap && material.metalnessMap.isTexture === true ) {
|
||||
|
||||
node = metalnessNode.mul( this.getTexture( scope ).b );
|
||||
|
||||
} else {
|
||||
|
||||
node = metalnessNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.EMISSIVE ) {
|
||||
|
||||
const emissiveNode = this.getColor( scope );
|
||||
|
||||
if ( material.emissiveMap && material.emissiveMap.isTexture === true ) {
|
||||
|
||||
node = emissiveNode.mul( this.getTexture( scope ) );
|
||||
|
||||
} else {
|
||||
|
||||
node = emissiveNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.NORMAL ) {
|
||||
|
||||
if ( material.normalMap ) {
|
||||
|
||||
node = this.getTexture( 'normal' ).normalMap( this.getCache( 'normalScale', 'vec2' ) );
|
||||
|
||||
} else if ( material.bumpMap ) {
|
||||
|
||||
node = this.getTexture( 'bump' ).r.bumpMap( this.getFloat( 'bumpScale' ) );
|
||||
|
||||
} else {
|
||||
|
||||
node = normalView;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.CLEARCOAT ) {
|
||||
|
||||
const clearcoatNode = this.getFloat( scope );
|
||||
|
||||
if ( material.clearcoatMap && material.clearcoatMap.isTexture === true ) {
|
||||
|
||||
node = clearcoatNode.mul( this.getTexture( scope ).r );
|
||||
|
||||
} else {
|
||||
|
||||
node = clearcoatNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.CLEARCOAT_ROUGHNESS ) {
|
||||
|
||||
const clearcoatRoughnessNode = this.getFloat( scope );
|
||||
|
||||
if ( material.clearcoatRoughnessMap && material.clearcoatRoughnessMap.isTexture === true ) {
|
||||
|
||||
node = clearcoatRoughnessNode.mul( this.getTexture( scope ).r );
|
||||
|
||||
} else {
|
||||
|
||||
node = clearcoatRoughnessNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.CLEARCOAT_NORMAL ) {
|
||||
|
||||
if ( material.clearcoatNormalMap ) {
|
||||
|
||||
node = this.getTexture( scope ).normalMap( this.getCache( scope + 'Scale', 'vec2' ) );
|
||||
|
||||
} else {
|
||||
|
||||
node = normalView;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.SHEEN ) {
|
||||
|
||||
const sheenNode = this.getColor( 'sheenColor' ).mul( this.getFloat( 'sheen' ) ); // Move this mul() to CPU
|
||||
|
||||
if ( material.sheenColorMap && material.sheenColorMap.isTexture === true ) {
|
||||
|
||||
node = sheenNode.mul( this.getTexture( 'sheenColor' ).rgb );
|
||||
|
||||
} else {
|
||||
|
||||
node = sheenNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.SHEEN_ROUGHNESS ) {
|
||||
|
||||
const sheenRoughnessNode = this.getFloat( scope );
|
||||
|
||||
if ( material.sheenRoughnessMap && material.sheenRoughnessMap.isTexture === true ) {
|
||||
|
||||
node = sheenRoughnessNode.mul( this.getTexture( scope ).a );
|
||||
|
||||
} else {
|
||||
|
||||
node = sheenRoughnessNode;
|
||||
|
||||
}
|
||||
|
||||
node = node.clamp( 0.07, 1.0 );
|
||||
|
||||
} else if ( scope === MaterialNode.ANISOTROPY ) {
|
||||
|
||||
if ( material.anisotropyMap && material.anisotropyMap.isTexture === true ) {
|
||||
|
||||
const anisotropyPolar = this.getTexture( scope );
|
||||
const anisotropyMat = mat2( materialAnisotropyVector.x, materialAnisotropyVector.y, materialAnisotropyVector.y.negate(), materialAnisotropyVector.x );
|
||||
|
||||
node = anisotropyMat.mul( anisotropyPolar.rg.mul( 2.0 ).sub( vec2( 1.0 ) ).normalize().mul( anisotropyPolar.b ) );
|
||||
|
||||
} else {
|
||||
|
||||
node = materialAnisotropyVector;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.IRIDESCENCE_THICKNESS ) {
|
||||
|
||||
const iridescenceThicknessMaximum = reference( '1', 'float', material.iridescenceThicknessRange );
|
||||
|
||||
if ( material.iridescenceThicknessMap ) {
|
||||
|
||||
const iridescenceThicknessMinimum = reference( '0', 'float', material.iridescenceThicknessRange );
|
||||
|
||||
node = iridescenceThicknessMaximum.sub( iridescenceThicknessMinimum ).mul( this.getTexture( scope ).g ).add( iridescenceThicknessMinimum );
|
||||
|
||||
} else {
|
||||
|
||||
node = iridescenceThicknessMaximum;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.TRANSMISSION ) {
|
||||
|
||||
const transmissionNode = this.getFloat( scope );
|
||||
|
||||
if ( material.transmissionMap ) {
|
||||
|
||||
node = transmissionNode.mul( this.getTexture( scope ).r );
|
||||
|
||||
} else {
|
||||
|
||||
node = transmissionNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.THICKNESS ) {
|
||||
|
||||
const thicknessNode = this.getFloat( scope );
|
||||
|
||||
if ( material.thicknessMap ) {
|
||||
|
||||
node = thicknessNode.mul( this.getTexture( scope ).g );
|
||||
|
||||
} else {
|
||||
|
||||
node = thicknessNode;
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === MaterialNode.IOR ) {
|
||||
|
||||
node = this.getFloat( scope );
|
||||
|
||||
} else {
|
||||
|
||||
const outputType = this.getNodeType( builder );
|
||||
|
||||
node = this.getCache( scope, outputType );
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MaterialNode.ALPHA_TEST = 'alphaTest';
|
||||
MaterialNode.COLOR = 'color';
|
||||
MaterialNode.OPACITY = 'opacity';
|
||||
MaterialNode.SHININESS = 'shininess';
|
||||
MaterialNode.SPECULAR = 'specular';
|
||||
MaterialNode.SPECULAR_STRENGTH = 'specularStrength';
|
||||
MaterialNode.SPECULAR_INTENSITY = 'specularIntensity';
|
||||
MaterialNode.SPECULAR_COLOR = 'specularColor';
|
||||
MaterialNode.REFLECTIVITY = 'reflectivity';
|
||||
MaterialNode.ROUGHNESS = 'roughness';
|
||||
MaterialNode.METALNESS = 'metalness';
|
||||
MaterialNode.NORMAL = 'normal';
|
||||
MaterialNode.CLEARCOAT = 'clearcoat';
|
||||
MaterialNode.CLEARCOAT_ROUGHNESS = 'clearcoatRoughness';
|
||||
MaterialNode.CLEARCOAT_NORMAL = 'clearcoatNormal';
|
||||
MaterialNode.EMISSIVE = 'emissive';
|
||||
MaterialNode.ROTATION = 'rotation';
|
||||
MaterialNode.SHEEN = 'sheen';
|
||||
MaterialNode.SHEEN_ROUGHNESS = 'sheenRoughness';
|
||||
MaterialNode.ANISOTROPY = 'anisotropy';
|
||||
MaterialNode.IRIDESCENCE = 'iridescence';
|
||||
MaterialNode.IRIDESCENCE_IOR = 'iridescenceIOR';
|
||||
MaterialNode.IRIDESCENCE_THICKNESS = 'iridescenceThickness';
|
||||
MaterialNode.IOR = 'ior';
|
||||
MaterialNode.TRANSMISSION = 'transmission';
|
||||
MaterialNode.THICKNESS = 'thickness';
|
||||
MaterialNode.ATTENUATION_DISTANCE = 'attenuationDistance';
|
||||
MaterialNode.ATTENUATION_COLOR = 'attenuationColor';
|
||||
MaterialNode.LINE_SCALE = 'scale';
|
||||
MaterialNode.LINE_DASH_SIZE = 'dashSize';
|
||||
MaterialNode.LINE_GAP_SIZE = 'gapSize';
|
||||
MaterialNode.LINE_WIDTH = 'linewidth';
|
||||
MaterialNode.LINE_DASH_OFFSET = 'dashOffset';
|
||||
MaterialNode.POINT_WIDTH = 'pointWidth';
|
||||
|
||||
export default MaterialNode;
|
||||
|
||||
export const materialAlphaTest = nodeImmutable( MaterialNode, MaterialNode.ALPHA_TEST );
|
||||
export const materialColor = nodeImmutable( MaterialNode, MaterialNode.COLOR );
|
||||
export const materialShininess = nodeImmutable( MaterialNode, MaterialNode.SHININESS );
|
||||
export const materialEmissive = nodeImmutable( MaterialNode, MaterialNode.EMISSIVE );
|
||||
export const materialOpacity = nodeImmutable( MaterialNode, MaterialNode.OPACITY );
|
||||
export const materialSpecular = nodeImmutable( MaterialNode, MaterialNode.SPECULAR );
|
||||
|
||||
export const materialSpecularIntensity = nodeImmutable( MaterialNode, MaterialNode.SPECULAR_INTENSITY );
|
||||
export const materialSpecularColor = nodeImmutable( MaterialNode, MaterialNode.SPECULAR_COLOR );
|
||||
|
||||
export const materialSpecularStrength = nodeImmutable( MaterialNode, MaterialNode.SPECULAR_STRENGTH );
|
||||
export const materialReflectivity = nodeImmutable( MaterialNode, MaterialNode.REFLECTIVITY );
|
||||
export const materialRoughness = nodeImmutable( MaterialNode, MaterialNode.ROUGHNESS );
|
||||
export const materialMetalness = nodeImmutable( MaterialNode, MaterialNode.METALNESS );
|
||||
export const materialNormal = nodeImmutable( MaterialNode, MaterialNode.NORMAL );
|
||||
export const materialClearcoat = nodeImmutable( MaterialNode, MaterialNode.CLEARCOAT );
|
||||
export const materialClearcoatRoughness = nodeImmutable( MaterialNode, MaterialNode.CLEARCOAT_ROUGHNESS );
|
||||
export const materialClearcoatNormal = nodeImmutable( MaterialNode, MaterialNode.CLEARCOAT_NORMAL );
|
||||
export const materialRotation = nodeImmutable( MaterialNode, MaterialNode.ROTATION );
|
||||
export const materialSheen = nodeImmutable( MaterialNode, MaterialNode.SHEEN );
|
||||
export const materialSheenRoughness = nodeImmutable( MaterialNode, MaterialNode.SHEEN_ROUGHNESS );
|
||||
export const materialAnisotropy = nodeImmutable( MaterialNode, MaterialNode.ANISOTROPY );
|
||||
export const materialIridescence = nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE );
|
||||
export const materialIridescenceIOR = nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE_IOR );
|
||||
export const materialIridescenceThickness = nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE_THICKNESS );
|
||||
export const materialTransmission = nodeImmutable( MaterialNode, MaterialNode.TRANSMISSION );
|
||||
export const materialThickness = nodeImmutable( MaterialNode, MaterialNode.THICKNESS );
|
||||
export const materialIOR = nodeImmutable( MaterialNode, MaterialNode.IOR );
|
||||
export const materialAttenuationDistance = nodeImmutable( MaterialNode, MaterialNode.ATTENUATION_DISTANCE );
|
||||
export const materialAttenuationColor = nodeImmutable( MaterialNode, MaterialNode.ATTENUATION_COLOR );
|
||||
export const materialLineScale = nodeImmutable( MaterialNode, MaterialNode.LINE_SCALE );
|
||||
export const materialLineDashSize = nodeImmutable( MaterialNode, MaterialNode.LINE_DASH_SIZE );
|
||||
export const materialLineGapSize = nodeImmutable( MaterialNode, MaterialNode.LINE_GAP_SIZE );
|
||||
export const materialLineWidth = nodeImmutable( MaterialNode, MaterialNode.LINE_WIDTH );
|
||||
export const materialLineDashOffset = nodeImmutable( MaterialNode, MaterialNode.LINE_DASH_OFFSET );
|
||||
export const materialPointWidth = nodeImmutable( MaterialNode, MaterialNode.POINT_WIDTH );
|
||||
export const materialAnisotropyVector = uniform( new Vector2() ).onReference( function ( frame ) {
|
||||
|
||||
return frame.material;
|
||||
|
||||
} ).onRenderUpdate( function ( { material } ) {
|
||||
|
||||
this.value.set( material.anisotropy * Math.cos( material.anisotropyRotation ), material.anisotropy * Math.sin( material.anisotropyRotation ) );
|
||||
|
||||
} );
|
||||
|
||||
addNodeClass( 'MaterialNode', MaterialNode );
|
41
dist/electron/static/sdk/three/jsm/nodes/accessors/MaterialReferenceNode.js
vendored
Normal file
41
dist/electron/static/sdk/three/jsm/nodes/accessors/MaterialReferenceNode.js
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
import ReferenceNode from './ReferenceNode.js';
|
||||
//import { renderGroup } from '../core/UniformGroupNode.js';
|
||||
//import { NodeUpdateType } from '../core/constants.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class MaterialReferenceNode extends ReferenceNode {
|
||||
|
||||
constructor( property, inputType, material = null ) {
|
||||
|
||||
super( property, inputType, material );
|
||||
|
||||
this.material = material;
|
||||
|
||||
//this.updateType = NodeUpdateType.RENDER;
|
||||
|
||||
}
|
||||
|
||||
/*setNodeType( node ) {
|
||||
|
||||
super.setNodeType( node );
|
||||
|
||||
this.node.groupNode = renderGroup;
|
||||
|
||||
}*/
|
||||
|
||||
updateReference( state ) {
|
||||
|
||||
this.reference = this.material !== null ? this.material : state.material;
|
||||
|
||||
return this.reference;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default MaterialReferenceNode;
|
||||
|
||||
export const materialReference = ( name, type, material ) => nodeObject( new MaterialReferenceNode( name, type, material ) );
|
||||
|
||||
addNodeClass( 'MaterialReferenceNode', MaterialReferenceNode );
|
33
dist/electron/static/sdk/three/jsm/nodes/accessors/ModelNode.js
vendored
Normal file
33
dist/electron/static/sdk/three/jsm/nodes/accessors/ModelNode.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
import Object3DNode from './Object3DNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class ModelNode extends Object3DNode {
|
||||
|
||||
constructor( scope = ModelNode.VIEW_MATRIX ) {
|
||||
|
||||
super( scope );
|
||||
|
||||
}
|
||||
|
||||
update( frame ) {
|
||||
|
||||
this.object3d = frame.object;
|
||||
|
||||
super.update( frame );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ModelNode;
|
||||
|
||||
export const modelDirection = nodeImmutable( ModelNode, ModelNode.DIRECTION );
|
||||
export const modelViewMatrix = nodeImmutable( ModelNode, ModelNode.VIEW_MATRIX ).label( 'modelViewMatrix' ).temp( 'ModelViewMatrix' );
|
||||
export const modelNormalMatrix = nodeImmutable( ModelNode, ModelNode.NORMAL_MATRIX );
|
||||
export const modelWorldMatrix = nodeImmutable( ModelNode, ModelNode.WORLD_MATRIX );
|
||||
export const modelPosition = nodeImmutable( ModelNode, ModelNode.POSITION );
|
||||
export const modelScale = nodeImmutable( ModelNode, ModelNode.SCALE );
|
||||
export const modelViewPosition = nodeImmutable( ModelNode, ModelNode.VIEW_POSITION );
|
||||
|
||||
addNodeClass( 'ModelNode', ModelNode );
|
39
dist/electron/static/sdk/three/jsm/nodes/accessors/ModelViewProjectionNode.js
vendored
Normal file
39
dist/electron/static/sdk/three/jsm/nodes/accessors/ModelViewProjectionNode.js
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { cameraProjectionMatrix } from './CameraNode.js';
|
||||
import { modelViewMatrix } from './ModelNode.js';
|
||||
import { positionLocal } from './PositionNode.js';
|
||||
import { nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
import { varying } from '../core/VaryingNode.js';
|
||||
|
||||
class ModelViewProjectionNode extends TempNode {
|
||||
|
||||
constructor( positionNode = null ) {
|
||||
|
||||
super( 'vec4' );
|
||||
|
||||
this.positionNode = positionNode;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
if ( builder.shaderStage === 'fragment' ) {
|
||||
|
||||
return varying( builder.context.mvp );
|
||||
|
||||
}
|
||||
|
||||
const position = this.positionNode || positionLocal;
|
||||
|
||||
return cameraProjectionMatrix.mul( modelViewMatrix ).mul( position );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ModelViewProjectionNode;
|
||||
|
||||
export const modelViewProjection = nodeProxy( ModelViewProjectionNode );
|
||||
|
||||
addNodeClass( 'ModelViewProjectionNode', ModelViewProjectionNode );
|
255
dist/electron/static/sdk/three/jsm/nodes/accessors/MorphNode.js
vendored
Normal file
255
dist/electron/static/sdk/three/jsm/nodes/accessors/MorphNode.js
vendored
Normal file
@ -0,0 +1,255 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { float, nodeProxy, tslFn } from '../shadernode/ShaderNode.js';
|
||||
import { uniform } from '../core/UniformNode.js';
|
||||
import { reference } from './ReferenceNode.js';
|
||||
import { positionLocal } from './PositionNode.js';
|
||||
import { normalLocal } from './NormalNode.js';
|
||||
import { textureLoad } from './TextureNode.js';
|
||||
import { instanceIndex, vertexIndex } from '../core/IndexNode.js';
|
||||
import { ivec2, int } from '../shadernode/ShaderNode.js';
|
||||
import { DataArrayTexture, Vector2, Vector4, FloatType } from 'three';
|
||||
import { loop } from '../utils/LoopNode.js';
|
||||
|
||||
const morphTextures = new WeakMap();
|
||||
const morphVec4 = new Vector4();
|
||||
|
||||
const getMorph = tslFn( ( { bufferMap, influence, stride, width, depth, offset } ) => {
|
||||
|
||||
const texelIndex = int( vertexIndex ).mul( stride ).add( offset );
|
||||
|
||||
const y = texelIndex.div( width );
|
||||
const x = texelIndex.sub( y.mul( width ) );
|
||||
|
||||
const bufferAttrib = textureLoad( bufferMap, ivec2( x, y ) ).depth( depth );
|
||||
|
||||
return bufferAttrib.mul( influence );
|
||||
|
||||
} );
|
||||
|
||||
function getEntry( geometry ) {
|
||||
|
||||
const hasMorphPosition = geometry.morphAttributes.position !== undefined;
|
||||
const hasMorphNormals = geometry.morphAttributes.normal !== undefined;
|
||||
const hasMorphColors = geometry.morphAttributes.color !== undefined;
|
||||
|
||||
// instead of using attributes, the WebGL 2 code path encodes morph targets
|
||||
// into an array of data textures. Each layer represents a single morph target.
|
||||
|
||||
const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
|
||||
const morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0;
|
||||
|
||||
let entry = morphTextures.get( geometry );
|
||||
|
||||
if ( entry === undefined || entry.count !== morphTargetsCount ) {
|
||||
|
||||
if ( entry !== undefined ) entry.texture.dispose();
|
||||
|
||||
const morphTargets = geometry.morphAttributes.position || [];
|
||||
const morphNormals = geometry.morphAttributes.normal || [];
|
||||
const morphColors = geometry.morphAttributes.color || [];
|
||||
|
||||
let vertexDataCount = 0;
|
||||
|
||||
if ( hasMorphPosition === true ) vertexDataCount = 1;
|
||||
if ( hasMorphNormals === true ) vertexDataCount = 2;
|
||||
if ( hasMorphColors === true ) vertexDataCount = 3;
|
||||
|
||||
let width = geometry.attributes.position.count * vertexDataCount;
|
||||
let height = 1;
|
||||
|
||||
const maxTextureSize = 4096; // @TODO: Use 'capabilities.maxTextureSize'
|
||||
|
||||
if ( width > maxTextureSize ) {
|
||||
|
||||
height = Math.ceil( width / maxTextureSize );
|
||||
width = maxTextureSize;
|
||||
|
||||
}
|
||||
|
||||
const buffer = new Float32Array( width * height * 4 * morphTargetsCount );
|
||||
|
||||
const bufferTexture = new DataArrayTexture( buffer, width, height, morphTargetsCount );
|
||||
bufferTexture.type = FloatType;
|
||||
bufferTexture.needsUpdate = true;
|
||||
|
||||
// fill buffer
|
||||
|
||||
const vertexDataStride = vertexDataCount * 4;
|
||||
|
||||
for ( let i = 0; i < morphTargetsCount; i ++ ) {
|
||||
|
||||
const morphTarget = morphTargets[ i ];
|
||||
const morphNormal = morphNormals[ i ];
|
||||
const morphColor = morphColors[ i ];
|
||||
|
||||
const offset = width * height * 4 * i;
|
||||
|
||||
for ( let j = 0; j < morphTarget.count; j ++ ) {
|
||||
|
||||
const stride = j * vertexDataStride;
|
||||
|
||||
if ( hasMorphPosition === true ) {
|
||||
|
||||
morphVec4.fromBufferAttribute( morphTarget, j );
|
||||
|
||||
buffer[ offset + stride + 0 ] = morphVec4.x;
|
||||
buffer[ offset + stride + 1 ] = morphVec4.y;
|
||||
buffer[ offset + stride + 2 ] = morphVec4.z;
|
||||
buffer[ offset + stride + 3 ] = 0;
|
||||
|
||||
}
|
||||
|
||||
if ( hasMorphNormals === true ) {
|
||||
|
||||
morphVec4.fromBufferAttribute( morphNormal, j );
|
||||
|
||||
buffer[ offset + stride + 4 ] = morphVec4.x;
|
||||
buffer[ offset + stride + 5 ] = morphVec4.y;
|
||||
buffer[ offset + stride + 6 ] = morphVec4.z;
|
||||
buffer[ offset + stride + 7 ] = 0;
|
||||
|
||||
}
|
||||
|
||||
if ( hasMorphColors === true ) {
|
||||
|
||||
morphVec4.fromBufferAttribute( morphColor, j );
|
||||
|
||||
buffer[ offset + stride + 8 ] = morphVec4.x;
|
||||
buffer[ offset + stride + 9 ] = morphVec4.y;
|
||||
buffer[ offset + stride + 10 ] = morphVec4.z;
|
||||
buffer[ offset + stride + 11 ] = ( morphColor.itemSize === 4 ) ? morphVec4.w : 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
entry = {
|
||||
count: morphTargetsCount,
|
||||
texture: bufferTexture,
|
||||
stride: vertexDataCount,
|
||||
size: new Vector2( width, height )
|
||||
};
|
||||
|
||||
morphTextures.set( geometry, entry );
|
||||
|
||||
function disposeTexture() {
|
||||
|
||||
bufferTexture.dispose();
|
||||
|
||||
morphTextures.delete( geometry );
|
||||
|
||||
geometry.removeEventListener( 'dispose', disposeTexture );
|
||||
|
||||
}
|
||||
|
||||
geometry.addEventListener( 'dispose', disposeTexture );
|
||||
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
|
||||
class MorphNode extends Node {
|
||||
|
||||
constructor( mesh ) {
|
||||
|
||||
super( 'void' );
|
||||
|
||||
this.mesh = mesh;
|
||||
this.morphBaseInfluence = uniform( 1 );
|
||||
|
||||
this.updateType = NodeUpdateType.OBJECT;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const { geometry } = builder;
|
||||
|
||||
const hasMorphPosition = geometry.morphAttributes.position !== undefined;
|
||||
const hasMorphNormals = geometry.morphAttributes.normal !== undefined;
|
||||
|
||||
const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
|
||||
const morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0;
|
||||
|
||||
// nodes
|
||||
|
||||
const { texture: bufferMap, stride, size } = getEntry( geometry );
|
||||
|
||||
if ( hasMorphPosition === true ) positionLocal.mulAssign( this.morphBaseInfluence );
|
||||
if ( hasMorphNormals === true ) normalLocal.mulAssign( this.morphBaseInfluence );
|
||||
|
||||
const width = int( size.width );
|
||||
|
||||
loop( morphTargetsCount, ( { i } ) => {
|
||||
|
||||
const influence = float( 0 ).toVar();
|
||||
|
||||
if ( this.mesh.isInstancedMesh === true && ( this.mesh.morphTexture !== null && this.mesh.morphTexture !== undefined ) ) {
|
||||
|
||||
influence.assign( textureLoad( this.mesh.morphTexture, ivec2( int( i ).add( 1 ), int( instanceIndex ) ) ).r );
|
||||
|
||||
} else {
|
||||
|
||||
influence.assign( reference( 'morphTargetInfluences', 'float' ).element( i ).toVar() );
|
||||
|
||||
}
|
||||
|
||||
if ( hasMorphPosition === true ) {
|
||||
|
||||
positionLocal.addAssign( getMorph( {
|
||||
bufferMap,
|
||||
influence,
|
||||
stride,
|
||||
width,
|
||||
depth: i,
|
||||
offset: int( 0 )
|
||||
} ) );
|
||||
|
||||
}
|
||||
|
||||
if ( hasMorphNormals === true ) {
|
||||
|
||||
normalLocal.addAssign( getMorph( {
|
||||
bufferMap,
|
||||
influence,
|
||||
stride,
|
||||
width,
|
||||
depth: i,
|
||||
offset: int( 1 )
|
||||
} ) );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const morphBaseInfluence = this.morphBaseInfluence;
|
||||
|
||||
if ( this.mesh.geometry.morphTargetsRelative ) {
|
||||
|
||||
morphBaseInfluence.value = 1;
|
||||
|
||||
} else {
|
||||
|
||||
morphBaseInfluence.value = 1 - this.mesh.morphTargetInfluences.reduce( ( a, b ) => a + b, 0 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default MorphNode;
|
||||
|
||||
export const morphReference = nodeProxy( MorphNode );
|
||||
|
||||
addNodeClass( 'MorphNode', MorphNode );
|
106
dist/electron/static/sdk/three/jsm/nodes/accessors/NormalNode.js
vendored
Normal file
106
dist/electron/static/sdk/three/jsm/nodes/accessors/NormalNode.js
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { attribute } from '../core/AttributeNode.js';
|
||||
import { varying } from '../core/VaryingNode.js';
|
||||
import { property } from '../core/PropertyNode.js';
|
||||
import { normalize } from '../math/MathNode.js';
|
||||
import { cameraViewMatrix } from './CameraNode.js';
|
||||
import { modelNormalMatrix } from './ModelNode.js';
|
||||
import { nodeImmutable, vec3 } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class NormalNode extends Node {
|
||||
|
||||
constructor( scope = NormalNode.LOCAL ) {
|
||||
|
||||
super( 'vec3' );
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
}
|
||||
|
||||
isGlobal() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
getHash( /*builder*/ ) {
|
||||
|
||||
return `normal-${this.scope}`;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const scope = this.scope;
|
||||
|
||||
let outputNode = null;
|
||||
|
||||
if ( scope === NormalNode.GEOMETRY ) {
|
||||
|
||||
const geometryAttribute = builder.hasGeometryAttribute( 'normal' );
|
||||
|
||||
if ( geometryAttribute === false ) {
|
||||
|
||||
outputNode = vec3( 0, 1, 0 );
|
||||
|
||||
} else {
|
||||
|
||||
outputNode = attribute( 'normal', 'vec3' );
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === NormalNode.LOCAL ) {
|
||||
|
||||
outputNode = varying( normalGeometry );
|
||||
|
||||
} else if ( scope === NormalNode.VIEW ) {
|
||||
|
||||
const vertexNode = modelNormalMatrix.mul( normalLocal );
|
||||
outputNode = normalize( varying( vertexNode ) );
|
||||
|
||||
} else if ( scope === NormalNode.WORLD ) {
|
||||
|
||||
// To use inverseTransformDirection only inverse the param order like this: cameraViewMatrix.transformDirection( normalView )
|
||||
const vertexNode = normalView.transformDirection( cameraViewMatrix );
|
||||
outputNode = normalize( varying( vertexNode ) );
|
||||
|
||||
}
|
||||
|
||||
return outputNode.build( builder, this.getNodeType( builder ) );
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.scope = this.scope;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.scope = data.scope;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NormalNode.GEOMETRY = 'geometry';
|
||||
NormalNode.LOCAL = 'local';
|
||||
NormalNode.VIEW = 'view';
|
||||
NormalNode.WORLD = 'world';
|
||||
|
||||
export default NormalNode;
|
||||
|
||||
export const normalGeometry = nodeImmutable( NormalNode, NormalNode.GEOMETRY );
|
||||
export const normalLocal = nodeImmutable( NormalNode, NormalNode.LOCAL ).temp( 'Normal' );
|
||||
export const normalView = nodeImmutable( NormalNode, NormalNode.VIEW );
|
||||
export const normalWorld = nodeImmutable( NormalNode, NormalNode.WORLD );
|
||||
export const transformedNormalView = property( 'vec3', 'TransformedNormalView' );
|
||||
export const transformedNormalWorld = transformedNormalView.transformDirection( cameraViewMatrix ).normalize();
|
||||
export const transformedClearcoatNormalView = property( 'vec3', 'TransformedClearcoatNormalView' );
|
||||
|
||||
addNodeClass( 'NormalNode', NormalNode );
|
150
dist/electron/static/sdk/three/jsm/nodes/accessors/Object3DNode.js
vendored
Normal file
150
dist/electron/static/sdk/three/jsm/nodes/accessors/Object3DNode.js
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import UniformNode from '../core/UniformNode.js';
|
||||
import { nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
import { Vector3 } from 'three';
|
||||
|
||||
class Object3DNode extends Node {
|
||||
|
||||
constructor( scope = Object3DNode.VIEW_MATRIX, object3d = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.scope = scope;
|
||||
this.object3d = object3d;
|
||||
|
||||
this.updateType = NodeUpdateType.OBJECT;
|
||||
|
||||
this._uniformNode = new UniformNode( null );
|
||||
|
||||
}
|
||||
|
||||
getNodeType() {
|
||||
|
||||
const scope = this.scope;
|
||||
|
||||
if ( scope === Object3DNode.WORLD_MATRIX || scope === Object3DNode.VIEW_MATRIX ) {
|
||||
|
||||
return 'mat4';
|
||||
|
||||
} else if ( scope === Object3DNode.NORMAL_MATRIX ) {
|
||||
|
||||
return 'mat3';
|
||||
|
||||
} else if ( scope === Object3DNode.POSITION || scope === Object3DNode.VIEW_POSITION || scope === Object3DNode.DIRECTION || scope === Object3DNode.SCALE ) {
|
||||
|
||||
return 'vec3';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update( frame ) {
|
||||
|
||||
const object = this.object3d;
|
||||
const uniformNode = this._uniformNode;
|
||||
const scope = this.scope;
|
||||
|
||||
if ( scope === Object3DNode.VIEW_MATRIX ) {
|
||||
|
||||
uniformNode.value = object.modelViewMatrix;
|
||||
|
||||
} else if ( scope === Object3DNode.NORMAL_MATRIX ) {
|
||||
|
||||
uniformNode.value = object.normalMatrix;
|
||||
|
||||
} else if ( scope === Object3DNode.WORLD_MATRIX ) {
|
||||
|
||||
uniformNode.value = object.matrixWorld;
|
||||
|
||||
} else if ( scope === Object3DNode.POSITION ) {
|
||||
|
||||
uniformNode.value = uniformNode.value || new Vector3();
|
||||
|
||||
uniformNode.value.setFromMatrixPosition( object.matrixWorld );
|
||||
|
||||
} else if ( scope === Object3DNode.SCALE ) {
|
||||
|
||||
uniformNode.value = uniformNode.value || new Vector3();
|
||||
|
||||
uniformNode.value.setFromMatrixScale( object.matrixWorld );
|
||||
|
||||
} else if ( scope === Object3DNode.DIRECTION ) {
|
||||
|
||||
uniformNode.value = uniformNode.value || new Vector3();
|
||||
|
||||
object.getWorldDirection( uniformNode.value );
|
||||
|
||||
} else if ( scope === Object3DNode.VIEW_POSITION ) {
|
||||
|
||||
const camera = frame.camera;
|
||||
|
||||
uniformNode.value = uniformNode.value || new Vector3();
|
||||
uniformNode.value.setFromMatrixPosition( object.matrixWorld );
|
||||
|
||||
uniformNode.value.applyMatrix4( camera.matrixWorldInverse );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const scope = this.scope;
|
||||
|
||||
if ( scope === Object3DNode.WORLD_MATRIX || scope === Object3DNode.VIEW_MATRIX ) {
|
||||
|
||||
this._uniformNode.nodeType = 'mat4';
|
||||
|
||||
} else if ( scope === Object3DNode.NORMAL_MATRIX ) {
|
||||
|
||||
this._uniformNode.nodeType = 'mat3';
|
||||
|
||||
} else if ( scope === Object3DNode.POSITION || scope === Object3DNode.VIEW_POSITION || scope === Object3DNode.DIRECTION || scope === Object3DNode.SCALE ) {
|
||||
|
||||
this._uniformNode.nodeType = 'vec3';
|
||||
|
||||
}
|
||||
|
||||
return this._uniformNode.build( builder );
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.scope = this.scope;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.scope = data.scope;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object3DNode.VIEW_MATRIX = 'viewMatrix';
|
||||
Object3DNode.NORMAL_MATRIX = 'normalMatrix';
|
||||
Object3DNode.WORLD_MATRIX = 'worldMatrix';
|
||||
Object3DNode.POSITION = 'position';
|
||||
Object3DNode.SCALE = 'scale';
|
||||
Object3DNode.VIEW_POSITION = 'viewPosition';
|
||||
Object3DNode.DIRECTION = 'direction';
|
||||
|
||||
export default Object3DNode;
|
||||
|
||||
export const objectDirection = nodeProxy( Object3DNode, Object3DNode.DIRECTION );
|
||||
export const objectViewMatrix = nodeProxy( Object3DNode, Object3DNode.VIEW_MATRIX );
|
||||
export const objectNormalMatrix = nodeProxy( Object3DNode, Object3DNode.NORMAL_MATRIX );
|
||||
export const objectWorldMatrix = nodeProxy( Object3DNode, Object3DNode.WORLD_MATRIX );
|
||||
export const objectPosition = nodeProxy( Object3DNode, Object3DNode.POSITION );
|
||||
export const objectScale = nodeProxy( Object3DNode, Object3DNode.SCALE );
|
||||
export const objectViewPosition = nodeProxy( Object3DNode, Object3DNode.VIEW_POSITION );
|
||||
|
||||
addNodeClass( 'Object3DNode', Object3DNode );
|
26
dist/electron/static/sdk/three/jsm/nodes/accessors/PointUVNode.js
vendored
Normal file
26
dist/electron/static/sdk/three/jsm/nodes/accessors/PointUVNode.js
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class PointUVNode extends Node {
|
||||
|
||||
constructor() {
|
||||
|
||||
super( 'vec2' );
|
||||
|
||||
this.isPointUVNode = true;
|
||||
|
||||
}
|
||||
|
||||
generate( /*builder*/ ) {
|
||||
|
||||
return 'vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y )';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default PointUVNode;
|
||||
|
||||
export const pointUV = nodeImmutable( PointUVNode );
|
||||
|
||||
addNodeClass( 'PointUVNode', PointUVNode );
|
104
dist/electron/static/sdk/three/jsm/nodes/accessors/PositionNode.js
vendored
Normal file
104
dist/electron/static/sdk/three/jsm/nodes/accessors/PositionNode.js
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { attribute } from '../core/AttributeNode.js';
|
||||
import { varying } from '../core/VaryingNode.js';
|
||||
import { normalize } from '../math/MathNode.js';
|
||||
import { modelWorldMatrix, modelViewMatrix } from './ModelNode.js';
|
||||
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class PositionNode extends Node {
|
||||
|
||||
constructor( scope = PositionNode.LOCAL ) {
|
||||
|
||||
super( 'vec3' );
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
}
|
||||
|
||||
isGlobal() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
getHash( /*builder*/ ) {
|
||||
|
||||
return `position-${this.scope}`;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const scope = this.scope;
|
||||
|
||||
let outputNode = null;
|
||||
|
||||
if ( scope === PositionNode.GEOMETRY ) {
|
||||
|
||||
outputNode = attribute( 'position', 'vec3' );
|
||||
|
||||
} else if ( scope === PositionNode.LOCAL ) {
|
||||
|
||||
outputNode = varying( positionGeometry );
|
||||
|
||||
} else if ( scope === PositionNode.WORLD ) {
|
||||
|
||||
const vertexPositionNode = modelWorldMatrix.mul( positionLocal );
|
||||
outputNode = varying( vertexPositionNode );
|
||||
|
||||
} else if ( scope === PositionNode.VIEW ) {
|
||||
|
||||
const vertexPositionNode = modelViewMatrix.mul( positionLocal );
|
||||
outputNode = varying( vertexPositionNode );
|
||||
|
||||
} else if ( scope === PositionNode.VIEW_DIRECTION ) {
|
||||
|
||||
const vertexPositionNode = positionView.negate();
|
||||
outputNode = normalize( varying( vertexPositionNode ) );
|
||||
|
||||
} else if ( scope === PositionNode.WORLD_DIRECTION ) {
|
||||
|
||||
const vertexPositionNode = positionLocal.transformDirection( modelWorldMatrix );
|
||||
outputNode = normalize( varying( vertexPositionNode ) );
|
||||
|
||||
}
|
||||
|
||||
return outputNode.build( builder, this.getNodeType( builder ) );
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.scope = this.scope;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.scope = data.scope;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PositionNode.GEOMETRY = 'geometry';
|
||||
PositionNode.LOCAL = 'local';
|
||||
PositionNode.WORLD = 'world';
|
||||
PositionNode.WORLD_DIRECTION = 'worldDirection';
|
||||
PositionNode.VIEW = 'view';
|
||||
PositionNode.VIEW_DIRECTION = 'viewDirection';
|
||||
|
||||
export default PositionNode;
|
||||
|
||||
export const positionGeometry = nodeImmutable( PositionNode, PositionNode.GEOMETRY );
|
||||
export const positionLocal = nodeImmutable( PositionNode, PositionNode.LOCAL ).temp( 'Position' );
|
||||
export const positionWorld = nodeImmutable( PositionNode, PositionNode.WORLD );
|
||||
export const positionWorldDirection = nodeImmutable( PositionNode, PositionNode.WORLD_DIRECTION );
|
||||
export const positionView = nodeImmutable( PositionNode, PositionNode.VIEW );
|
||||
export const positionViewDirection = nodeImmutable( PositionNode, PositionNode.VIEW_DIRECTION );
|
||||
|
||||
addNodeClass( 'PositionNode', PositionNode );
|
160
dist/electron/static/sdk/three/jsm/nodes/accessors/ReferenceNode.js
vendored
Normal file
160
dist/electron/static/sdk/three/jsm/nodes/accessors/ReferenceNode.js
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { uniform } from '../core/UniformNode.js';
|
||||
import { texture } from './TextureNode.js';
|
||||
import { buffer } from './BufferNode.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
import { uniforms } from './UniformsNode.js';
|
||||
import ArrayElementNode from '../utils/ArrayElementNode.js';
|
||||
|
||||
class ReferenceElementNode extends ArrayElementNode {
|
||||
|
||||
constructor( referenceNode, indexNode ) {
|
||||
|
||||
super( referenceNode, indexNode );
|
||||
|
||||
this.referenceNode = referenceNode;
|
||||
|
||||
this.isReferenceElementNode = true;
|
||||
|
||||
}
|
||||
|
||||
getNodeType() {
|
||||
|
||||
return this.referenceNode.uniformType;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const snippet = super.generate( builder );
|
||||
const arrayType = this.referenceNode.getNodeType();
|
||||
const elementType = this.getNodeType();
|
||||
|
||||
return builder.format( snippet, arrayType, elementType );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ReferenceNode extends Node {
|
||||
|
||||
constructor( property, uniformType, object = null, count = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.property = property;
|
||||
this.uniformType = uniformType;
|
||||
this.object = object;
|
||||
this.count = count;
|
||||
|
||||
this.properties = property.split( '.' );
|
||||
this.reference = null;
|
||||
this.node = null;
|
||||
|
||||
this.updateType = NodeUpdateType.OBJECT;
|
||||
|
||||
}
|
||||
|
||||
element( indexNode ) {
|
||||
|
||||
return nodeObject( new ReferenceElementNode( this, nodeObject( indexNode ) ) );
|
||||
|
||||
}
|
||||
|
||||
setNodeType( uniformType ) {
|
||||
|
||||
let node = null;
|
||||
|
||||
if ( this.count !== null ) {
|
||||
|
||||
node = buffer( null, uniformType, this.count );
|
||||
|
||||
} else if ( Array.isArray( this.getValueFromReference() ) ) {
|
||||
|
||||
node = uniforms( null, uniformType );
|
||||
|
||||
} else if ( uniformType === 'texture' ) {
|
||||
|
||||
node = texture( null );
|
||||
|
||||
} else {
|
||||
|
||||
node = uniform( null, uniformType );
|
||||
|
||||
}
|
||||
|
||||
this.node = node;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.node.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
getValueFromReference( object = this.reference ) {
|
||||
|
||||
const { properties } = this;
|
||||
|
||||
let value = object[ properties[ 0 ] ];
|
||||
|
||||
for ( let i = 1; i < properties.length; i ++ ) {
|
||||
|
||||
value = value[ properties[ i ] ];
|
||||
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
updateReference( state ) {
|
||||
|
||||
this.reference = this.object !== null ? this.object : state.object;
|
||||
|
||||
return this.reference;
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
this.updateValue();
|
||||
|
||||
return this.node;
|
||||
|
||||
}
|
||||
|
||||
update( /*frame*/ ) {
|
||||
|
||||
this.updateValue();
|
||||
|
||||
}
|
||||
|
||||
updateValue() {
|
||||
|
||||
if ( this.node === null ) this.setNodeType( this.uniformType );
|
||||
|
||||
const value = this.getValueFromReference();
|
||||
|
||||
if ( Array.isArray( value ) ) {
|
||||
|
||||
this.node.array = value;
|
||||
|
||||
} else {
|
||||
|
||||
this.node.value = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ReferenceNode;
|
||||
|
||||
export const reference = ( name, type, object ) => nodeObject( new ReferenceNode( name, type, object ) );
|
||||
export const referenceBuffer = ( name, type, count, object ) => nodeObject( new ReferenceNode( name, type, object, count ) );
|
||||
|
||||
addNodeClass( 'ReferenceNode', ReferenceNode );
|
35
dist/electron/static/sdk/three/jsm/nodes/accessors/ReflectVectorNode.js
vendored
Normal file
35
dist/electron/static/sdk/three/jsm/nodes/accessors/ReflectVectorNode.js
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { cameraViewMatrix } from './CameraNode.js';
|
||||
import { transformedNormalView } from './NormalNode.js';
|
||||
import { positionViewDirection } from './PositionNode.js';
|
||||
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class ReflectVectorNode extends Node {
|
||||
|
||||
constructor() {
|
||||
|
||||
super( 'vec3' );
|
||||
|
||||
}
|
||||
|
||||
getHash( /*builder*/ ) {
|
||||
|
||||
return 'reflectVector';
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
const reflectView = positionViewDirection.negate().reflect( transformedNormalView );
|
||||
|
||||
return reflectView.transformDirection( cameraViewMatrix );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ReflectVectorNode;
|
||||
|
||||
export const reflectVector = nodeImmutable( ReflectVectorNode );
|
||||
|
||||
addNodeClass( 'ReflectVectorNode', ReflectVectorNode );
|
29
dist/electron/static/sdk/three/jsm/nodes/accessors/RendererReferenceNode.js
vendored
Normal file
29
dist/electron/static/sdk/three/jsm/nodes/accessors/RendererReferenceNode.js
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
import ReferenceNode from './ReferenceNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class RendererReferenceNode extends ReferenceNode {
|
||||
|
||||
constructor( property, inputType, renderer = null ) {
|
||||
|
||||
super( property, inputType, renderer );
|
||||
|
||||
this.renderer = renderer;
|
||||
|
||||
}
|
||||
|
||||
updateReference( state ) {
|
||||
|
||||
this.reference = this.renderer !== null ? this.renderer : state.renderer;
|
||||
|
||||
return this.reference;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RendererReferenceNode;
|
||||
|
||||
export const rendererReference = ( name, type, renderer ) => nodeObject( new RendererReferenceNode( name, type, renderer ) );
|
||||
|
||||
addNodeClass( 'RendererReferenceNode', RendererReferenceNode );
|
52
dist/electron/static/sdk/three/jsm/nodes/accessors/SceneNode.js
vendored
Normal file
52
dist/electron/static/sdk/three/jsm/nodes/accessors/SceneNode.js
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
import Node from '../core/Node.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
||||
import { reference } from './ReferenceNode.js';
|
||||
|
||||
class SceneNode extends Node {
|
||||
|
||||
constructor( scope = SceneNode.BACKGROUND_BLURRINESS, scene = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.scope = scope;
|
||||
this.scene = scene;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const scope = this.scope;
|
||||
const scene = this.scene !== null ? this.scene : builder.scene;
|
||||
|
||||
let output;
|
||||
|
||||
if ( scope === SceneNode.BACKGROUND_BLURRINESS ) {
|
||||
|
||||
output = reference( 'backgroundBlurriness', 'float', scene );
|
||||
|
||||
} else if ( scope === SceneNode.BACKGROUND_INTENSITY ) {
|
||||
|
||||
output = reference( 'backgroundIntensity', 'float', scene );
|
||||
|
||||
} else {
|
||||
|
||||
console.error( 'THREE.SceneNode: Unknown scope:', scope );
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SceneNode.BACKGROUND_BLURRINESS = 'backgroundBlurriness';
|
||||
SceneNode.BACKGROUND_INTENSITY = 'backgroundIntensity';
|
||||
|
||||
export default SceneNode;
|
||||
|
||||
export const backgroundBlurriness = nodeImmutable( SceneNode, SceneNode.BACKGROUND_BLURRINESS );
|
||||
export const backgroundIntensity = nodeImmutable( SceneNode, SceneNode.BACKGROUND_INTENSITY );
|
||||
|
||||
addNodeClass( 'SceneNode', SceneNode );
|
124
dist/electron/static/sdk/three/jsm/nodes/accessors/SkinningNode.js
vendored
Normal file
124
dist/electron/static/sdk/three/jsm/nodes/accessors/SkinningNode.js
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
import { attribute } from '../core/AttributeNode.js';
|
||||
import { reference, referenceBuffer } from './ReferenceNode.js';
|
||||
import { add } from '../math/OperatorNode.js';
|
||||
import { normalLocal } from './NormalNode.js';
|
||||
import { positionLocal } from './PositionNode.js';
|
||||
import { tangentLocal } from './TangentNode.js';
|
||||
import { uniform } from '../core/UniformNode.js';
|
||||
import { buffer } from './BufferNode.js';
|
||||
|
||||
class SkinningNode extends Node {
|
||||
|
||||
constructor( skinnedMesh, useReference = false ) {
|
||||
|
||||
super( 'void' );
|
||||
|
||||
this.skinnedMesh = skinnedMesh;
|
||||
this.useReference = useReference;
|
||||
|
||||
this.updateType = NodeUpdateType.OBJECT;
|
||||
|
||||
//
|
||||
|
||||
this.skinIndexNode = attribute( 'skinIndex', 'uvec4' );
|
||||
this.skinWeightNode = attribute( 'skinWeight', 'vec4' );
|
||||
|
||||
let bindMatrixNode, bindMatrixInverseNode, boneMatricesNode;
|
||||
|
||||
if ( useReference ) {
|
||||
|
||||
bindMatrixNode = reference( 'bindMatrix', 'mat4' );
|
||||
bindMatrixInverseNode = reference( 'bindMatrixInverse', 'mat4' );
|
||||
boneMatricesNode = referenceBuffer( 'skeleton.boneMatrices', 'mat4', skinnedMesh.skeleton.bones.length );
|
||||
|
||||
} else {
|
||||
|
||||
bindMatrixNode = uniform( skinnedMesh.bindMatrix, 'mat4' );
|
||||
bindMatrixInverseNode = uniform( skinnedMesh.bindMatrixInverse, 'mat4' );
|
||||
boneMatricesNode = buffer( skinnedMesh.skeleton.boneMatrices, 'mat4', skinnedMesh.skeleton.bones.length );
|
||||
|
||||
}
|
||||
|
||||
this.bindMatrixNode = bindMatrixNode;
|
||||
this.bindMatrixInverseNode = bindMatrixInverseNode;
|
||||
this.boneMatricesNode = boneMatricesNode;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const { skinIndexNode, skinWeightNode, bindMatrixNode, bindMatrixInverseNode, boneMatricesNode } = this;
|
||||
|
||||
const boneMatX = boneMatricesNode.element( skinIndexNode.x );
|
||||
const boneMatY = boneMatricesNode.element( skinIndexNode.y );
|
||||
const boneMatZ = boneMatricesNode.element( skinIndexNode.z );
|
||||
const boneMatW = boneMatricesNode.element( skinIndexNode.w );
|
||||
|
||||
// POSITION
|
||||
|
||||
const skinVertex = bindMatrixNode.mul( positionLocal );
|
||||
|
||||
const skinned = add(
|
||||
boneMatX.mul( skinWeightNode.x ).mul( skinVertex ),
|
||||
boneMatY.mul( skinWeightNode.y ).mul( skinVertex ),
|
||||
boneMatZ.mul( skinWeightNode.z ).mul( skinVertex ),
|
||||
boneMatW.mul( skinWeightNode.w ).mul( skinVertex )
|
||||
);
|
||||
|
||||
const skinPosition = bindMatrixInverseNode.mul( skinned ).xyz;
|
||||
|
||||
// NORMAL
|
||||
|
||||
let skinMatrix = add(
|
||||
skinWeightNode.x.mul( boneMatX ),
|
||||
skinWeightNode.y.mul( boneMatY ),
|
||||
skinWeightNode.z.mul( boneMatZ ),
|
||||
skinWeightNode.w.mul( boneMatW )
|
||||
);
|
||||
|
||||
skinMatrix = bindMatrixInverseNode.mul( skinMatrix ).mul( bindMatrixNode );
|
||||
|
||||
const skinNormal = skinMatrix.transformDirection( normalLocal ).xyz;
|
||||
|
||||
// ASSIGNS
|
||||
|
||||
positionLocal.assign( skinPosition );
|
||||
normalLocal.assign( skinNormal );
|
||||
|
||||
if ( builder.hasGeometryAttribute( 'tangent' ) ) {
|
||||
|
||||
tangentLocal.assign( skinNormal );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
if ( output !== 'void' ) {
|
||||
|
||||
return positionLocal.build( builder, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update( frame ) {
|
||||
|
||||
const object = this.useReference ? frame.object : this.skinnedMesh;
|
||||
|
||||
object.skeleton.update();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default SkinningNode;
|
||||
|
||||
export const skinning = ( skinnedMesh ) => nodeObject( new SkinningNode( skinnedMesh ) );
|
||||
export const skinningReference = ( skinnedMesh ) => nodeObject( new SkinningNode( skinnedMesh, true ) );
|
||||
|
||||
addNodeClass( 'SkinningNode', SkinningNode );
|
81
dist/electron/static/sdk/three/jsm/nodes/accessors/StorageBufferNode.js
vendored
Normal file
81
dist/electron/static/sdk/three/jsm/nodes/accessors/StorageBufferNode.js
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
import BufferNode from './BufferNode.js';
|
||||
import { bufferAttribute } from './BufferAttributeNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
import { varying } from '../core/VaryingNode.js';
|
||||
import { storageElement } from '../utils/StorageArrayElementNode.js';
|
||||
|
||||
class StorageBufferNode extends BufferNode {
|
||||
|
||||
constructor( value, bufferType, bufferCount = 0 ) {
|
||||
|
||||
super( value, bufferType, bufferCount );
|
||||
|
||||
this.isStorageBufferNode = true;
|
||||
|
||||
this.bufferObject = false;
|
||||
|
||||
this._attribute = null;
|
||||
this._varying = null;
|
||||
|
||||
if ( value.isStorageBufferAttribute !== true && value.isStorageInstancedBufferAttribute !== true ) {
|
||||
|
||||
// TOOD: Improve it, possibly adding a new property to the BufferAttribute to identify it as a storage buffer read-only attribute in Renderer
|
||||
|
||||
if ( value.isInstancedBufferAttribute ) value.isStorageInstancedBufferAttribute = true;
|
||||
else value.isStorageBufferAttribute = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getInputType( /*builder*/ ) {
|
||||
|
||||
return 'storageBuffer';
|
||||
|
||||
}
|
||||
|
||||
element( indexNode ) {
|
||||
|
||||
return storageElement( this, indexNode );
|
||||
|
||||
}
|
||||
|
||||
setBufferObject( value ) {
|
||||
|
||||
this.bufferObject = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
if ( builder.isAvailable( 'storageBuffer' ) ) return super.generate( builder );
|
||||
|
||||
const nodeType = this.getNodeType( builder );
|
||||
|
||||
if ( this._attribute === null ) {
|
||||
|
||||
this._attribute = bufferAttribute( this.value );
|
||||
this._varying = varying( this._attribute );
|
||||
|
||||
}
|
||||
|
||||
|
||||
const output = this._varying.build( builder, nodeType );
|
||||
|
||||
builder.registerTransform( output, this._attribute );
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default StorageBufferNode;
|
||||
|
||||
export const storage = ( value, type, count ) => nodeObject( new StorageBufferNode( value, type, count ) );
|
||||
export const storageObject = ( value, type, count ) => nodeObject( new StorageBufferNode( value, type, count ).setBufferObject( true ) );
|
||||
|
||||
addNodeClass( 'StorageBufferNode', StorageBufferNode );
|
109
dist/electron/static/sdk/three/jsm/nodes/accessors/TangentNode.js
vendored
Normal file
109
dist/electron/static/sdk/three/jsm/nodes/accessors/TangentNode.js
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { attribute } from '../core/AttributeNode.js';
|
||||
import { temp } from '../core/VarNode.js';
|
||||
import { varying } from '../core/VaryingNode.js';
|
||||
import { normalize } from '../math/MathNode.js';
|
||||
import { cameraViewMatrix } from './CameraNode.js';
|
||||
import { modelViewMatrix } from './ModelNode.js';
|
||||
import { nodeImmutable, vec4 } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class TangentNode extends Node {
|
||||
|
||||
constructor( scope = TangentNode.LOCAL ) {
|
||||
|
||||
super();
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
}
|
||||
|
||||
getHash( /*builder*/ ) {
|
||||
|
||||
return `tangent-${this.scope}`;
|
||||
|
||||
}
|
||||
|
||||
getNodeType() {
|
||||
|
||||
const scope = this.scope;
|
||||
|
||||
if ( scope === TangentNode.GEOMETRY ) {
|
||||
|
||||
return 'vec4';
|
||||
|
||||
}
|
||||
|
||||
return 'vec3';
|
||||
|
||||
}
|
||||
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const scope = this.scope;
|
||||
|
||||
let outputNode = null;
|
||||
|
||||
if ( scope === TangentNode.GEOMETRY ) {
|
||||
|
||||
outputNode = attribute( 'tangent', 'vec4' );
|
||||
|
||||
if ( builder.geometry.hasAttribute( 'tangent' ) === false ) {
|
||||
|
||||
builder.geometry.computeTangents();
|
||||
|
||||
}
|
||||
|
||||
} else if ( scope === TangentNode.LOCAL ) {
|
||||
|
||||
outputNode = varying( tangentGeometry.xyz );
|
||||
|
||||
} else if ( scope === TangentNode.VIEW ) {
|
||||
|
||||
const vertexNode = modelViewMatrix.mul( vec4( tangentLocal, 0 ) ).xyz;
|
||||
outputNode = normalize( varying( vertexNode ) );
|
||||
|
||||
} else if ( scope === TangentNode.WORLD ) {
|
||||
|
||||
const vertexNode = tangentView.transformDirection( cameraViewMatrix );
|
||||
outputNode = normalize( varying( vertexNode ) );
|
||||
|
||||
}
|
||||
|
||||
return outputNode.build( builder, this.getNodeType( builder ) );
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.scope = this.scope;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.scope = data.scope;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TangentNode.GEOMETRY = 'geometry';
|
||||
TangentNode.LOCAL = 'local';
|
||||
TangentNode.VIEW = 'view';
|
||||
TangentNode.WORLD = 'world';
|
||||
|
||||
export default TangentNode;
|
||||
|
||||
export const tangentGeometry = nodeImmutable( TangentNode, TangentNode.GEOMETRY );
|
||||
export const tangentLocal = nodeImmutable( TangentNode, TangentNode.LOCAL );
|
||||
export const tangentView = nodeImmutable( TangentNode, TangentNode.VIEW );
|
||||
export const tangentWorld = nodeImmutable( TangentNode, TangentNode.WORLD );
|
||||
export const transformedTangentView = temp( tangentView, 'TransformedTangentView' );
|
||||
export const transformedTangentWorld = normalize( transformedTangentView.transformDirection( cameraViewMatrix ) );
|
||||
|
||||
addNodeClass( 'TangentNode', TangentNode );
|
94
dist/electron/static/sdk/three/jsm/nodes/accessors/TextureBicubicNode.js
vendored
Normal file
94
dist/electron/static/sdk/three/jsm/nodes/accessors/TextureBicubicNode.js
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { add, mul, div } from '../math/OperatorNode.js';
|
||||
import { floor, ceil, fract, pow } from '../math/MathNode.js';
|
||||
import { nodeProxy, addNodeElement, float, vec2, vec4, int } from '../shadernode/ShaderNode.js';
|
||||
|
||||
// Mipped Bicubic Texture Filtering by N8
|
||||
// https://www.shadertoy.com/view/Dl2SDW
|
||||
|
||||
const bC = 1.0 / 6.0;
|
||||
|
||||
const w0 = ( a ) => mul( bC, mul( a, mul( a, a.negate().add( 3.0 ) ).sub( 3.0 ) ).add( 1.0 ) );
|
||||
|
||||
const w1 = ( a ) => mul( bC, mul( a, mul( a, mul( 3.0, a ).sub( 6.0 ) ) ).add( 4.0 ) );
|
||||
|
||||
const w2 = ( a ) => mul( bC, mul( a, mul( a, mul( - 3.0, a ).add( 3.0 ) ).add( 3.0 ) ).add( 1.0 ) );
|
||||
|
||||
const w3 = ( a ) => mul( bC, pow( a, 3 ) );
|
||||
|
||||
const g0 = ( a ) => w0( a ).add( w1( a ) );
|
||||
|
||||
const g1 = ( a ) => w2( a ).add( w3( a ) );
|
||||
|
||||
// h0 and h1 are the two offset functions
|
||||
const h0 = ( a ) => add( - 1.0, w1( a ).div( w0( a ).add( w1( a ) ) ) );
|
||||
|
||||
const h1 = ( a ) => add( 1.0, w3( a ).div( w2( a ).add( w3( a ) ) ) );
|
||||
|
||||
const bicubic = ( textureNode, texelSize, lod ) => {
|
||||
|
||||
const uv = textureNode.uvNode;
|
||||
const uvScaled = mul( uv, texelSize.zw ).add( 0.5 );
|
||||
|
||||
const iuv = floor( uvScaled );
|
||||
const fuv = fract( uvScaled );
|
||||
|
||||
const g0x = g0( fuv.x );
|
||||
const g1x = g1( fuv.x );
|
||||
const h0x = h0( fuv.x );
|
||||
const h1x = h1( fuv.x );
|
||||
const h0y = h0( fuv.y );
|
||||
const h1y = h1( fuv.y );
|
||||
|
||||
const p0 = vec2( iuv.x.add( h0x ), iuv.y.add( h0y ) ).sub( 0.5 ).mul( texelSize.xy );
|
||||
const p1 = vec2( iuv.x.add( h1x ), iuv.y.add( h0y ) ).sub( 0.5 ).mul( texelSize.xy );
|
||||
const p2 = vec2( iuv.x.add( h0x ), iuv.y.add( h1y ) ).sub( 0.5 ).mul( texelSize.xy );
|
||||
const p3 = vec2( iuv.x.add( h1x ), iuv.y.add( h1y ) ).sub( 0.5 ).mul( texelSize.xy );
|
||||
|
||||
const a = g0( fuv.y ).mul( add( g0x.mul( textureNode.uv( p0 ).level( lod ) ), g1x.mul( textureNode.uv( p1 ).level( lod ) ) ) );
|
||||
const b = g1( fuv.y ).mul( add( g0x.mul( textureNode.uv( p2 ).level( lod ) ), g1x.mul( textureNode.uv( p3 ).level( lod ) ) ) );
|
||||
|
||||
return a.add( b );
|
||||
|
||||
};
|
||||
|
||||
const textureBicubicMethod = ( textureNode, lodNode ) => {
|
||||
|
||||
const fLodSize = vec2( textureNode.size( int( lodNode ) ) );
|
||||
const cLodSize = vec2( textureNode.size( int( lodNode.add( 1.0 ) ) ) );
|
||||
const fLodSizeInv = div( 1.0, fLodSize );
|
||||
const cLodSizeInv = div( 1.0, cLodSize );
|
||||
const fSample = bicubic( textureNode, vec4( fLodSizeInv, fLodSize ), floor( lodNode ) );
|
||||
const cSample = bicubic( textureNode, vec4( cLodSizeInv, cLodSize ), ceil( lodNode ) );
|
||||
|
||||
return fract( lodNode ).mix( fSample, cSample );
|
||||
|
||||
};
|
||||
|
||||
class TextureBicubicNode extends TempNode {
|
||||
|
||||
constructor( textureNode, blurNode = float( 3 ) ) {
|
||||
|
||||
super( 'vec4' );
|
||||
|
||||
this.textureNode = textureNode;
|
||||
this.blurNode = blurNode;
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
return textureBicubicMethod( this.textureNode, this.blurNode );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default TextureBicubicNode;
|
||||
|
||||
export const textureBicubic = nodeProxy( TextureBicubicNode );
|
||||
|
||||
addNodeElement( 'bicubic', textureBicubic );
|
||||
|
||||
addNodeClass( 'TextureBicubicNode', TextureBicubicNode );
|
408
dist/electron/static/sdk/three/jsm/nodes/accessors/TextureNode.js
vendored
Normal file
408
dist/electron/static/sdk/three/jsm/nodes/accessors/TextureNode.js
vendored
Normal file
@ -0,0 +1,408 @@
|
||||
import UniformNode, { uniform } from '../core/UniformNode.js';
|
||||
import { uv } from './UVNode.js';
|
||||
import { textureSize } from './TextureSizeNode.js';
|
||||
import { colorSpaceToLinear } from '../display/ColorSpaceNode.js';
|
||||
import { expression } from '../code/ExpressionNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { maxMipLevel } from '../utils/MaxMipLevelNode.js';
|
||||
import { addNodeElement, nodeProxy, vec3, nodeObject } from '../shadernode/ShaderNode.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
|
||||
class TextureNode extends UniformNode {
|
||||
|
||||
constructor( value, uvNode = null, levelNode = null ) {
|
||||
|
||||
super( value );
|
||||
|
||||
this.isTextureNode = true;
|
||||
|
||||
this.uvNode = uvNode;
|
||||
this.levelNode = levelNode;
|
||||
this.compareNode = null;
|
||||
this.depthNode = null;
|
||||
this.gradNode = null;
|
||||
|
||||
this.sampler = true;
|
||||
this.updateMatrix = false;
|
||||
this.updateType = NodeUpdateType.NONE;
|
||||
|
||||
this.referenceNode = null;
|
||||
|
||||
this._value = value;
|
||||
|
||||
this.setUpdateMatrix( uvNode === null );
|
||||
|
||||
}
|
||||
|
||||
set value( value ) {
|
||||
|
||||
if ( this.referenceNode ) {
|
||||
|
||||
this.referenceNode.value = value;
|
||||
|
||||
} else {
|
||||
|
||||
this._value = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
get value() {
|
||||
|
||||
return this.referenceNode ? this.referenceNode.value : this._value;
|
||||
|
||||
}
|
||||
|
||||
getUniformHash( /*builder*/ ) {
|
||||
|
||||
return this.value.uuid;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( /*builder*/ ) {
|
||||
|
||||
if ( this.value.isDepthTexture === true ) return 'float';
|
||||
|
||||
return 'vec4';
|
||||
|
||||
}
|
||||
|
||||
getInputType( /*builder*/ ) {
|
||||
|
||||
return 'texture';
|
||||
|
||||
}
|
||||
|
||||
getDefaultUV() {
|
||||
|
||||
return uv( this.value.channel );
|
||||
|
||||
}
|
||||
|
||||
updateReference( /*state*/ ) {
|
||||
|
||||
return this.value;
|
||||
|
||||
}
|
||||
|
||||
getTransformedUV( uvNode ) {
|
||||
|
||||
const texture = this.value;
|
||||
|
||||
return uniform( texture.matrix ).mul( vec3( uvNode, 1 ) ).xy;
|
||||
|
||||
}
|
||||
|
||||
setUpdateMatrix( value ) {
|
||||
|
||||
this.updateMatrix = value;
|
||||
this.updateType = value ? NodeUpdateType.FRAME : NodeUpdateType.NONE;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setupUV( builder, uvNode ) {
|
||||
|
||||
const texture = this.value;
|
||||
|
||||
if ( builder.isFlipY() && ( texture.isRenderTargetTexture === true || texture.isFramebufferTexture === true || texture.isDepthTexture === true ) ) {
|
||||
|
||||
uvNode = uvNode.setY( uvNode.y.oneMinus() );
|
||||
|
||||
}
|
||||
|
||||
return uvNode;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const properties = builder.getNodeProperties( this );
|
||||
|
||||
//
|
||||
|
||||
let uvNode = this.uvNode;
|
||||
|
||||
if ( ( uvNode === null || builder.context.forceUVContext === true ) && builder.context.getUV ) {
|
||||
|
||||
uvNode = builder.context.getUV( this );
|
||||
|
||||
}
|
||||
|
||||
if ( ! uvNode ) uvNode = this.getDefaultUV();
|
||||
|
||||
if ( this.updateMatrix === true ) {
|
||||
|
||||
uvNode = this.getTransformedUV( uvNode );
|
||||
|
||||
}
|
||||
|
||||
uvNode = this.setupUV( builder, uvNode );
|
||||
|
||||
//
|
||||
|
||||
let levelNode = this.levelNode;
|
||||
|
||||
if ( levelNode === null && builder.context.getTextureLevel ) {
|
||||
|
||||
levelNode = builder.context.getTextureLevel( this );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
properties.uvNode = uvNode;
|
||||
properties.levelNode = levelNode;
|
||||
properties.compareNode = this.compareNode;
|
||||
properties.gradNode = this.gradNode;
|
||||
properties.depthNode = this.depthNode;
|
||||
|
||||
}
|
||||
|
||||
generateUV( builder, uvNode ) {
|
||||
|
||||
return uvNode.build( builder, this.sampler === true ? 'vec2' : 'ivec2' );
|
||||
|
||||
}
|
||||
|
||||
generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, depthSnippet, compareSnippet, gradSnippet ) {
|
||||
|
||||
const texture = this.value;
|
||||
|
||||
let snippet;
|
||||
|
||||
if ( levelSnippet ) {
|
||||
|
||||
snippet = builder.generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet );
|
||||
|
||||
} else if ( gradSnippet ) {
|
||||
|
||||
snippet = builder.generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet );
|
||||
|
||||
} else if ( compareSnippet ) {
|
||||
|
||||
snippet = builder.generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet );
|
||||
|
||||
} else if ( this.sampler === false ) {
|
||||
|
||||
snippet = builder.generateTextureLoad( texture, textureProperty, uvSnippet, depthSnippet );
|
||||
|
||||
} else {
|
||||
|
||||
snippet = builder.generateTexture( texture, textureProperty, uvSnippet, depthSnippet );
|
||||
|
||||
}
|
||||
|
||||
return snippet;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const properties = builder.getNodeProperties( this );
|
||||
|
||||
const texture = this.value;
|
||||
|
||||
if ( ! texture || texture.isTexture !== true ) {
|
||||
|
||||
throw new Error( 'TextureNode: Need a three.js texture.' );
|
||||
|
||||
}
|
||||
|
||||
const textureProperty = super.generate( builder, 'property' );
|
||||
|
||||
if ( output === 'sampler' ) {
|
||||
|
||||
return textureProperty + '_sampler';
|
||||
|
||||
} else if ( builder.isReference( output ) ) {
|
||||
|
||||
return textureProperty;
|
||||
|
||||
} else {
|
||||
|
||||
const nodeData = builder.getDataFromNode( this );
|
||||
|
||||
let propertyName = nodeData.propertyName;
|
||||
|
||||
if ( propertyName === undefined ) {
|
||||
|
||||
const { uvNode, levelNode, compareNode, depthNode, gradNode } = properties;
|
||||
|
||||
const uvSnippet = this.generateUV( builder, uvNode );
|
||||
const levelSnippet = levelNode ? levelNode.build( builder, 'float' ) : null;
|
||||
const depthSnippet = depthNode ? depthNode.build( builder, 'int' ) : null;
|
||||
const compareSnippet = compareNode ? compareNode.build( builder, 'float' ) : null;
|
||||
const gradSnippet = gradNode ? [ gradNode[ 0 ].build( builder, 'vec2' ), gradNode[ 1 ].build( builder, 'vec2' ) ] : null;
|
||||
|
||||
const nodeVar = builder.getVarFromNode( this );
|
||||
|
||||
propertyName = builder.getPropertyName( nodeVar );
|
||||
|
||||
const snippet = this.generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, depthSnippet, compareSnippet, gradSnippet );
|
||||
|
||||
builder.addLineFlowCode( `${propertyName} = ${snippet}` );
|
||||
|
||||
if ( builder.context.tempWrite !== false ) {
|
||||
|
||||
nodeData.snippet = snippet;
|
||||
nodeData.propertyName = propertyName;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let snippet = propertyName;
|
||||
const nodeType = this.getNodeType( builder );
|
||||
|
||||
if ( builder.needsColorSpaceToLinear( texture ) ) {
|
||||
|
||||
snippet = colorSpaceToLinear( expression( snippet, nodeType ), texture.colorSpace ).setup( builder ).build( builder, nodeType );
|
||||
|
||||
}
|
||||
|
||||
return builder.format( snippet, nodeType, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setSampler( value ) {
|
||||
|
||||
this.sampler = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getSampler() {
|
||||
|
||||
return this.sampler;
|
||||
|
||||
}
|
||||
|
||||
// @TODO: Move to TSL
|
||||
|
||||
uv( uvNode ) {
|
||||
|
||||
const textureNode = this.clone();
|
||||
textureNode.uvNode = uvNode;
|
||||
textureNode.referenceNode = this;
|
||||
|
||||
return nodeObject( textureNode );
|
||||
|
||||
}
|
||||
|
||||
blur( levelNode ) {
|
||||
|
||||
const textureNode = this.clone();
|
||||
textureNode.levelNode = levelNode.mul( maxMipLevel( textureNode ) );
|
||||
textureNode.referenceNode = this;
|
||||
|
||||
return nodeObject( textureNode );
|
||||
|
||||
}
|
||||
|
||||
level( levelNode ) {
|
||||
|
||||
const textureNode = this.clone();
|
||||
textureNode.levelNode = levelNode;
|
||||
textureNode.referenceNode = this;
|
||||
|
||||
return textureNode;
|
||||
|
||||
}
|
||||
|
||||
size( levelNode ) {
|
||||
|
||||
return textureSize( this, levelNode );
|
||||
|
||||
}
|
||||
|
||||
compare( compareNode ) {
|
||||
|
||||
const textureNode = this.clone();
|
||||
textureNode.compareNode = nodeObject( compareNode );
|
||||
textureNode.referenceNode = this;
|
||||
|
||||
return nodeObject( textureNode );
|
||||
|
||||
}
|
||||
|
||||
grad( gradNodeX, gradNodeY ) {
|
||||
|
||||
const textureNode = this.clone();
|
||||
textureNode.gradNode = [ nodeObject( gradNodeX ), nodeObject( gradNodeY ) ];
|
||||
|
||||
textureNode.referenceNode = this;
|
||||
|
||||
return nodeObject( textureNode );
|
||||
|
||||
}
|
||||
|
||||
depth( depthNode ) {
|
||||
|
||||
const textureNode = this.clone();
|
||||
textureNode.depthNode = nodeObject( depthNode );
|
||||
textureNode.referenceNode = this;
|
||||
|
||||
return nodeObject( textureNode );
|
||||
|
||||
}
|
||||
|
||||
// --
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.value = this.value.toJSON( data.meta ).uuid;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.value = data.meta.textures[ data.value ];
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const texture = this.value;
|
||||
|
||||
if ( texture.matrixAutoUpdate === true ) {
|
||||
|
||||
texture.updateMatrix();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
const newNode = new this.constructor( this.value, this.uvNode, this.levelNode );
|
||||
newNode.sampler = this.sampler;
|
||||
|
||||
return newNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default TextureNode;
|
||||
|
||||
export const texture = nodeProxy( TextureNode );
|
||||
export const textureLoad = ( ...params ) => texture( ...params ).setSampler( false );
|
||||
|
||||
//export const textureLevel = ( value, uv, level ) => texture( value, uv ).level( level );
|
||||
|
||||
export const sampler = ( aTexture ) => ( aTexture.isNode === true ? aTexture : texture( aTexture ) ).convert( 'sampler' );
|
||||
|
||||
addNodeElement( 'texture', texture );
|
||||
//addNodeElement( 'textureLevel', textureLevel );
|
||||
|
||||
addNodeClass( 'TextureNode', TextureNode );
|
35
dist/electron/static/sdk/three/jsm/nodes/accessors/TextureSizeNode.js
vendored
Normal file
35
dist/electron/static/sdk/three/jsm/nodes/accessors/TextureSizeNode.js
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
import Node from '../core/Node.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class TextureSizeNode extends Node {
|
||||
|
||||
constructor( textureNode, levelNode = null ) {
|
||||
|
||||
super( 'uvec2' );
|
||||
|
||||
this.isTextureSizeNode = true;
|
||||
|
||||
this.textureNode = textureNode;
|
||||
this.levelNode = levelNode;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const textureProperty = this.textureNode.build( builder, 'property' );
|
||||
const levelNode = this.levelNode.build( builder, 'int' );
|
||||
|
||||
return builder.format( `${ builder.getMethod( 'textureDimensions' ) }( ${ textureProperty }, ${ levelNode } )`, this.getNodeType( builder ), output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default TextureSizeNode;
|
||||
|
||||
export const textureSize = nodeProxy( TextureSizeNode );
|
||||
|
||||
addNodeElement( 'textureSize', textureSize );
|
||||
|
||||
addNodeClass( 'TextureSizeNode', TextureSizeNode );
|
82
dist/electron/static/sdk/three/jsm/nodes/accessors/TextureStoreNode.js
vendored
Normal file
82
dist/electron/static/sdk/three/jsm/nodes/accessors/TextureStoreNode.js
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import TextureNode from './TextureNode.js';
|
||||
import { nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class TextureStoreNode extends TextureNode {
|
||||
|
||||
constructor( value, uvNode, storeNode = null ) {
|
||||
|
||||
super( value, uvNode );
|
||||
|
||||
this.storeNode = storeNode;
|
||||
|
||||
this.isStoreTextureNode = true;
|
||||
|
||||
}
|
||||
|
||||
getInputType( /*builder*/ ) {
|
||||
|
||||
return 'storageTexture';
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
super.setup( builder );
|
||||
|
||||
const properties = builder.getNodeProperties( this );
|
||||
properties.storeNode = this.storeNode;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
let snippet;
|
||||
|
||||
if ( this.storeNode !== null ) {
|
||||
|
||||
snippet = this.generateStore( builder );
|
||||
|
||||
} else {
|
||||
|
||||
snippet = super.generate( builder, output );
|
||||
|
||||
}
|
||||
|
||||
return snippet;
|
||||
|
||||
}
|
||||
|
||||
generateStore( builder ) {
|
||||
|
||||
const properties = builder.getNodeProperties( this );
|
||||
|
||||
const { uvNode, storeNode } = properties;
|
||||
|
||||
const textureProperty = super.generate( builder, 'property' );
|
||||
const uvSnippet = uvNode.build( builder, 'uvec2' );
|
||||
const storeSnippet = storeNode.build( builder, 'vec4' );
|
||||
|
||||
const snippet = builder.generateTextureStore( builder, textureProperty, uvSnippet, storeSnippet );
|
||||
|
||||
builder.addLineFlowCode( snippet );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default TextureStoreNode;
|
||||
|
||||
const textureStoreBase = nodeProxy( TextureStoreNode );
|
||||
|
||||
export const textureStore = ( value, uvNode, storeNode ) => {
|
||||
|
||||
const node = textureStoreBase( value, uvNode, storeNode );
|
||||
|
||||
if ( storeNode !== null ) node.append();
|
||||
|
||||
return node;
|
||||
|
||||
};
|
||||
|
||||
addNodeClass( 'TextureStoreNode', TextureStoreNode );
|
47
dist/electron/static/sdk/three/jsm/nodes/accessors/UVNode.js
vendored
Normal file
47
dist/electron/static/sdk/three/jsm/nodes/accessors/UVNode.js
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import AttributeNode from '../core/AttributeNode.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class UVNode extends AttributeNode {
|
||||
|
||||
constructor( index = 0 ) {
|
||||
|
||||
super( null, 'vec2' );
|
||||
|
||||
this.isUVNode = true;
|
||||
|
||||
this.index = index;
|
||||
|
||||
}
|
||||
|
||||
getAttributeName( /*builder*/ ) {
|
||||
|
||||
const index = this.index;
|
||||
|
||||
return 'uv' + ( index > 0 ? index : '' );
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.index = this.index;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.index = data.index;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default UVNode;
|
||||
|
||||
export const uv = ( ...params ) => nodeObject( new UVNode( ...params ) );
|
||||
|
||||
addNodeClass( 'UVNode', UVNode );
|
140
dist/electron/static/sdk/three/jsm/nodes/accessors/UniformsNode.js
vendored
Normal file
140
dist/electron/static/sdk/three/jsm/nodes/accessors/UniformsNode.js
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { getValueType } from '../core/NodeUtils.js';
|
||||
import ArrayElementNode from '../utils/ArrayElementNode.js';
|
||||
import BufferNode from './BufferNode.js';
|
||||
|
||||
class UniformsElementNode extends ArrayElementNode {
|
||||
|
||||
constructor( arrayBuffer, indexNode ) {
|
||||
|
||||
super( arrayBuffer, indexNode );
|
||||
|
||||
this.isArrayBufferElementNode = true;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.node.getElementType( builder );
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const snippet = super.generate( builder );
|
||||
const type = this.getNodeType();
|
||||
|
||||
return builder.format( snippet, 'vec4', type );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class UniformsNode extends BufferNode {
|
||||
|
||||
constructor( value, elementType = null ) {
|
||||
|
||||
super( null, 'vec4' );
|
||||
|
||||
this.array = value;
|
||||
this.elementType = elementType;
|
||||
|
||||
this._elementType = null;
|
||||
this._elementLength = 0;
|
||||
|
||||
this.updateType = NodeUpdateType.RENDER;
|
||||
|
||||
this.isArrayBufferNode = true;
|
||||
|
||||
}
|
||||
|
||||
getElementType() {
|
||||
|
||||
return this.elementType || this._elementType;
|
||||
|
||||
}
|
||||
|
||||
getElementLength() {
|
||||
|
||||
return this._elementLength;
|
||||
|
||||
}
|
||||
|
||||
update( /*frame*/ ) {
|
||||
|
||||
const { array, value } = this;
|
||||
|
||||
const elementLength = this.getElementLength();
|
||||
const elementType = this.getElementType();
|
||||
|
||||
if ( elementLength === 1 ) {
|
||||
|
||||
for ( let i = 0; i < array.length; i ++ ) {
|
||||
|
||||
const index = i * 4;
|
||||
|
||||
value[ index ] = array[ i ];
|
||||
|
||||
}
|
||||
|
||||
} else if ( elementType === 'color' ) {
|
||||
|
||||
for ( let i = 0; i < array.length; i ++ ) {
|
||||
|
||||
const index = i * 4;
|
||||
const vector = array[ i ];
|
||||
|
||||
value[ index ] = vector.r;
|
||||
value[ index + 1 ] = vector.g;
|
||||
value[ index + 2 ] = vector.b || 0;
|
||||
//value[ index + 3 ] = vector.a || 0;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for ( let i = 0; i < array.length; i ++ ) {
|
||||
|
||||
const index = i * 4;
|
||||
const vector = array[ i ];
|
||||
|
||||
value[ index ] = vector.x;
|
||||
value[ index + 1 ] = vector.y;
|
||||
value[ index + 2 ] = vector.z || 0;
|
||||
value[ index + 3 ] = vector.w || 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const length = this.array.length;
|
||||
|
||||
this._elementType = this.elementType === null ? getValueType( this.array[ 0 ] ) : this.elementType;
|
||||
this._elementLength = builder.getTypeLength( this._elementType );
|
||||
|
||||
this.value = new Float32Array( length * 4 );
|
||||
this.bufferCount = length;
|
||||
|
||||
return super.setup( builder );
|
||||
|
||||
}
|
||||
|
||||
element( indexNode ) {
|
||||
|
||||
return nodeObject( new UniformsElementNode( this, nodeObject( indexNode ) ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default UniformsNode;
|
||||
|
||||
export const uniforms = ( values, nodeType ) => nodeObject( new UniformsNode( values, nodeType ) );
|
||||
|
||||
addNodeClass( 'UniformsNode', UniformsNode );
|
29
dist/electron/static/sdk/three/jsm/nodes/accessors/UserDataNode.js
vendored
Normal file
29
dist/electron/static/sdk/three/jsm/nodes/accessors/UserDataNode.js
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
import ReferenceNode from './ReferenceNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class UserDataNode extends ReferenceNode {
|
||||
|
||||
constructor( property, inputType, userData = null ) {
|
||||
|
||||
super( property, inputType, userData );
|
||||
|
||||
this.userData = userData;
|
||||
|
||||
}
|
||||
|
||||
update( frame ) {
|
||||
|
||||
this.reference = this.userData !== null ? this.userData : frame.object.userData;
|
||||
|
||||
super.update( frame );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default UserDataNode;
|
||||
|
||||
export const userData = ( name, inputType, userData ) => nodeObject( new UserDataNode( name, inputType, userData ) );
|
||||
|
||||
addNodeClass( 'UserDataNode', UserDataNode );
|
70
dist/electron/static/sdk/three/jsm/nodes/accessors/VertexColorNode.js
vendored
Normal file
70
dist/electron/static/sdk/three/jsm/nodes/accessors/VertexColorNode.js
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import AttributeNode from '../core/AttributeNode.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
import { Vector4 } from 'three';
|
||||
|
||||
class VertexColorNode extends AttributeNode {
|
||||
|
||||
constructor( index = 0 ) {
|
||||
|
||||
super( null, 'vec4' );
|
||||
|
||||
this.isVertexColorNode = true;
|
||||
|
||||
this.index = index;
|
||||
|
||||
}
|
||||
|
||||
getAttributeName( /*builder*/ ) {
|
||||
|
||||
const index = this.index;
|
||||
|
||||
return 'color' + ( index > 0 ? index : '' );
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const attributeName = this.getAttributeName( builder );
|
||||
const geometryAttribute = builder.hasGeometryAttribute( attributeName );
|
||||
|
||||
let result;
|
||||
|
||||
if ( geometryAttribute === true ) {
|
||||
|
||||
result = super.generate( builder );
|
||||
|
||||
} else {
|
||||
|
||||
// Vertex color fallback should be white
|
||||
result = builder.generateConst( this.nodeType, new Vector4( 1, 1, 1, 1 ) );
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.index = this.index;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.index = data.index;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default VertexColorNode;
|
||||
|
||||
export const vertexColor = ( ...params ) => nodeObject( new VertexColorNode( ...params ) );
|
||||
|
||||
addNodeClass( 'VertexColorNode', VertexColorNode );
|
84
dist/electron/static/sdk/three/jsm/nodes/code/CodeNode.js
vendored
Normal file
84
dist/electron/static/sdk/three/jsm/nodes/code/CodeNode.js
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class CodeNode extends Node {
|
||||
|
||||
constructor( code = '', includes = [], language = '' ) {
|
||||
|
||||
super( 'code' );
|
||||
|
||||
this.isCodeNode = true;
|
||||
|
||||
this.code = code;
|
||||
this.language = language;
|
||||
|
||||
this.includes = includes;
|
||||
|
||||
}
|
||||
|
||||
isGlobal() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
setIncludes( includes ) {
|
||||
|
||||
this.includes = includes;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getIncludes( /*builder*/ ) {
|
||||
|
||||
return this.includes;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const includes = this.getIncludes( builder );
|
||||
|
||||
for ( const include of includes ) {
|
||||
|
||||
include.build( builder );
|
||||
|
||||
}
|
||||
|
||||
const nodeCode = builder.getCodeFromNode( this, this.getNodeType( builder ) );
|
||||
nodeCode.code = this.code;
|
||||
|
||||
return nodeCode.code;
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.code = this.code;
|
||||
data.language = this.language;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.code = data.code;
|
||||
this.language = data.language;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CodeNode;
|
||||
|
||||
export const code = nodeProxy( CodeNode );
|
||||
|
||||
export const js = ( src, includes ) => code( src, includes, 'js' );
|
||||
export const wgsl = ( src, includes ) => code( src, includes, 'wgsl' );
|
||||
export const glsl = ( src, includes ) => code( src, includes, 'glsl' );
|
||||
|
||||
addNodeClass( 'CodeNode', CodeNode );
|
37
dist/electron/static/sdk/three/jsm/nodes/code/ExpressionNode.js
vendored
Normal file
37
dist/electron/static/sdk/three/jsm/nodes/code/ExpressionNode.js
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class ExpressionNode extends Node {
|
||||
|
||||
constructor( snippet = '', nodeType = 'void' ) {
|
||||
|
||||
super( nodeType );
|
||||
|
||||
this.snippet = snippet;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const type = this.getNodeType( builder );
|
||||
const snippet = this.snippet;
|
||||
|
||||
if ( type === 'void' ) {
|
||||
|
||||
builder.addLineFlowCode( snippet );
|
||||
|
||||
} else {
|
||||
|
||||
return builder.format( `( ${ snippet } )`, type, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ExpressionNode;
|
||||
|
||||
export const expression = nodeProxy( ExpressionNode );
|
||||
|
||||
addNodeClass( 'ExpressionNode', ExpressionNode );
|
96
dist/electron/static/sdk/three/jsm/nodes/code/FunctionCallNode.js
vendored
Normal file
96
dist/electron/static/sdk/three/jsm/nodes/code/FunctionCallNode.js
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, nodeArray, nodeObject, nodeObjects } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class FunctionCallNode extends TempNode {
|
||||
|
||||
constructor( functionNode = null, parameters = {} ) {
|
||||
|
||||
super();
|
||||
|
||||
this.functionNode = functionNode;
|
||||
this.parameters = parameters;
|
||||
|
||||
}
|
||||
|
||||
setParameters( parameters ) {
|
||||
|
||||
this.parameters = parameters;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getParameters() {
|
||||
|
||||
return this.parameters;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.functionNode.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const params = [];
|
||||
|
||||
const functionNode = this.functionNode;
|
||||
|
||||
const inputs = functionNode.getInputs( builder );
|
||||
const parameters = this.parameters;
|
||||
|
||||
if ( Array.isArray( parameters ) ) {
|
||||
|
||||
for ( let i = 0; i < parameters.length; i ++ ) {
|
||||
|
||||
const inputNode = inputs[ i ];
|
||||
const node = parameters[ i ];
|
||||
|
||||
params.push( node.build( builder, inputNode.type ) );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for ( const inputNode of inputs ) {
|
||||
|
||||
const node = parameters[ inputNode.name ];
|
||||
|
||||
if ( node !== undefined ) {
|
||||
|
||||
params.push( node.build( builder, inputNode.type ) );
|
||||
|
||||
} else {
|
||||
|
||||
throw new Error( `FunctionCallNode: Input '${inputNode.name}' not found in FunctionNode.` );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const functionName = functionNode.build( builder, 'property' );
|
||||
|
||||
return `${functionName}( ${params.join( ', ' )} )`;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default FunctionCallNode;
|
||||
|
||||
export const call = ( func, ...params ) => {
|
||||
|
||||
params = params.length > 1 || ( params[ 0 ] && params[ 0 ].isNode === true ) ? nodeArray( params ) : nodeObjects( params[ 0 ] );
|
||||
|
||||
return nodeObject( new FunctionCallNode( nodeObject( func ), params ) );
|
||||
|
||||
};
|
||||
|
||||
addNodeElement( 'call', call );
|
||||
|
||||
addNodeClass( 'FunctionCallNode', FunctionCallNode );
|
130
dist/electron/static/sdk/three/jsm/nodes/code/FunctionNode.js
vendored
Normal file
130
dist/electron/static/sdk/three/jsm/nodes/code/FunctionNode.js
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
import CodeNode from './CodeNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class FunctionNode extends CodeNode {
|
||||
|
||||
constructor( code = '', includes = [], language = '' ) {
|
||||
|
||||
super( code, includes, language );
|
||||
|
||||
this.keywords = {};
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.getNodeFunction( builder ).type;
|
||||
|
||||
}
|
||||
|
||||
getInputs( builder ) {
|
||||
|
||||
return this.getNodeFunction( builder ).inputs;
|
||||
|
||||
}
|
||||
|
||||
getNodeFunction( builder ) {
|
||||
|
||||
const nodeData = builder.getDataFromNode( this );
|
||||
|
||||
let nodeFunction = nodeData.nodeFunction;
|
||||
|
||||
if ( nodeFunction === undefined ) {
|
||||
|
||||
nodeFunction = builder.parser.parseFunction( this.code );
|
||||
|
||||
nodeData.nodeFunction = nodeFunction;
|
||||
|
||||
}
|
||||
|
||||
return nodeFunction;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
super.generate( builder );
|
||||
|
||||
const nodeFunction = this.getNodeFunction( builder );
|
||||
|
||||
const name = nodeFunction.name;
|
||||
const type = nodeFunction.type;
|
||||
|
||||
const nodeCode = builder.getCodeFromNode( this, type );
|
||||
|
||||
if ( name !== '' ) {
|
||||
|
||||
// use a custom property name
|
||||
|
||||
nodeCode.name = name;
|
||||
|
||||
}
|
||||
|
||||
const propertyName = builder.getPropertyName( nodeCode );
|
||||
|
||||
let code = this.getNodeFunction( builder ).getCode( propertyName );
|
||||
|
||||
const keywords = this.keywords;
|
||||
const keywordsProperties = Object.keys( keywords );
|
||||
|
||||
if ( keywordsProperties.length > 0 ) {
|
||||
|
||||
for ( const property of keywordsProperties ) {
|
||||
|
||||
const propertyRegExp = new RegExp( `\\b${property}\\b`, 'g' );
|
||||
const nodeProperty = keywords[ property ].build( builder, 'property' );
|
||||
|
||||
code = code.replace( propertyRegExp, nodeProperty );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nodeCode.code = code + '\n';
|
||||
|
||||
if ( output === 'property' ) {
|
||||
|
||||
return propertyName;
|
||||
|
||||
} else {
|
||||
|
||||
return builder.format( `${ propertyName }()`, type, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default FunctionNode;
|
||||
|
||||
const nativeFn = ( code, includes = [], language = '' ) => {
|
||||
|
||||
for ( let i = 0; i < includes.length; i ++ ) {
|
||||
|
||||
const include = includes[ i ];
|
||||
|
||||
// TSL Function: glslFn, wgslFn
|
||||
|
||||
if ( typeof include === 'function' ) {
|
||||
|
||||
includes[ i ] = include.functionNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const functionNode = nodeObject( new FunctionNode( code, includes, language ) );
|
||||
|
||||
const fn = ( ...params ) => functionNode.call( ...params );
|
||||
fn.functionNode = functionNode;
|
||||
|
||||
return fn;
|
||||
|
||||
};
|
||||
|
||||
export const glslFn = ( code, includes ) => nativeFn( code, includes, 'glsl' );
|
||||
export const wgslFn = ( code, includes ) => nativeFn( code, includes, 'wgsl' );
|
||||
|
||||
addNodeClass( 'FunctionNode', FunctionNode );
|
488
dist/electron/static/sdk/three/jsm/nodes/code/ScriptableNode.js
vendored
Normal file
488
dist/electron/static/sdk/three/jsm/nodes/code/ScriptableNode.js
vendored
Normal file
@ -0,0 +1,488 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { scriptableValue } from './ScriptableValueNode.js';
|
||||
import { addNodeElement, nodeProxy, float } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class Resources extends Map {
|
||||
|
||||
get( key, callback = null, ...params ) {
|
||||
|
||||
if ( this.has( key ) ) return super.get( key );
|
||||
|
||||
if ( callback !== null ) {
|
||||
|
||||
const value = callback( ...params );
|
||||
this.set( key, value );
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Parameters {
|
||||
|
||||
constructor( scriptableNode ) {
|
||||
|
||||
this.scriptableNode = scriptableNode;
|
||||
|
||||
}
|
||||
|
||||
get parameters() {
|
||||
|
||||
return this.scriptableNode.parameters;
|
||||
|
||||
}
|
||||
|
||||
get layout() {
|
||||
|
||||
return this.scriptableNode.getLayout();
|
||||
|
||||
}
|
||||
|
||||
getInputLayout( id ) {
|
||||
|
||||
return this.scriptableNode.getInputLayout( id );
|
||||
|
||||
}
|
||||
|
||||
get( name ) {
|
||||
|
||||
const param = this.parameters[ name ];
|
||||
const value = param ? param.getValue() : null;
|
||||
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const global = new Resources();
|
||||
|
||||
class ScriptableNode extends Node {
|
||||
|
||||
constructor( codeNode = null, parameters = {} ) {
|
||||
|
||||
super();
|
||||
|
||||
this.codeNode = codeNode;
|
||||
this.parameters = parameters;
|
||||
|
||||
this._local = new Resources();
|
||||
this._output = scriptableValue();
|
||||
this._outputs = {};
|
||||
this._source = this.source;
|
||||
this._method = null;
|
||||
this._object = null;
|
||||
this._value = null;
|
||||
this._needsOutputUpdate = true;
|
||||
|
||||
this.onRefresh = this.onRefresh.bind( this );
|
||||
|
||||
this.isScriptableNode = true;
|
||||
|
||||
}
|
||||
|
||||
get source() {
|
||||
|
||||
return this.codeNode ? this.codeNode.code : '';
|
||||
|
||||
}
|
||||
|
||||
setLocal( name, value ) {
|
||||
|
||||
return this._local.set( name, value );
|
||||
|
||||
}
|
||||
|
||||
getLocal( name ) {
|
||||
|
||||
return this._local.get( name );
|
||||
|
||||
}
|
||||
|
||||
onRefresh() {
|
||||
|
||||
this._refresh();
|
||||
|
||||
}
|
||||
|
||||
getInputLayout( id ) {
|
||||
|
||||
for ( const element of this.getLayout() ) {
|
||||
|
||||
if ( element.inputType && ( element.id === id || element.name === id ) ) {
|
||||
|
||||
return element;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getOutputLayout( id ) {
|
||||
|
||||
for ( const element of this.getLayout() ) {
|
||||
|
||||
if ( element.outputType && ( element.id === id || element.name === id ) ) {
|
||||
|
||||
return element;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setOutput( name, value ) {
|
||||
|
||||
const outputs = this._outputs;
|
||||
|
||||
if ( outputs[ name ] === undefined ) {
|
||||
|
||||
outputs[ name ] = scriptableValue( value );
|
||||
|
||||
} else {
|
||||
|
||||
outputs[ name ].value = value;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getOutput( name ) {
|
||||
|
||||
return this._outputs[ name ];
|
||||
|
||||
}
|
||||
|
||||
getParameter( name ) {
|
||||
|
||||
return this.parameters[ name ];
|
||||
|
||||
}
|
||||
|
||||
setParameter( name, value ) {
|
||||
|
||||
const parameters = this.parameters;
|
||||
|
||||
if ( value && value.isScriptableNode ) {
|
||||
|
||||
this.deleteParameter( name );
|
||||
|
||||
parameters[ name ] = value;
|
||||
parameters[ name ].getDefaultOutput().events.addEventListener( 'refresh', this.onRefresh );
|
||||
|
||||
} else if ( value && value.isScriptableValueNode ) {
|
||||
|
||||
this.deleteParameter( name );
|
||||
|
||||
parameters[ name ] = value;
|
||||
parameters[ name ].events.addEventListener( 'refresh', this.onRefresh );
|
||||
|
||||
} else if ( parameters[ name ] === undefined ) {
|
||||
|
||||
parameters[ name ] = scriptableValue( value );
|
||||
parameters[ name ].events.addEventListener( 'refresh', this.onRefresh );
|
||||
|
||||
} else {
|
||||
|
||||
parameters[ name ].value = value;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
|
||||
return this.getDefaultOutput().getValue();
|
||||
|
||||
}
|
||||
|
||||
deleteParameter( name ) {
|
||||
|
||||
let valueNode = this.parameters[ name ];
|
||||
|
||||
if ( valueNode ) {
|
||||
|
||||
if ( valueNode.isScriptableNode ) valueNode = valueNode.getDefaultOutput();
|
||||
|
||||
valueNode.events.removeEventListener( 'refresh', this.onRefresh );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
clearParameters() {
|
||||
|
||||
for ( const name of Object.keys( this.parameters ) ) {
|
||||
|
||||
this.deleteParameter( name );
|
||||
|
||||
}
|
||||
|
||||
this.needsUpdate = true;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
call( name, ...params ) {
|
||||
|
||||
const object = this.getObject();
|
||||
const method = object[ name ];
|
||||
|
||||
if ( typeof method === 'function' ) {
|
||||
|
||||
return method( ...params );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async callAsync( name, ...params ) {
|
||||
|
||||
const object = this.getObject();
|
||||
const method = object[ name ];
|
||||
|
||||
if ( typeof method === 'function' ) {
|
||||
|
||||
return method.constructor.name === 'AsyncFunction' ? await method( ...params ) : method( ...params );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.getDefaultOutputNode().getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
refresh( output = null ) {
|
||||
|
||||
if ( output !== null ) {
|
||||
|
||||
this.getOutput( output ).refresh();
|
||||
|
||||
} else {
|
||||
|
||||
this._refresh();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getObject() {
|
||||
|
||||
if ( this.needsUpdate ) this.dispose();
|
||||
if ( this._object !== null ) return this._object;
|
||||
|
||||
//
|
||||
|
||||
const refresh = () => this.refresh();
|
||||
const setOutput = ( id, value ) => this.setOutput( id, value );
|
||||
|
||||
const parameters = new Parameters( this );
|
||||
|
||||
const THREE = global.get( 'THREE' );
|
||||
const TSL = global.get( 'TSL' );
|
||||
|
||||
const method = this.getMethod( this.codeNode );
|
||||
const params = [ parameters, this._local, global, refresh, setOutput, THREE, TSL ];
|
||||
|
||||
this._object = method( ...params );
|
||||
|
||||
const layout = this._object.layout;
|
||||
|
||||
if ( layout ) {
|
||||
|
||||
if ( layout.cache === false ) {
|
||||
|
||||
this._local.clear();
|
||||
|
||||
}
|
||||
|
||||
// default output
|
||||
this._output.outputType = layout.outputType || null;
|
||||
|
||||
if ( Array.isArray( layout.elements ) ) {
|
||||
|
||||
for ( const element of layout.elements ) {
|
||||
|
||||
const id = element.id || element.name;
|
||||
|
||||
if ( element.inputType ) {
|
||||
|
||||
if ( this.getParameter( id ) === undefined ) this.setParameter( id, null );
|
||||
|
||||
this.getParameter( id ).inputType = element.inputType;
|
||||
|
||||
}
|
||||
|
||||
if ( element.outputType ) {
|
||||
|
||||
if ( this.getOutput( id ) === undefined ) this.setOutput( id, null );
|
||||
|
||||
this.getOutput( id ).outputType = element.outputType;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this._object;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
for ( const name in this.parameters ) {
|
||||
|
||||
let valueNode = this.parameters[ name ];
|
||||
|
||||
if ( valueNode.isScriptableNode ) valueNode = valueNode.getDefaultOutput();
|
||||
|
||||
valueNode.events.addEventListener( 'refresh', this.onRefresh );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getLayout() {
|
||||
|
||||
return this.getObject().layout;
|
||||
|
||||
}
|
||||
|
||||
getDefaultOutputNode() {
|
||||
|
||||
const output = this.getDefaultOutput().value;
|
||||
|
||||
if ( output && output.isNode ) {
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
return float();
|
||||
|
||||
}
|
||||
|
||||
getDefaultOutput() {
|
||||
|
||||
return this._exec()._output;
|
||||
|
||||
}
|
||||
|
||||
getMethod() {
|
||||
|
||||
if ( this.needsUpdate ) this.dispose();
|
||||
if ( this._method !== null ) return this._method;
|
||||
|
||||
//
|
||||
|
||||
const parametersProps = [ 'parameters', 'local', 'global', 'refresh', 'setOutput', 'THREE', 'TSL' ];
|
||||
const interfaceProps = [ 'layout', 'init', 'main', 'dispose' ];
|
||||
|
||||
const properties = interfaceProps.join( ', ' );
|
||||
const declarations = 'var ' + properties + '; var output = {};\n';
|
||||
const returns = '\nreturn { ...output, ' + properties + ' };';
|
||||
|
||||
const code = declarations + this.codeNode.code + returns;
|
||||
|
||||
//
|
||||
|
||||
this._method = new Function( ...parametersProps, code );
|
||||
|
||||
return this._method;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
if ( this._method === null ) return;
|
||||
|
||||
if ( this._object && typeof this._object.dispose === 'function' ) {
|
||||
|
||||
this._object.dispose();
|
||||
|
||||
}
|
||||
|
||||
this._method = null;
|
||||
this._object = null;
|
||||
this._source = null;
|
||||
this._value = null;
|
||||
this._needsOutputUpdate = true;
|
||||
this._output.value = null;
|
||||
this._outputs = {};
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
return this.getDefaultOutputNode();
|
||||
|
||||
}
|
||||
|
||||
set needsUpdate( value ) {
|
||||
|
||||
if ( value === true ) this.dispose();
|
||||
|
||||
}
|
||||
|
||||
get needsUpdate() {
|
||||
|
||||
return this.source !== this._source;
|
||||
|
||||
}
|
||||
|
||||
_exec() {
|
||||
|
||||
if ( this.codeNode === null ) return this;
|
||||
|
||||
if ( this._needsOutputUpdate === true ) {
|
||||
|
||||
this._value = this.call( 'main' );
|
||||
|
||||
this._needsOutputUpdate = false;
|
||||
|
||||
}
|
||||
|
||||
this._output.value = this._value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
_refresh() {
|
||||
|
||||
this.needsUpdate = true;
|
||||
|
||||
this._exec();
|
||||
|
||||
this._output.refresh();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ScriptableNode;
|
||||
|
||||
export const scriptable = nodeProxy( ScriptableNode );
|
||||
|
||||
addNodeElement( 'scriptable', scriptable );
|
||||
|
||||
addNodeClass( 'ScriptableNode', ScriptableNode );
|
167
dist/electron/static/sdk/three/jsm/nodes/code/ScriptableValueNode.js
vendored
Normal file
167
dist/electron/static/sdk/three/jsm/nodes/code/ScriptableValueNode.js
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { arrayBufferToBase64, base64ToArrayBuffer } from '../core/NodeUtils.js';
|
||||
import { addNodeElement, nodeProxy, float } from '../shadernode/ShaderNode.js';
|
||||
import { EventDispatcher } from 'three';
|
||||
|
||||
class ScriptableValueNode extends Node {
|
||||
|
||||
constructor( value = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this._value = value;
|
||||
this._cache = null;
|
||||
|
||||
this.inputType = null;
|
||||
this.outpuType = null;
|
||||
|
||||
this.events = new EventDispatcher();
|
||||
|
||||
this.isScriptableValueNode = true;
|
||||
|
||||
}
|
||||
|
||||
get isScriptableOutputNode() {
|
||||
|
||||
return this.outputType !== null;
|
||||
|
||||
}
|
||||
|
||||
set value( val ) {
|
||||
|
||||
if ( this._value === val ) return;
|
||||
|
||||
if ( this._cache && this.inputType === 'URL' && this.value.value instanceof ArrayBuffer ) {
|
||||
|
||||
URL.revokeObjectURL( this._cache );
|
||||
|
||||
this._cache = null;
|
||||
|
||||
}
|
||||
|
||||
this._value = val;
|
||||
|
||||
this.events.dispatchEvent( { type: 'change' } );
|
||||
|
||||
this.refresh();
|
||||
|
||||
}
|
||||
|
||||
get value() {
|
||||
|
||||
return this._value;
|
||||
|
||||
}
|
||||
|
||||
refresh() {
|
||||
|
||||
this.events.dispatchEvent( { type: 'refresh' } );
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
|
||||
const value = this.value;
|
||||
|
||||
if ( value && this._cache === null && this.inputType === 'URL' && value.value instanceof ArrayBuffer ) {
|
||||
|
||||
this._cache = URL.createObjectURL( new Blob( [ value.value ] ) );
|
||||
|
||||
} else if ( value && value.value !== null && value.value !== undefined && (
|
||||
( ( this.inputType === 'URL' || this.inputType === 'String' ) && typeof value.value === 'string' ) ||
|
||||
( this.inputType === 'Number' && typeof value.value === 'number' ) ||
|
||||
( this.inputType === 'Vector2' && value.value.isVector2 ) ||
|
||||
( this.inputType === 'Vector3' && value.value.isVector3 ) ||
|
||||
( this.inputType === 'Vector4' && value.value.isVector4 ) ||
|
||||
( this.inputType === 'Color' && value.value.isColor ) ||
|
||||
( this.inputType === 'Matrix3' && value.value.isMatrix3 ) ||
|
||||
( this.inputType === 'Matrix4' && value.value.isMatrix4 )
|
||||
) ) {
|
||||
|
||||
return value.value;
|
||||
|
||||
}
|
||||
|
||||
return this._cache || value;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.value && this.value.isNode ? this.value.getNodeType( builder ) : 'float';
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
return this.value && this.value.isNode ? this.value : float();
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
if ( this.value !== null ) {
|
||||
|
||||
if ( this.inputType === 'ArrayBuffer' ) {
|
||||
|
||||
data.value = arrayBufferToBase64( this.value );
|
||||
|
||||
} else {
|
||||
|
||||
data.value = this.value ? this.value.toJSON( data.meta ).uuid : null;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
data.value = null;
|
||||
|
||||
}
|
||||
|
||||
data.inputType = this.inputType;
|
||||
data.outputType = this.outputType;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
let value = null;
|
||||
|
||||
if ( data.value !== null ) {
|
||||
|
||||
if ( data.inputType === 'ArrayBuffer' ) {
|
||||
|
||||
value = base64ToArrayBuffer( data.value );
|
||||
|
||||
} else if ( data.inputType === 'Texture' ) {
|
||||
|
||||
value = data.meta.textures[ data.value ];
|
||||
|
||||
} else {
|
||||
|
||||
value = data.meta.nodes[ data.value ] || null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.value = value;
|
||||
|
||||
this.inputType = data.inputType;
|
||||
this.outputType = data.outputType;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ScriptableValueNode;
|
||||
|
||||
export const scriptableValue = nodeProxy( ScriptableValueNode );
|
||||
|
||||
addNodeElement( 'scriptableValue', scriptableValue );
|
||||
|
||||
addNodeClass( 'ScriptableValueNode', ScriptableValueNode );
|
128
dist/electron/static/sdk/three/jsm/nodes/core/AssignNode.js
vendored
Normal file
128
dist/electron/static/sdk/three/jsm/nodes/core/AssignNode.js
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
import { vectorComponents } from '../core/constants.js';
|
||||
|
||||
class AssignNode extends TempNode {
|
||||
|
||||
constructor( targetNode, sourceNode ) {
|
||||
|
||||
super();
|
||||
|
||||
this.targetNode = targetNode;
|
||||
this.sourceNode = sourceNode;
|
||||
|
||||
}
|
||||
|
||||
hasDependencies() {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder, output ) {
|
||||
|
||||
return output !== 'void' ? this.targetNode.getNodeType( builder ) : 'void';
|
||||
|
||||
}
|
||||
|
||||
needsSplitAssign( builder ) {
|
||||
|
||||
const { targetNode } = this;
|
||||
|
||||
if ( builder.isAvailable( 'swizzleAssign' ) === false && targetNode.isSplitNode && targetNode.components.length > 1 ) {
|
||||
|
||||
const targetLength = builder.getTypeLength( targetNode.node.getNodeType( builder ) );
|
||||
const assignDiferentVector = vectorComponents.join( '' ).slice( 0, targetLength ) !== targetNode.components;
|
||||
|
||||
return assignDiferentVector;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const { targetNode, sourceNode } = this;
|
||||
|
||||
const needsSplitAssign = this.needsSplitAssign( builder );
|
||||
|
||||
const targetType = targetNode.getNodeType( builder );
|
||||
|
||||
const target = targetNode.context( { assign: true } ).build( builder );
|
||||
const source = sourceNode.build( builder, targetType );
|
||||
|
||||
const sourceType = sourceNode.getNodeType( builder );
|
||||
|
||||
const nodeData = builder.getDataFromNode( this );
|
||||
|
||||
//
|
||||
|
||||
let snippet;
|
||||
|
||||
if ( nodeData.initialized === true ) {
|
||||
|
||||
if ( output !== 'void' ) {
|
||||
|
||||
snippet = target;
|
||||
|
||||
}
|
||||
|
||||
} else if ( needsSplitAssign ) {
|
||||
|
||||
const sourceVar = builder.getVarFromNode( this, null, targetType );
|
||||
const sourceProperty = builder.getPropertyName( sourceVar );
|
||||
|
||||
builder.addLineFlowCode( `${ sourceProperty } = ${ source }` );
|
||||
|
||||
const targetRoot = targetNode.node.context( { assign: true } ).build( builder );
|
||||
|
||||
for ( let i = 0; i < targetNode.components.length; i ++ ) {
|
||||
|
||||
const component = targetNode.components[ i ];
|
||||
|
||||
builder.addLineFlowCode( `${ targetRoot }.${ component } = ${ sourceProperty }[ ${ i } ]` );
|
||||
|
||||
}
|
||||
|
||||
if ( output !== 'void' ) {
|
||||
|
||||
snippet = target;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
snippet = `${ target } = ${ source }`;
|
||||
|
||||
if ( output === 'void' || sourceType === 'void' ) {
|
||||
|
||||
builder.addLineFlowCode( snippet );
|
||||
|
||||
if ( output !== 'void' ) {
|
||||
|
||||
snippet = target;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nodeData.initialized = true;
|
||||
|
||||
return builder.format( snippet, targetType, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AssignNode;
|
||||
|
||||
export const assign = nodeProxy( AssignNode );
|
||||
|
||||
addNodeClass( 'AssignNode', AssignNode );
|
||||
|
||||
addNodeElement( 'assign', assign );
|
108
dist/electron/static/sdk/three/jsm/nodes/core/AttributeNode.js
vendored
Normal file
108
dist/electron/static/sdk/three/jsm/nodes/core/AttributeNode.js
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { varying } from './VaryingNode.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class AttributeNode extends Node {
|
||||
|
||||
constructor( attributeName, nodeType = null ) {
|
||||
|
||||
super( nodeType );
|
||||
|
||||
this._attributeName = attributeName;
|
||||
|
||||
}
|
||||
|
||||
isGlobal() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
getHash( builder ) {
|
||||
|
||||
return this.getAttributeName( builder );
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
let nodeType = super.getNodeType( builder );
|
||||
|
||||
if ( nodeType === null ) {
|
||||
|
||||
const attributeName = this.getAttributeName( builder );
|
||||
|
||||
if ( builder.hasGeometryAttribute( attributeName ) ) {
|
||||
|
||||
const attribute = builder.geometry.getAttribute( attributeName );
|
||||
|
||||
nodeType = builder.getTypeFromAttribute( attribute );
|
||||
|
||||
} else {
|
||||
|
||||
nodeType = 'float';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nodeType;
|
||||
|
||||
}
|
||||
|
||||
setAttributeName( attributeName ) {
|
||||
|
||||
this._attributeName = attributeName;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getAttributeName( /*builder*/ ) {
|
||||
|
||||
return this._attributeName;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const attributeName = this.getAttributeName( builder );
|
||||
const nodeType = this.getNodeType( builder );
|
||||
const geometryAttribute = builder.hasGeometryAttribute( attributeName );
|
||||
|
||||
if ( geometryAttribute === true ) {
|
||||
|
||||
const attribute = builder.geometry.getAttribute( attributeName );
|
||||
const attributeType = builder.getTypeFromAttribute( attribute );
|
||||
|
||||
const nodeAttribute = builder.getAttribute( attributeName, attributeType );
|
||||
|
||||
if ( builder.shaderStage === 'vertex' ) {
|
||||
|
||||
return builder.format( nodeAttribute.name, attributeType, nodeType );
|
||||
|
||||
} else {
|
||||
|
||||
const nodeVarying = varying( this );
|
||||
|
||||
return nodeVarying.build( builder, nodeType );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
console.warn( `AttributeNode: Vertex attribute "${ attributeName }" not found on geometry.` );
|
||||
|
||||
return builder.generateConst( nodeType );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AttributeNode;
|
||||
|
||||
export const attribute = ( name, nodeType ) => nodeObject( new AttributeNode( name, nodeType ) );
|
||||
|
||||
addNodeClass( 'AttributeNode', AttributeNode );
|
45
dist/electron/static/sdk/three/jsm/nodes/core/BypassNode.js
vendored
Normal file
45
dist/electron/static/sdk/three/jsm/nodes/core/BypassNode.js
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class BypassNode extends Node {
|
||||
|
||||
constructor( returnNode, callNode ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isBypassNode = true;
|
||||
|
||||
this.outputNode = returnNode;
|
||||
this.callNode = callNode;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.outputNode.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const snippet = this.callNode.build( builder, 'void' );
|
||||
|
||||
if ( snippet !== '' ) {
|
||||
|
||||
builder.addLineFlowCode( snippet );
|
||||
|
||||
}
|
||||
|
||||
return this.outputNode.build( builder );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BypassNode;
|
||||
|
||||
export const bypass = nodeProxy( BypassNode );
|
||||
|
||||
addNodeElement( 'bypass', bypass );
|
||||
|
||||
addNodeClass( 'BypassNode', BypassNode );
|
49
dist/electron/static/sdk/three/jsm/nodes/core/CacheNode.js
vendored
Normal file
49
dist/electron/static/sdk/three/jsm/nodes/core/CacheNode.js
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import NodeCache from './NodeCache.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class CacheNode extends Node {
|
||||
|
||||
constructor( node, cache = new NodeCache() ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isCacheNode = true;
|
||||
|
||||
this.node = node;
|
||||
this.cache = cache;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.node.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
build( builder, ...params ) {
|
||||
|
||||
const previousCache = builder.getCache();
|
||||
const cache = this.cache || builder.globalCache;
|
||||
|
||||
builder.setCache( cache );
|
||||
|
||||
const data = this.node.build( builder, ...params );
|
||||
|
||||
builder.setCache( previousCache );
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CacheNode;
|
||||
|
||||
export const cache = nodeProxy( CacheNode );
|
||||
export const globalCache = ( node ) => cache( node, null );
|
||||
|
||||
addNodeElement( 'cache', cache );
|
||||
addNodeElement( 'globalCache', globalCache );
|
||||
|
||||
addNodeClass( 'CacheNode', CacheNode );
|
32
dist/electron/static/sdk/three/jsm/nodes/core/ConstNode.js
vendored
Normal file
32
dist/electron/static/sdk/three/jsm/nodes/core/ConstNode.js
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
import InputNode from './InputNode.js';
|
||||
import { addNodeClass } from './Node.js';
|
||||
|
||||
class ConstNode extends InputNode {
|
||||
|
||||
constructor( value, nodeType = null ) {
|
||||
|
||||
super( value, nodeType );
|
||||
|
||||
this.isConstNode = true;
|
||||
|
||||
}
|
||||
|
||||
generateConst( builder ) {
|
||||
|
||||
return builder.generateConst( this.getNodeType( builder ), this.value );
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const type = this.getNodeType( builder );
|
||||
|
||||
return builder.format( this.generateConst( builder ), type, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ConstNode;
|
||||
|
||||
addNodeClass( 'ConstNode', ConstNode );
|
61
dist/electron/static/sdk/three/jsm/nodes/core/ContextNode.js
vendored
Normal file
61
dist/electron/static/sdk/three/jsm/nodes/core/ContextNode.js
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class ContextNode extends Node {
|
||||
|
||||
constructor( node, context = {} ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isContextNode = true;
|
||||
|
||||
this.node = node;
|
||||
this.context = context;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.node.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const previousContext = builder.getContext();
|
||||
|
||||
builder.setContext( { ...builder.context, ...this.context } );
|
||||
|
||||
const node = this.node.build( builder );
|
||||
|
||||
builder.setContext( previousContext );
|
||||
|
||||
return node;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const previousContext = builder.getContext();
|
||||
|
||||
builder.setContext( { ...builder.context, ...this.context } );
|
||||
|
||||
const snippet = this.node.build( builder, output );
|
||||
|
||||
builder.setContext( previousContext );
|
||||
|
||||
return snippet;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ContextNode;
|
||||
|
||||
export const context = nodeProxy( ContextNode );
|
||||
export const label = ( node, name ) => context( node, { label: name } );
|
||||
|
||||
addNodeElement( 'context', context );
|
||||
addNodeElement( 'label', label );
|
||||
|
||||
addNodeClass( 'ContextNode', ContextNode );
|
66
dist/electron/static/sdk/three/jsm/nodes/core/IndexNode.js
vendored
Normal file
66
dist/electron/static/sdk/three/jsm/nodes/core/IndexNode.js
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { varying } from './VaryingNode.js';
|
||||
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class IndexNode extends Node {
|
||||
|
||||
constructor( scope ) {
|
||||
|
||||
super( 'uint' );
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
this.isInstanceIndexNode = true;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const nodeType = this.getNodeType( builder );
|
||||
const scope = this.scope;
|
||||
|
||||
let propertyName;
|
||||
|
||||
if ( scope === IndexNode.VERTEX ) {
|
||||
|
||||
propertyName = builder.getVertexIndex();
|
||||
|
||||
} else if ( scope === IndexNode.INSTANCE ) {
|
||||
|
||||
propertyName = builder.getInstanceIndex();
|
||||
|
||||
} else {
|
||||
|
||||
throw new Error( 'THREE.IndexNode: Unknown scope: ' + scope );
|
||||
|
||||
}
|
||||
|
||||
let output;
|
||||
|
||||
if ( builder.shaderStage === 'vertex' || builder.shaderStage === 'compute' ) {
|
||||
|
||||
output = propertyName;
|
||||
|
||||
} else {
|
||||
|
||||
const nodeVarying = varying( this );
|
||||
|
||||
output = nodeVarying.build( builder, nodeType );
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IndexNode.VERTEX = 'vertex';
|
||||
IndexNode.INSTANCE = 'instance';
|
||||
|
||||
export default IndexNode;
|
||||
|
||||
export const vertexIndex = nodeImmutable( IndexNode, IndexNode.VERTEX );
|
||||
export const instanceIndex = nodeImmutable( IndexNode, IndexNode.INSTANCE );
|
||||
|
||||
addNodeClass( 'IndexNode', IndexNode );
|
83
dist/electron/static/sdk/three/jsm/nodes/core/InputNode.js
vendored
Normal file
83
dist/electron/static/sdk/three/jsm/nodes/core/InputNode.js
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { getValueType, getValueFromType, arrayBufferToBase64 } from './NodeUtils.js';
|
||||
|
||||
class InputNode extends Node {
|
||||
|
||||
constructor( value, nodeType = null ) {
|
||||
|
||||
super( nodeType );
|
||||
|
||||
this.isInputNode = true;
|
||||
|
||||
this.value = value;
|
||||
this.precision = null;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( /*builder*/ ) {
|
||||
|
||||
if ( this.nodeType === null ) {
|
||||
|
||||
return getValueType( this.value );
|
||||
|
||||
}
|
||||
|
||||
return this.nodeType;
|
||||
|
||||
}
|
||||
|
||||
getInputType( builder ) {
|
||||
|
||||
return this.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
setPrecision( precision ) {
|
||||
|
||||
this.precision = precision;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.value = this.value;
|
||||
|
||||
if ( this.value && this.value.toArray ) data.value = this.value.toArray();
|
||||
|
||||
data.valueType = getValueType( this.value );
|
||||
data.nodeType = this.nodeType;
|
||||
|
||||
if ( data.valueType === 'ArrayBuffer' ) data.value = arrayBufferToBase64( data.value );
|
||||
|
||||
data.precision = this.precision;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.nodeType = data.nodeType;
|
||||
this.value = Array.isArray( data.value ) ? getValueFromType( data.valueType, ...data.value ) : data.value;
|
||||
|
||||
this.precision = data.precision || null;
|
||||
|
||||
if ( this.value && this.value.fromArray ) this.value = this.value.fromArray( data.value );
|
||||
|
||||
}
|
||||
|
||||
generate( /*builder, output*/ ) {
|
||||
|
||||
console.warn( 'Abstract function.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default InputNode;
|
||||
|
||||
addNodeClass( 'InputNode', InputNode );
|
17
dist/electron/static/sdk/three/jsm/nodes/core/LightingModel.js
vendored
Normal file
17
dist/electron/static/sdk/three/jsm/nodes/core/LightingModel.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
class LightingModel {
|
||||
|
||||
start( /*input, stack, builder*/ ) { }
|
||||
|
||||
finish( /*input, stack, builder*/ ) { }
|
||||
|
||||
direct( /*input, stack, builder*/ ) { }
|
||||
|
||||
indirectDiffuse( /*input, stack, builder*/ ) { }
|
||||
|
||||
indirectSpecular( /*input, stack, builder*/ ) { }
|
||||
|
||||
ambientOcclusion( /*input, stack, builder*/ ) { }
|
||||
|
||||
}
|
||||
|
||||
export default LightingModel;
|
552
dist/electron/static/sdk/three/jsm/nodes/core/Node.js
vendored
Normal file
552
dist/electron/static/sdk/three/jsm/nodes/core/Node.js
vendored
Normal file
@ -0,0 +1,552 @@
|
||||
import { EventDispatcher } from 'three';
|
||||
import { NodeUpdateType } from './constants.js';
|
||||
import { getNodeChildren, getCacheKey } from './NodeUtils.js';
|
||||
import { MathUtils } from 'three';
|
||||
|
||||
const NodeClasses = new Map();
|
||||
|
||||
let _nodeId = 0;
|
||||
|
||||
class Node extends EventDispatcher {
|
||||
|
||||
constructor( nodeType = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.nodeType = nodeType;
|
||||
|
||||
this.updateType = NodeUpdateType.NONE;
|
||||
this.updateBeforeType = NodeUpdateType.NONE;
|
||||
|
||||
this.uuid = MathUtils.generateUUID();
|
||||
|
||||
this.version = 0;
|
||||
|
||||
this._cacheKey = null;
|
||||
this._cacheKeyVersion = 0;
|
||||
|
||||
this.isNode = true;
|
||||
|
||||
Object.defineProperty( this, 'id', { value: _nodeId ++ } );
|
||||
|
||||
}
|
||||
|
||||
set needsUpdate( value ) {
|
||||
|
||||
if ( value === true ) {
|
||||
|
||||
this.version ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
get type() {
|
||||
|
||||
return this.constructor.type;
|
||||
|
||||
}
|
||||
|
||||
onUpdate( callback, updateType ) {
|
||||
|
||||
this.updateType = updateType;
|
||||
this.update = callback.bind( this.getSelf() );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
onFrameUpdate( callback ) {
|
||||
|
||||
return this.onUpdate( callback, NodeUpdateType.FRAME );
|
||||
|
||||
}
|
||||
|
||||
onRenderUpdate( callback ) {
|
||||
|
||||
return this.onUpdate( callback, NodeUpdateType.RENDER );
|
||||
|
||||
}
|
||||
|
||||
onObjectUpdate( callback ) {
|
||||
|
||||
return this.onUpdate( callback, NodeUpdateType.OBJECT );
|
||||
|
||||
}
|
||||
|
||||
onReference( callback ) {
|
||||
|
||||
this.updateReference = callback.bind( this.getSelf() );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getSelf() {
|
||||
|
||||
// Returns non-node object.
|
||||
|
||||
return this.self || this;
|
||||
|
||||
}
|
||||
|
||||
updateReference( /*state*/ ) {
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
isGlobal( /*builder*/ ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
* getChildren() {
|
||||
|
||||
for ( const { childNode } of getNodeChildren( this ) ) {
|
||||
|
||||
yield childNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.dispatchEvent( { type: 'dispose' } );
|
||||
|
||||
}
|
||||
|
||||
traverse( callback ) {
|
||||
|
||||
callback( this );
|
||||
|
||||
for ( const childNode of this.getChildren() ) {
|
||||
|
||||
childNode.traverse( callback );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getCacheKey( force = false ) {
|
||||
|
||||
force = force || this.version !== this._cacheKeyVersion;
|
||||
|
||||
if ( force === true || this._cacheKey === null ) {
|
||||
|
||||
this._cacheKey = getCacheKey( this, force );
|
||||
this._cacheKeyVersion = this.version;
|
||||
|
||||
}
|
||||
|
||||
return this._cacheKey;
|
||||
|
||||
}
|
||||
|
||||
getHash( /*builder*/ ) {
|
||||
|
||||
return this.uuid;
|
||||
|
||||
}
|
||||
|
||||
getUpdateType() {
|
||||
|
||||
return this.updateType;
|
||||
|
||||
}
|
||||
|
||||
getUpdateBeforeType() {
|
||||
|
||||
return this.updateBeforeType;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
const nodeProperties = builder.getNodeProperties( this );
|
||||
|
||||
if ( nodeProperties.outputNode ) {
|
||||
|
||||
return nodeProperties.outputNode.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
return this.nodeType;
|
||||
|
||||
}
|
||||
|
||||
getShared( builder ) {
|
||||
|
||||
const hash = this.getHash( builder );
|
||||
const nodeFromHash = builder.getNodeFromHash( hash );
|
||||
|
||||
return nodeFromHash || this;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const nodeProperties = builder.getNodeProperties( this );
|
||||
|
||||
for ( const childNode of this.getChildren() ) {
|
||||
|
||||
nodeProperties[ '_node' + childNode.id ] = childNode;
|
||||
|
||||
}
|
||||
|
||||
// return a outputNode if exists
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
construct( builder ) { // @deprecated, r157
|
||||
|
||||
console.warn( 'THREE.Node: construct() is deprecated. Use setup() instead.' );
|
||||
|
||||
return this.setup( builder );
|
||||
|
||||
}
|
||||
|
||||
increaseUsage( builder ) {
|
||||
|
||||
const nodeData = builder.getDataFromNode( this );
|
||||
nodeData.usageCount = nodeData.usageCount === undefined ? 1 : nodeData.usageCount + 1;
|
||||
|
||||
return nodeData.usageCount;
|
||||
|
||||
}
|
||||
|
||||
analyze( builder ) {
|
||||
|
||||
const usageCount = this.increaseUsage( builder );
|
||||
|
||||
if ( usageCount === 1 ) {
|
||||
|
||||
// node flow children
|
||||
|
||||
const nodeProperties = builder.getNodeProperties( this );
|
||||
|
||||
for ( const childNode of Object.values( nodeProperties ) ) {
|
||||
|
||||
if ( childNode && childNode.isNode === true ) {
|
||||
|
||||
childNode.build( builder );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const { outputNode } = builder.getNodeProperties( this );
|
||||
|
||||
if ( outputNode && outputNode.isNode === true ) {
|
||||
|
||||
return outputNode.build( builder, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateBefore( /*frame*/ ) {
|
||||
|
||||
console.warn( 'Abstract function.' );
|
||||
|
||||
}
|
||||
|
||||
update( /*frame*/ ) {
|
||||
|
||||
console.warn( 'Abstract function.' );
|
||||
|
||||
}
|
||||
|
||||
build( builder, output = null ) {
|
||||
|
||||
const refNode = this.getShared( builder );
|
||||
|
||||
if ( this !== refNode ) {
|
||||
|
||||
return refNode.build( builder, output );
|
||||
|
||||
}
|
||||
|
||||
builder.addNode( this );
|
||||
builder.addChain( this );
|
||||
|
||||
/* Build stages expected results:
|
||||
- "setup" -> Node
|
||||
- "analyze" -> null
|
||||
- "generate" -> String
|
||||
*/
|
||||
let result = null;
|
||||
|
||||
const buildStage = builder.getBuildStage();
|
||||
|
||||
if ( buildStage === 'setup' ) {
|
||||
|
||||
this.updateReference( builder );
|
||||
|
||||
const properties = builder.getNodeProperties( this );
|
||||
|
||||
if ( properties.initialized !== true || builder.context.tempRead === false ) {
|
||||
|
||||
const stackNodesBeforeSetup = builder.stack.nodes.length;
|
||||
|
||||
properties.initialized = true;
|
||||
properties.outputNode = this.setup( builder );
|
||||
|
||||
if ( properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeSetup ) {
|
||||
|
||||
properties.outputNode = builder.stack;
|
||||
|
||||
}
|
||||
|
||||
for ( const childNode of Object.values( properties ) ) {
|
||||
|
||||
if ( childNode && childNode.isNode === true ) {
|
||||
|
||||
childNode.build( builder );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( buildStage === 'analyze' ) {
|
||||
|
||||
this.analyze( builder );
|
||||
|
||||
} else if ( buildStage === 'generate' ) {
|
||||
|
||||
const isGenerateOnce = this.generate.length === 1;
|
||||
|
||||
if ( isGenerateOnce ) {
|
||||
|
||||
const type = this.getNodeType( builder );
|
||||
const nodeData = builder.getDataFromNode( this );
|
||||
|
||||
result = nodeData.snippet;
|
||||
|
||||
if ( result === undefined /*|| builder.context.tempRead === false*/ ) {
|
||||
|
||||
result = this.generate( builder ) || '';
|
||||
|
||||
nodeData.snippet = result;
|
||||
|
||||
}
|
||||
|
||||
result = builder.format( result, type, output );
|
||||
|
||||
} else {
|
||||
|
||||
result = this.generate( builder, output ) || '';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
builder.removeChain( this );
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
getSerializeChildren() {
|
||||
|
||||
return getNodeChildren( this );
|
||||
|
||||
}
|
||||
|
||||
serialize( json ) {
|
||||
|
||||
const nodeChildren = this.getSerializeChildren();
|
||||
|
||||
const inputNodes = {};
|
||||
|
||||
for ( const { property, index, childNode } of nodeChildren ) {
|
||||
|
||||
if ( index !== undefined ) {
|
||||
|
||||
if ( inputNodes[ property ] === undefined ) {
|
||||
|
||||
inputNodes[ property ] = Number.isInteger( index ) ? [] : {};
|
||||
|
||||
}
|
||||
|
||||
inputNodes[ property ][ index ] = childNode.toJSON( json.meta ).uuid;
|
||||
|
||||
} else {
|
||||
|
||||
inputNodes[ property ] = childNode.toJSON( json.meta ).uuid;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( Object.keys( inputNodes ).length > 0 ) {
|
||||
|
||||
json.inputNodes = inputNodes;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
deserialize( json ) {
|
||||
|
||||
if ( json.inputNodes !== undefined ) {
|
||||
|
||||
const nodes = json.meta.nodes;
|
||||
|
||||
for ( const property in json.inputNodes ) {
|
||||
|
||||
if ( Array.isArray( json.inputNodes[ property ] ) ) {
|
||||
|
||||
const inputArray = [];
|
||||
|
||||
for ( const uuid of json.inputNodes[ property ] ) {
|
||||
|
||||
inputArray.push( nodes[ uuid ] );
|
||||
|
||||
}
|
||||
|
||||
this[ property ] = inputArray;
|
||||
|
||||
} else if ( typeof json.inputNodes[ property ] === 'object' ) {
|
||||
|
||||
const inputObject = {};
|
||||
|
||||
for ( const subProperty in json.inputNodes[ property ] ) {
|
||||
|
||||
const uuid = json.inputNodes[ property ][ subProperty ];
|
||||
|
||||
inputObject[ subProperty ] = nodes[ uuid ];
|
||||
|
||||
}
|
||||
|
||||
this[ property ] = inputObject;
|
||||
|
||||
} else {
|
||||
|
||||
const uuid = json.inputNodes[ property ];
|
||||
|
||||
this[ property ] = nodes[ uuid ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
toJSON( meta ) {
|
||||
|
||||
const { uuid, type } = this;
|
||||
const isRoot = ( meta === undefined || typeof meta === 'string' );
|
||||
|
||||
if ( isRoot ) {
|
||||
|
||||
meta = {
|
||||
textures: {},
|
||||
images: {},
|
||||
nodes: {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// serialize
|
||||
|
||||
let data = meta.nodes[ uuid ];
|
||||
|
||||
if ( data === undefined ) {
|
||||
|
||||
data = {
|
||||
uuid,
|
||||
type,
|
||||
meta,
|
||||
metadata: {
|
||||
version: 4.6,
|
||||
type: 'Node',
|
||||
generator: 'Node.toJSON'
|
||||
}
|
||||
};
|
||||
|
||||
if ( isRoot !== true ) meta.nodes[ data.uuid ] = data;
|
||||
|
||||
this.serialize( data );
|
||||
|
||||
delete data.meta;
|
||||
|
||||
}
|
||||
|
||||
// TODO: Copied from Object3D.toJSON
|
||||
|
||||
function extractFromCache( cache ) {
|
||||
|
||||
const values = [];
|
||||
|
||||
for ( const key in cache ) {
|
||||
|
||||
const data = cache[ key ];
|
||||
delete data.metadata;
|
||||
values.push( data );
|
||||
|
||||
}
|
||||
|
||||
return values;
|
||||
|
||||
}
|
||||
|
||||
if ( isRoot ) {
|
||||
|
||||
const textures = extractFromCache( meta.textures );
|
||||
const images = extractFromCache( meta.images );
|
||||
const nodes = extractFromCache( meta.nodes );
|
||||
|
||||
if ( textures.length > 0 ) data.textures = textures;
|
||||
if ( images.length > 0 ) data.images = images;
|
||||
if ( nodes.length > 0 ) data.nodes = nodes;
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Node;
|
||||
|
||||
export function addNodeClass( type, nodeClass ) {
|
||||
|
||||
if ( typeof nodeClass !== 'function' || ! type ) throw new Error( `Node class ${ type } is not a class` );
|
||||
if ( NodeClasses.has( type ) ) {
|
||||
|
||||
console.warn( `Redefinition of node class ${ type }` );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
NodeClasses.set( type, nodeClass );
|
||||
nodeClass.type = type;
|
||||
|
||||
}
|
||||
|
||||
export function createNodeFromType( type ) {
|
||||
|
||||
const Class = NodeClasses.get( type );
|
||||
|
||||
if ( Class !== undefined ) {
|
||||
|
||||
return new Class();
|
||||
|
||||
}
|
||||
|
||||
}
|
15
dist/electron/static/sdk/three/jsm/nodes/core/NodeAttribute.js
vendored
Normal file
15
dist/electron/static/sdk/three/jsm/nodes/core/NodeAttribute.js
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
class NodeAttribute {
|
||||
|
||||
constructor( name, type, node = null ) {
|
||||
|
||||
this.isNodeAttribute = true;
|
||||
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.node = node;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeAttribute;
|
1251
dist/electron/static/sdk/three/jsm/nodes/core/NodeBuilder.js
vendored
Normal file
1251
dist/electron/static/sdk/three/jsm/nodes/core/NodeBuilder.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
26
dist/electron/static/sdk/three/jsm/nodes/core/NodeCache.js
vendored
Normal file
26
dist/electron/static/sdk/three/jsm/nodes/core/NodeCache.js
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
let id = 0;
|
||||
|
||||
class NodeCache {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.id = id ++;
|
||||
this.nodesData = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
getNodeData( node ) {
|
||||
|
||||
return this.nodesData.get( node );
|
||||
|
||||
}
|
||||
|
||||
setNodeData( node, data ) {
|
||||
|
||||
this.nodesData.set( node, data );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeCache;
|
15
dist/electron/static/sdk/three/jsm/nodes/core/NodeCode.js
vendored
Normal file
15
dist/electron/static/sdk/three/jsm/nodes/core/NodeCode.js
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
class NodeCode {
|
||||
|
||||
constructor( name, type, code = '' ) {
|
||||
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.code = code;
|
||||
|
||||
Object.defineProperty( this, 'isNodeCode', { value: true } );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeCode;
|
143
dist/electron/static/sdk/three/jsm/nodes/core/NodeFrame.js
vendored
Normal file
143
dist/electron/static/sdk/three/jsm/nodes/core/NodeFrame.js
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
import { NodeUpdateType } from './constants.js';
|
||||
|
||||
class NodeFrame {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.time = 0;
|
||||
this.deltaTime = 0;
|
||||
|
||||
this.frameId = 0;
|
||||
this.renderId = 0;
|
||||
|
||||
this.startTime = null;
|
||||
|
||||
this.updateMap = new WeakMap();
|
||||
this.updateBeforeMap = new WeakMap();
|
||||
|
||||
this.renderer = null;
|
||||
this.material = null;
|
||||
this.camera = null;
|
||||
this.object = null;
|
||||
this.scene = null;
|
||||
|
||||
}
|
||||
|
||||
_getMaps( referenceMap, nodeRef ) {
|
||||
|
||||
let maps = referenceMap.get( nodeRef );
|
||||
|
||||
if ( maps === undefined ) {
|
||||
|
||||
maps = {
|
||||
renderMap: new WeakMap(),
|
||||
frameMap: new WeakMap()
|
||||
};
|
||||
|
||||
referenceMap.set( nodeRef, maps );
|
||||
|
||||
}
|
||||
|
||||
return maps;
|
||||
|
||||
}
|
||||
|
||||
updateBeforeNode( node ) {
|
||||
|
||||
const updateType = node.getUpdateBeforeType();
|
||||
const reference = node.updateReference( this );
|
||||
|
||||
if ( updateType === NodeUpdateType.FRAME ) {
|
||||
|
||||
const { frameMap } = this._getMaps( this.updateBeforeMap, reference );
|
||||
|
||||
if ( frameMap.get( reference ) !== this.frameId ) {
|
||||
|
||||
if ( node.updateBefore( this ) !== false ) {
|
||||
|
||||
frameMap.set( reference, this.frameId );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( updateType === NodeUpdateType.RENDER ) {
|
||||
|
||||
const { renderMap } = this._getMaps( this.updateBeforeMap, reference );
|
||||
|
||||
if ( renderMap.get( reference ) !== this.renderId ) {
|
||||
|
||||
if ( node.updateBefore( this ) !== false ) {
|
||||
|
||||
renderMap.set( reference, this.renderId );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( updateType === NodeUpdateType.OBJECT ) {
|
||||
|
||||
node.updateBefore( this );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateNode( node ) {
|
||||
|
||||
const updateType = node.getUpdateType();
|
||||
const reference = node.updateReference( this );
|
||||
|
||||
if ( updateType === NodeUpdateType.FRAME ) {
|
||||
|
||||
const { frameMap } = this._getMaps( this.updateMap, reference );
|
||||
|
||||
if ( frameMap.get( reference ) !== this.frameId ) {
|
||||
|
||||
if ( node.update( this ) !== false ) {
|
||||
|
||||
frameMap.set( reference, this.frameId );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( updateType === NodeUpdateType.RENDER ) {
|
||||
|
||||
const { renderMap } = this._getMaps( this.updateMap, reference );
|
||||
|
||||
if ( renderMap.get( reference ) !== this.renderId ) {
|
||||
|
||||
if ( node.update( this ) !== false ) {
|
||||
|
||||
renderMap.set( reference, this.renderId );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( updateType === NodeUpdateType.OBJECT ) {
|
||||
|
||||
node.update( this );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
this.frameId ++;
|
||||
|
||||
if ( this.lastTime === undefined ) this.lastTime = performance.now();
|
||||
|
||||
this.deltaTime = ( performance.now() - this.lastTime ) / 1000;
|
||||
|
||||
this.lastTime = performance.now();
|
||||
|
||||
this.time += this.deltaTime;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeFrame;
|
22
dist/electron/static/sdk/three/jsm/nodes/core/NodeFunction.js
vendored
Normal file
22
dist/electron/static/sdk/three/jsm/nodes/core/NodeFunction.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
class NodeFunction {
|
||||
|
||||
constructor( type, inputs, name = '', presicion = '' ) {
|
||||
|
||||
this.type = type;
|
||||
this.inputs = inputs;
|
||||
this.name = name;
|
||||
this.presicion = presicion;
|
||||
|
||||
}
|
||||
|
||||
getCode( /*name = this.name*/ ) {
|
||||
|
||||
console.warn( 'Abstract function.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NodeFunction.isNodeFunction = true;
|
||||
|
||||
export default NodeFunction;
|
17
dist/electron/static/sdk/three/jsm/nodes/core/NodeFunctionInput.js
vendored
Normal file
17
dist/electron/static/sdk/three/jsm/nodes/core/NodeFunctionInput.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
class NodeFunctionInput {
|
||||
|
||||
constructor( type, name, count = null, qualifier = '', isConst = false ) {
|
||||
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.count = count;
|
||||
this.qualifier = qualifier;
|
||||
this.isConst = isConst;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NodeFunctionInput.isNodeFunctionInput = true;
|
||||
|
||||
export default NodeFunctionInput;
|
80
dist/electron/static/sdk/three/jsm/nodes/core/NodeKeywords.js
vendored
Normal file
80
dist/electron/static/sdk/three/jsm/nodes/core/NodeKeywords.js
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
class NodeKeywords {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.keywords = [];
|
||||
this.nodes = [];
|
||||
this.keywordsCallback = {};
|
||||
|
||||
}
|
||||
|
||||
getNode( name ) {
|
||||
|
||||
let node = this.nodes[ name ];
|
||||
|
||||
if ( node === undefined && this.keywordsCallback[ name ] !== undefined ) {
|
||||
|
||||
node = this.keywordsCallback[ name ]( name );
|
||||
|
||||
this.nodes[ name ] = node;
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
}
|
||||
|
||||
addKeyword( name, callback ) {
|
||||
|
||||
this.keywords.push( name );
|
||||
this.keywordsCallback[ name ] = callback;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
parse( code ) {
|
||||
|
||||
const keywordNames = this.keywords;
|
||||
|
||||
const regExp = new RegExp( `\\b${keywordNames.join( '\\b|\\b' )}\\b`, 'g' );
|
||||
|
||||
const codeKeywords = code.match( regExp );
|
||||
|
||||
const keywordNodes = [];
|
||||
|
||||
if ( codeKeywords !== null ) {
|
||||
|
||||
for ( const keyword of codeKeywords ) {
|
||||
|
||||
const node = this.getNode( keyword );
|
||||
|
||||
if ( node !== undefined && keywordNodes.indexOf( node ) === - 1 ) {
|
||||
|
||||
keywordNodes.push( node );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return keywordNodes;
|
||||
|
||||
}
|
||||
|
||||
include( builder, code ) {
|
||||
|
||||
const keywordNodes = this.parse( code );
|
||||
|
||||
for ( const keywordNode of keywordNodes ) {
|
||||
|
||||
keywordNode.build( builder );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeKeywords;
|
11
dist/electron/static/sdk/three/jsm/nodes/core/NodeParser.js
vendored
Normal file
11
dist/electron/static/sdk/three/jsm/nodes/core/NodeParser.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
class NodeParser {
|
||||
|
||||
parseFunction( /*source*/ ) {
|
||||
|
||||
console.warn( 'Abstract function.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeParser;
|
40
dist/electron/static/sdk/three/jsm/nodes/core/NodeUniform.js
vendored
Normal file
40
dist/electron/static/sdk/three/jsm/nodes/core/NodeUniform.js
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
class NodeUniform {
|
||||
|
||||
constructor( name, type, node, needsUpdate = undefined ) {
|
||||
|
||||
this.isNodeUniform = true;
|
||||
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.node = node.getSelf();
|
||||
this.needsUpdate = needsUpdate;
|
||||
|
||||
}
|
||||
|
||||
get value() {
|
||||
|
||||
return this.node.value;
|
||||
|
||||
}
|
||||
|
||||
set value( val ) {
|
||||
|
||||
this.node.value = val;
|
||||
|
||||
}
|
||||
|
||||
get id() {
|
||||
|
||||
return this.node.id;
|
||||
|
||||
}
|
||||
|
||||
get groupNode() {
|
||||
|
||||
return this.node.groupNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeUniform;
|
210
dist/electron/static/sdk/three/jsm/nodes/core/NodeUtils.js
vendored
Normal file
210
dist/electron/static/sdk/three/jsm/nodes/core/NodeUtils.js
vendored
Normal file
@ -0,0 +1,210 @@
|
||||
import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three';
|
||||
|
||||
export function getCacheKey( object, force = false ) {
|
||||
|
||||
let cacheKey = '{';
|
||||
|
||||
if ( object.isNode === true ) {
|
||||
|
||||
cacheKey += object.id;
|
||||
|
||||
}
|
||||
|
||||
for ( const { property, childNode } of getNodeChildren( object ) ) {
|
||||
|
||||
cacheKey += ',' + property.slice( 0, - 4 ) + ':' + childNode.getCacheKey( force );
|
||||
|
||||
}
|
||||
|
||||
cacheKey += '}';
|
||||
|
||||
return cacheKey;
|
||||
|
||||
}
|
||||
|
||||
export function* getNodeChildren( node, toJSON = false ) {
|
||||
|
||||
for ( const property in node ) {
|
||||
|
||||
// Ignore private properties.
|
||||
if ( property.startsWith( '_' ) === true ) continue;
|
||||
|
||||
const object = node[ property ];
|
||||
|
||||
if ( Array.isArray( object ) === true ) {
|
||||
|
||||
for ( let i = 0; i < object.length; i ++ ) {
|
||||
|
||||
const child = object[ i ];
|
||||
|
||||
if ( child && ( child.isNode === true || toJSON && typeof child.toJSON === 'function' ) ) {
|
||||
|
||||
yield { property, index: i, childNode: child };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( object && object.isNode === true ) {
|
||||
|
||||
yield { property, childNode: object };
|
||||
|
||||
} else if ( typeof object === 'object' ) {
|
||||
|
||||
for ( const subProperty in object ) {
|
||||
|
||||
const child = object[ subProperty ];
|
||||
|
||||
if ( child && ( child.isNode === true || toJSON && typeof child.toJSON === 'function' ) ) {
|
||||
|
||||
yield { property, index: subProperty, childNode: child };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function getValueType( value ) {
|
||||
|
||||
if ( value === undefined || value === null ) return null;
|
||||
|
||||
const typeOf = typeof value;
|
||||
|
||||
if ( value.isNode === true ) {
|
||||
|
||||
return 'node';
|
||||
|
||||
} else if ( typeOf === 'number' ) {
|
||||
|
||||
return 'float';
|
||||
|
||||
} else if ( typeOf === 'boolean' ) {
|
||||
|
||||
return 'bool';
|
||||
|
||||
} else if ( typeOf === 'string' ) {
|
||||
|
||||
return 'string';
|
||||
|
||||
} else if ( typeOf === 'function' ) {
|
||||
|
||||
return 'shader';
|
||||
|
||||
} else if ( value.isVector2 === true ) {
|
||||
|
||||
return 'vec2';
|
||||
|
||||
} else if ( value.isVector3 === true ) {
|
||||
|
||||
return 'vec3';
|
||||
|
||||
} else if ( value.isVector4 === true ) {
|
||||
|
||||
return 'vec4';
|
||||
|
||||
} else if ( value.isMatrix3 === true ) {
|
||||
|
||||
return 'mat3';
|
||||
|
||||
} else if ( value.isMatrix4 === true ) {
|
||||
|
||||
return 'mat4';
|
||||
|
||||
} else if ( value.isColor === true ) {
|
||||
|
||||
return 'color';
|
||||
|
||||
} else if ( value instanceof ArrayBuffer ) {
|
||||
|
||||
return 'ArrayBuffer';
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
export function getValueFromType( type, ...params ) {
|
||||
|
||||
const last4 = type ? type.slice( - 4 ) : undefined;
|
||||
|
||||
if ( params.length === 1 ) { // ensure same behaviour as in NodeBuilder.format()
|
||||
|
||||
if ( last4 === 'vec2' ) params = [ params[ 0 ], params[ 0 ] ];
|
||||
else if ( last4 === 'vec3' ) params = [ params[ 0 ], params[ 0 ], params[ 0 ] ];
|
||||
else if ( last4 === 'vec4' ) params = [ params[ 0 ], params[ 0 ], params[ 0 ], params[ 0 ] ];
|
||||
|
||||
}
|
||||
|
||||
if ( type === 'color' ) {
|
||||
|
||||
return new Color( ...params );
|
||||
|
||||
} else if ( last4 === 'vec2' ) {
|
||||
|
||||
return new Vector2( ...params );
|
||||
|
||||
} else if ( last4 === 'vec3' ) {
|
||||
|
||||
return new Vector3( ...params );
|
||||
|
||||
} else if ( last4 === 'vec4' ) {
|
||||
|
||||
return new Vector4( ...params );
|
||||
|
||||
} else if ( last4 === 'mat3' ) {
|
||||
|
||||
return new Matrix3( ...params );
|
||||
|
||||
} else if ( last4 === 'mat4' ) {
|
||||
|
||||
return new Matrix4( ...params );
|
||||
|
||||
} else if ( type === 'bool' ) {
|
||||
|
||||
return params[ 0 ] || false;
|
||||
|
||||
} else if ( ( type === 'float' ) || ( type === 'int' ) || ( type === 'uint' ) ) {
|
||||
|
||||
return params[ 0 ] || 0;
|
||||
|
||||
} else if ( type === 'string' ) {
|
||||
|
||||
return params[ 0 ] || '';
|
||||
|
||||
} else if ( type === 'ArrayBuffer' ) {
|
||||
|
||||
return base64ToArrayBuffer( params[ 0 ] );
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
export function arrayBufferToBase64( arrayBuffer ) {
|
||||
|
||||
let chars = '';
|
||||
|
||||
const array = new Uint8Array( arrayBuffer );
|
||||
|
||||
for ( let i = 0; i < array.length; i ++ ) {
|
||||
|
||||
chars += String.fromCharCode( array[ i ] );
|
||||
|
||||
}
|
||||
|
||||
return btoa( chars );
|
||||
|
||||
}
|
||||
|
||||
export function base64ToArrayBuffer( base64 ) {
|
||||
|
||||
return Uint8Array.from( atob( base64 ), c => c.charCodeAt( 0 ) ).buffer;
|
||||
|
||||
}
|
14
dist/electron/static/sdk/three/jsm/nodes/core/NodeVar.js
vendored
Normal file
14
dist/electron/static/sdk/three/jsm/nodes/core/NodeVar.js
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
class NodeVar {
|
||||
|
||||
constructor( name, type ) {
|
||||
|
||||
this.isNodeVar = true;
|
||||
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeVar;
|
17
dist/electron/static/sdk/three/jsm/nodes/core/NodeVarying.js
vendored
Normal file
17
dist/electron/static/sdk/three/jsm/nodes/core/NodeVarying.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
import NodeVar from './NodeVar.js';
|
||||
|
||||
class NodeVarying extends NodeVar {
|
||||
|
||||
constructor( name, type ) {
|
||||
|
||||
super( name, type );
|
||||
|
||||
this.needsInterpolation = false;
|
||||
|
||||
this.isNodeVarying = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeVarying;
|
63
dist/electron/static/sdk/three/jsm/nodes/core/OutputStructNode.js
vendored
Normal file
63
dist/electron/static/sdk/three/jsm/nodes/core/OutputStructNode.js
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import StructTypeNode from './StructTypeNode.js';
|
||||
import { nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class OutputStructNode extends Node {
|
||||
|
||||
constructor( ...members ) {
|
||||
|
||||
super();
|
||||
|
||||
this.members = members;
|
||||
|
||||
this.isOutputStructNode = true;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
super.setup( builder );
|
||||
|
||||
const members = this.members;
|
||||
const types = [];
|
||||
|
||||
for ( let i = 0; i < members.length; i ++ ) {
|
||||
|
||||
types.push( members[ i ].getNodeType( builder ) );
|
||||
|
||||
}
|
||||
|
||||
this.nodeType = builder.getStructTypeFromNode( new StructTypeNode( types ) ).name;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const nodeVar = builder.getVarFromNode( this );
|
||||
nodeVar.isOutputStructVar = true;
|
||||
|
||||
const propertyName = builder.getPropertyName( nodeVar );
|
||||
|
||||
const members = this.members;
|
||||
|
||||
const structPrefix = propertyName !== '' ? propertyName + '.' : '';
|
||||
|
||||
for ( let i = 0; i < members.length; i ++ ) {
|
||||
|
||||
const snippet = members[ i ].build( builder, output );
|
||||
|
||||
builder.addLineFlowCode( `${ structPrefix }m${ i } = ${ snippet }` );
|
||||
|
||||
}
|
||||
|
||||
return propertyName;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default OutputStructNode;
|
||||
|
||||
export const outputStruct = nodeProxy( OutputStructNode );
|
||||
|
||||
addNodeClass( 'OutputStructNode', OutputStructNode );
|
33
dist/electron/static/sdk/three/jsm/nodes/core/ParameterNode.js
vendored
Normal file
33
dist/electron/static/sdk/three/jsm/nodes/core/ParameterNode.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
import { addNodeClass } from './Node.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
import PropertyNode from './PropertyNode.js';
|
||||
|
||||
class ParameterNode extends PropertyNode {
|
||||
|
||||
constructor( nodeType, name = null ) {
|
||||
|
||||
super( nodeType, name );
|
||||
|
||||
this.isParameterNode = true;
|
||||
|
||||
}
|
||||
|
||||
getHash() {
|
||||
|
||||
return this.uuid;
|
||||
|
||||
}
|
||||
|
||||
generate() {
|
||||
|
||||
return this.name;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ParameterNode;
|
||||
|
||||
export const parameter = ( type, name ) => nodeObject( new ParameterNode( type, name ) );
|
||||
|
||||
addNodeClass( 'ParameterNode', ParameterNode );
|
82
dist/electron/static/sdk/three/jsm/nodes/core/PropertyNode.js
vendored
Normal file
82
dist/electron/static/sdk/three/jsm/nodes/core/PropertyNode.js
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { nodeImmutable, nodeObject } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class PropertyNode extends Node {
|
||||
|
||||
constructor( nodeType, name = null, varying = false ) {
|
||||
|
||||
super( nodeType );
|
||||
|
||||
this.name = name;
|
||||
this.varying = varying;
|
||||
|
||||
this.isPropertyNode = true;
|
||||
|
||||
}
|
||||
|
||||
getHash( builder ) {
|
||||
|
||||
return this.name || super.getHash( builder );
|
||||
|
||||
}
|
||||
|
||||
isGlobal( /*builder*/ ) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
let nodeVar;
|
||||
|
||||
if ( this.varying === true ) {
|
||||
|
||||
nodeVar = builder.getVaryingFromNode( this, this.name );
|
||||
nodeVar.needsInterpolation = true;
|
||||
|
||||
} else {
|
||||
|
||||
nodeVar = builder.getVarFromNode( this, this.name );
|
||||
|
||||
}
|
||||
|
||||
return builder.getPropertyName( nodeVar );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default PropertyNode;
|
||||
|
||||
export const property = ( type, name ) => nodeObject( new PropertyNode( type, name ) );
|
||||
export const varyingProperty = ( type, name ) => nodeObject( new PropertyNode( type, name, true ) );
|
||||
|
||||
export const diffuseColor = nodeImmutable( PropertyNode, 'vec4', 'DiffuseColor' );
|
||||
export const roughness = nodeImmutable( PropertyNode, 'float', 'Roughness' );
|
||||
export const metalness = nodeImmutable( PropertyNode, 'float', 'Metalness' );
|
||||
export const clearcoat = nodeImmutable( PropertyNode, 'float', 'Clearcoat' );
|
||||
export const clearcoatRoughness = nodeImmutable( PropertyNode, 'float', 'ClearcoatRoughness' );
|
||||
export const sheen = nodeImmutable( PropertyNode, 'vec3', 'Sheen' );
|
||||
export const sheenRoughness = nodeImmutable( PropertyNode, 'float', 'SheenRoughness' );
|
||||
export const iridescence = nodeImmutable( PropertyNode, 'float', 'Iridescence' );
|
||||
export const iridescenceIOR = nodeImmutable( PropertyNode, 'float', 'IridescenceIOR' );
|
||||
export const iridescenceThickness = nodeImmutable( PropertyNode, 'float', 'IridescenceThickness' );
|
||||
export const alphaT = nodeImmutable( PropertyNode, 'float', 'AlphaT' );
|
||||
export const anisotropy = nodeImmutable( PropertyNode, 'float', 'Anisotropy' );
|
||||
export const anisotropyT = nodeImmutable( PropertyNode, 'vec3', 'AnisotropyT' );
|
||||
export const anisotropyB = nodeImmutable( PropertyNode, 'vec3', 'AnisotropyB' );
|
||||
export const specularColor = nodeImmutable( PropertyNode, 'color', 'SpecularColor' );
|
||||
export const specularF90 = nodeImmutable( PropertyNode, 'float', 'SpecularF90' );
|
||||
export const shininess = nodeImmutable( PropertyNode, 'float', 'Shininess' );
|
||||
export const output = nodeImmutable( PropertyNode, 'vec4', 'Output' );
|
||||
export const dashSize = nodeImmutable( PropertyNode, 'float', 'dashSize' );
|
||||
export const gapSize = nodeImmutable( PropertyNode, 'float', 'gapSize' );
|
||||
export const pointWidth = nodeImmutable( PropertyNode, 'float', 'pointWidth' );
|
||||
export const ior = nodeImmutable( PropertyNode, 'float', 'IOR' );
|
||||
export const transmission = nodeImmutable( PropertyNode, 'float', 'Transmission' );
|
||||
export const thickness = nodeImmutable( PropertyNode, 'float', 'Thickness' );
|
||||
export const attenuationDistance = nodeImmutable( PropertyNode, 'float', 'AttenuationDistance' );
|
||||
export const attenuationColor = nodeImmutable( PropertyNode, 'color', 'AttenuationColor' );
|
||||
|
||||
addNodeClass( 'PropertyNode', PropertyNode );
|
89
dist/electron/static/sdk/three/jsm/nodes/core/StackNode.js
vendored
Normal file
89
dist/electron/static/sdk/three/jsm/nodes/core/StackNode.js
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { cond } from '../math/CondNode.js';
|
||||
import { ShaderNode, nodeProxy, getCurrentStack, setCurrentStack } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class StackNode extends Node {
|
||||
|
||||
constructor( parent = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.nodes = [];
|
||||
this.outputNode = null;
|
||||
|
||||
this.parent = parent;
|
||||
|
||||
this._currentCond = null;
|
||||
|
||||
this.isStackNode = true;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.outputNode ? this.outputNode.getNodeType( builder ) : 'void';
|
||||
|
||||
}
|
||||
|
||||
add( node ) {
|
||||
|
||||
this.nodes.push( node );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
if( boolNode, method ) {
|
||||
|
||||
const methodNode = new ShaderNode( method );
|
||||
this._currentCond = cond( boolNode, methodNode );
|
||||
|
||||
return this.add( this._currentCond );
|
||||
|
||||
}
|
||||
|
||||
elseif( boolNode, method ) {
|
||||
|
||||
const methodNode = new ShaderNode( method );
|
||||
const ifNode = cond( boolNode, methodNode );
|
||||
|
||||
this._currentCond.elseNode = ifNode;
|
||||
this._currentCond = ifNode;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
else( method ) {
|
||||
|
||||
this._currentCond.elseNode = new ShaderNode( method );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
build( builder, ...params ) {
|
||||
|
||||
const previousStack = getCurrentStack();
|
||||
|
||||
setCurrentStack( this );
|
||||
|
||||
for ( const node of this.nodes ) {
|
||||
|
||||
node.build( builder, 'void' );
|
||||
|
||||
}
|
||||
|
||||
setCurrentStack( previousStack );
|
||||
|
||||
return this.outputNode ? this.outputNode.build( builder, ...params ) : super.build( builder, ...params );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default StackNode;
|
||||
|
||||
export const stack = nodeProxy( StackNode );
|
||||
|
||||
addNodeClass( 'StackNode', StackNode );
|
24
dist/electron/static/sdk/three/jsm/nodes/core/StructTypeNode.js
vendored
Normal file
24
dist/electron/static/sdk/three/jsm/nodes/core/StructTypeNode.js
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
|
||||
class StructTypeNode extends Node {
|
||||
|
||||
constructor( types ) {
|
||||
|
||||
super();
|
||||
|
||||
this.types = types;
|
||||
this.isStructTypeNode = true;
|
||||
|
||||
}
|
||||
|
||||
getMemberTypes() {
|
||||
|
||||
return this.types;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default StructTypeNode;
|
||||
|
||||
addNodeClass( 'StructTypeNode', StructTypeNode );
|
58
dist/electron/static/sdk/three/jsm/nodes/core/TempNode.js
vendored
Normal file
58
dist/electron/static/sdk/three/jsm/nodes/core/TempNode.js
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
|
||||
class TempNode extends Node {
|
||||
|
||||
constructor( type ) {
|
||||
|
||||
super( type );
|
||||
|
||||
this.isTempNode = true;
|
||||
|
||||
}
|
||||
|
||||
hasDependencies( builder ) {
|
||||
|
||||
return builder.getDataFromNode( this ).usageCount > 1;
|
||||
|
||||
}
|
||||
|
||||
build( builder, output ) {
|
||||
|
||||
const buildStage = builder.getBuildStage();
|
||||
|
||||
if ( buildStage === 'generate' ) {
|
||||
|
||||
const type = builder.getVectorType( this.getNodeType( builder, output ) );
|
||||
const nodeData = builder.getDataFromNode( this );
|
||||
|
||||
if ( builder.context.tempRead !== false && nodeData.propertyName !== undefined ) {
|
||||
|
||||
return builder.format( nodeData.propertyName, type, output );
|
||||
|
||||
} else if ( builder.context.tempWrite !== false && type !== 'void' && output !== 'void' && this.hasDependencies( builder ) ) {
|
||||
|
||||
const snippet = super.build( builder, type );
|
||||
|
||||
const nodeVar = builder.getVarFromNode( this, null, type );
|
||||
const propertyName = builder.getPropertyName( nodeVar );
|
||||
|
||||
builder.addLineFlowCode( `${propertyName} = ${snippet}` );
|
||||
|
||||
nodeData.snippet = snippet;
|
||||
nodeData.propertyName = propertyName;
|
||||
|
||||
return builder.format( nodeData.propertyName, type, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return super.build( builder, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default TempNode;
|
||||
|
||||
addNodeClass( 'TempNode', TempNode );
|
13
dist/electron/static/sdk/three/jsm/nodes/core/UniformGroup.js
vendored
Normal file
13
dist/electron/static/sdk/three/jsm/nodes/core/UniformGroup.js
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
class UniformGroup {
|
||||
|
||||
constructor( name ) {
|
||||
|
||||
this.name = name;
|
||||
|
||||
this.isUniformGroup = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default UniformGroup;
|
36
dist/electron/static/sdk/three/jsm/nodes/core/UniformGroupNode.js
vendored
Normal file
36
dist/electron/static/sdk/three/jsm/nodes/core/UniformGroupNode.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
import Node from './Node.js';
|
||||
import { addNodeClass } from './Node.js';
|
||||
|
||||
class UniformGroupNode extends Node {
|
||||
|
||||
constructor( name, shared = false ) {
|
||||
|
||||
super( 'string' );
|
||||
|
||||
this.name = name;
|
||||
this.version = 0;
|
||||
|
||||
this.shared = shared;
|
||||
|
||||
this.isUniformGroup = true;
|
||||
|
||||
}
|
||||
|
||||
set needsUpdate( value ) {
|
||||
|
||||
if ( value === true ) this.version ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const uniformGroup = ( name ) => new UniformGroupNode( name );
|
||||
export const sharedUniformGroup = ( name ) => new UniformGroupNode( name, true );
|
||||
|
||||
export const frameGroup = sharedUniformGroup( 'frame' );
|
||||
export const renderGroup = sharedUniformGroup( 'render' );
|
||||
export const objectGroup = uniformGroup( 'object' );
|
||||
|
||||
export default UniformGroupNode;
|
||||
|
||||
addNodeClass( 'UniformGroupNode', UniformGroupNode );
|
100
dist/electron/static/sdk/three/jsm/nodes/core/UniformNode.js
vendored
Normal file
100
dist/electron/static/sdk/three/jsm/nodes/core/UniformNode.js
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
import InputNode from './InputNode.js';
|
||||
import { objectGroup } from './UniformGroupNode.js';
|
||||
import { addNodeClass } from './Node.js';
|
||||
import { nodeObject, getConstNodeType } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class UniformNode extends InputNode {
|
||||
|
||||
constructor( value, nodeType = null ) {
|
||||
|
||||
super( value, nodeType );
|
||||
|
||||
this.isUniformNode = true;
|
||||
|
||||
this.groupNode = objectGroup;
|
||||
|
||||
}
|
||||
|
||||
setGroup( group ) {
|
||||
|
||||
this.groupNode = group;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getGroup() {
|
||||
|
||||
return this.groupNode;
|
||||
|
||||
}
|
||||
|
||||
getUniformHash( builder ) {
|
||||
|
||||
return this.getHash( builder );
|
||||
|
||||
}
|
||||
|
||||
onUpdate( callback, updateType ) {
|
||||
|
||||
const self = this.getSelf();
|
||||
|
||||
callback = callback.bind( self );
|
||||
|
||||
return super.onUpdate( ( frame ) => {
|
||||
|
||||
const value = callback( frame, self );
|
||||
|
||||
if ( value !== undefined ) {
|
||||
|
||||
this.value = value;
|
||||
|
||||
}
|
||||
|
||||
}, updateType );
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const type = this.getNodeType( builder );
|
||||
|
||||
const hash = this.getUniformHash( builder );
|
||||
|
||||
let sharedNode = builder.getNodeFromHash( hash );
|
||||
|
||||
if ( sharedNode === undefined ) {
|
||||
|
||||
builder.setHashNode( this, hash );
|
||||
|
||||
sharedNode = this;
|
||||
|
||||
}
|
||||
|
||||
const sharedNodeType = sharedNode.getInputType( builder );
|
||||
|
||||
const nodeUniform = builder.getUniformFromNode( sharedNode, sharedNodeType, builder.shaderStage, builder.context.label );
|
||||
const propertyName = builder.getPropertyName( nodeUniform );
|
||||
|
||||
if ( builder.context.label !== undefined ) delete builder.context.label;
|
||||
|
||||
return builder.format( propertyName, type, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default UniformNode;
|
||||
|
||||
export const uniform = ( arg1, arg2 ) => {
|
||||
|
||||
const nodeType = getConstNodeType( arg2 || arg1 );
|
||||
|
||||
// @TODO: get ConstNode from .traverse() in the future
|
||||
const value = ( arg1 && arg1.isNode === true ) ? ( arg1.node && arg1.node.value ) || arg1.value : arg1;
|
||||
|
||||
return nodeObject( new UniformNode( value, nodeType ) );
|
||||
|
||||
};
|
||||
|
||||
addNodeClass( 'UniformNode', UniformNode );
|
60
dist/electron/static/sdk/three/jsm/nodes/core/VarNode.js
vendored
Normal file
60
dist/electron/static/sdk/three/jsm/nodes/core/VarNode.js
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class VarNode extends Node {
|
||||
|
||||
constructor( node, name = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.node = node;
|
||||
this.name = name;
|
||||
|
||||
this.isVarNode = true;
|
||||
|
||||
}
|
||||
|
||||
isGlobal() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
getHash( builder ) {
|
||||
|
||||
return this.name || super.getHash( builder );
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.node.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const { node, name } = this;
|
||||
|
||||
const nodeVar = builder.getVarFromNode( this, name, builder.getVectorType( this.getNodeType( builder ) ) );
|
||||
|
||||
const propertyName = builder.getPropertyName( nodeVar );
|
||||
|
||||
const snippet = node.build( builder, nodeVar.type );
|
||||
|
||||
builder.addLineFlowCode( `${propertyName} = ${snippet}` );
|
||||
|
||||
return propertyName;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default VarNode;
|
||||
|
||||
export const temp = nodeProxy( VarNode );
|
||||
|
||||
addNodeElement( 'temp', temp ); // @TODO: Will be removed in the future
|
||||
addNodeElement( 'toVar', ( ...params ) => temp( ...params ).append() );
|
||||
|
||||
addNodeClass( 'VarNode', VarNode );
|
65
dist/electron/static/sdk/three/jsm/nodes/core/VaryingNode.js
vendored
Normal file
65
dist/electron/static/sdk/three/jsm/nodes/core/VaryingNode.js
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { NodeShaderStage } from './constants.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class VaryingNode extends Node {
|
||||
|
||||
constructor( node, name = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.node = node;
|
||||
this.name = name;
|
||||
|
||||
this.isVaryingNode = true;
|
||||
|
||||
}
|
||||
|
||||
isGlobal() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
getHash( builder ) {
|
||||
|
||||
return this.name || super.getHash( builder );
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
// VaryingNode is auto type
|
||||
|
||||
return this.node.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const { name, node } = this;
|
||||
const type = this.getNodeType( builder );
|
||||
|
||||
const nodeVarying = builder.getVaryingFromNode( this, name, type );
|
||||
|
||||
// this property can be used to check if the varying can be optimized for a var
|
||||
nodeVarying.needsInterpolation || ( nodeVarying.needsInterpolation = ( builder.shaderStage === 'fragment' ) );
|
||||
|
||||
const propertyName = builder.getPropertyName( nodeVarying, NodeShaderStage.VERTEX );
|
||||
|
||||
// force node run in vertex stage
|
||||
builder.flowNodeFromShaderStage( NodeShaderStage.VERTEX, node, type, propertyName );
|
||||
|
||||
return builder.getPropertyName( nodeVarying );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default VaryingNode;
|
||||
|
||||
export const varying = nodeProxy( VaryingNode );
|
||||
|
||||
addNodeElement( 'varying', varying );
|
||||
|
||||
addNodeClass( 'VaryingNode', VaryingNode );
|
28
dist/electron/static/sdk/three/jsm/nodes/core/constants.js
vendored
Normal file
28
dist/electron/static/sdk/three/jsm/nodes/core/constants.js
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
export const NodeShaderStage = {
|
||||
VERTEX: 'vertex',
|
||||
FRAGMENT: 'fragment'
|
||||
};
|
||||
|
||||
export const NodeUpdateType = {
|
||||
NONE: 'none',
|
||||
FRAME: 'frame',
|
||||
RENDER: 'render',
|
||||
OBJECT: 'object'
|
||||
};
|
||||
|
||||
export const NodeType = {
|
||||
BOOLEAN: 'bool',
|
||||
INTEGER: 'int',
|
||||
FLOAT: 'float',
|
||||
VECTOR2: 'vec2',
|
||||
VECTOR3: 'vec3',
|
||||
VECTOR4: 'vec4',
|
||||
MATRIX2: 'mat2',
|
||||
MATRIX3: 'mat3',
|
||||
MATRIX4: 'mat4'
|
||||
};
|
||||
|
||||
export const defaultShaderStages = [ 'fragment', 'vertex' ];
|
||||
export const defaultBuildStages = [ 'setup', 'analyze', 'generate' ];
|
||||
export const shaderStages = [ ...defaultShaderStages, 'compute' ];
|
||||
export const vectorComponents = [ 'x', 'y', 'z', 'w' ];
|
148
dist/electron/static/sdk/three/jsm/nodes/display/AfterImageNode.js
vendored
Normal file
148
dist/electron/static/sdk/three/jsm/nodes/display/AfterImageNode.js
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { nodeObject, addNodeElement, tslFn, float, vec4 } from '../shadernode/ShaderNode.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { uv } from '../accessors/UVNode.js';
|
||||
import { texture } from '../accessors/TextureNode.js';
|
||||
import { texturePass } from './PassNode.js';
|
||||
import { uniform } from '../core/UniformNode.js';
|
||||
import { RenderTarget } from 'three';
|
||||
import { sign, max } from '../math/MathNode.js';
|
||||
import QuadMesh from '../../objects/QuadMesh.js';
|
||||
|
||||
const quadMeshComp = new QuadMesh();
|
||||
|
||||
class AfterImageNode extends TempNode {
|
||||
|
||||
constructor( textureNode, damp = 0.96 ) {
|
||||
|
||||
super( textureNode );
|
||||
|
||||
this.textureNode = textureNode;
|
||||
this.textureNodeOld = texture();
|
||||
this.damp = uniform( damp );
|
||||
|
||||
this._compRT = new RenderTarget();
|
||||
this._compRT.texture.name = 'AfterImageNode.comp';
|
||||
|
||||
this._oldRT = new RenderTarget();
|
||||
this._oldRT.texture.name = 'AfterImageNode.old';
|
||||
|
||||
this._textureNode = texturePass( this, this._compRT.texture );
|
||||
|
||||
this.updateBeforeType = NodeUpdateType.RENDER;
|
||||
|
||||
}
|
||||
|
||||
getTextureNode() {
|
||||
|
||||
return this._textureNode;
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this._compRT.setSize( width, height );
|
||||
this._oldRT.setSize( width, height );
|
||||
|
||||
}
|
||||
|
||||
updateBefore( frame ) {
|
||||
|
||||
const { renderer } = frame;
|
||||
|
||||
const textureNode = this.textureNode;
|
||||
const map = textureNode.value;
|
||||
|
||||
const textureType = map.type;
|
||||
|
||||
this._compRT.texture.type = textureType;
|
||||
this._oldRT.texture.type = textureType;
|
||||
|
||||
const currentRenderTarget = renderer.getRenderTarget();
|
||||
const currentTexture = textureNode.value;
|
||||
|
||||
this.textureNodeOld.value = this._oldRT.texture;
|
||||
|
||||
// comp
|
||||
renderer.setRenderTarget( this._compRT );
|
||||
quadMeshComp.render( renderer );
|
||||
|
||||
// Swap the textures
|
||||
const temp = this._oldRT;
|
||||
this._oldRT = this._compRT;
|
||||
this._compRT = temp;
|
||||
|
||||
// set size before swapping fails
|
||||
this.setSize( map.image.width, map.image.height );
|
||||
|
||||
renderer.setRenderTarget( currentRenderTarget );
|
||||
textureNode.value = currentTexture;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const textureNode = this.textureNode;
|
||||
const textureNodeOld = this.textureNodeOld;
|
||||
|
||||
if ( textureNode.isTextureNode !== true ) {
|
||||
|
||||
console.error( 'AfterImageNode requires a TextureNode.' );
|
||||
|
||||
return vec4();
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const uvNode = textureNode.uvNode || uv();
|
||||
|
||||
textureNodeOld.uvNode = uvNode;
|
||||
|
||||
const sampleTexture = ( uv ) => textureNode.cache().context( { getUV: () => uv, forceUVContext: true } );
|
||||
|
||||
const when_gt = tslFn( ( [ x_immutable, y_immutable ] ) => {
|
||||
|
||||
const y = float( y_immutable ).toVar();
|
||||
const x = vec4( x_immutable ).toVar();
|
||||
|
||||
return max( sign( x.sub( y ) ), 0.0 );
|
||||
|
||||
} );
|
||||
|
||||
const afterImg = tslFn( () => {
|
||||
|
||||
const texelOld = vec4( textureNodeOld );
|
||||
const texelNew = vec4( sampleTexture( uvNode ) );
|
||||
|
||||
texelOld.mulAssign( this.damp.mul( when_gt( texelOld, 0.1 ) ) );
|
||||
return max( texelNew, texelOld );
|
||||
|
||||
} );
|
||||
|
||||
//
|
||||
|
||||
const materialComposed = this._materialComposed || ( this._materialComposed = builder.createNodeMaterial() );
|
||||
materialComposed.fragmentNode = afterImg();
|
||||
|
||||
quadMeshComp.material = materialComposed;
|
||||
|
||||
//
|
||||
|
||||
const properties = builder.getNodeProperties( this );
|
||||
properties.textureNode = textureNode;
|
||||
|
||||
//
|
||||
|
||||
return this._textureNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const afterImage = ( node, damp ) => nodeObject( new AfterImageNode( nodeObject( node ), damp ) );
|
||||
|
||||
addNodeElement( 'afterImage', afterImage );
|
||||
|
||||
export default AfterImageNode;
|
||||
|
148
dist/electron/static/sdk/three/jsm/nodes/display/AnamorphicNode.js
vendored
Normal file
148
dist/electron/static/sdk/three/jsm/nodes/display/AnamorphicNode.js
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { nodeObject, addNodeElement, tslFn, float, vec2, vec3, vec4 } from '../shadernode/ShaderNode.js';
|
||||
import { loop } from '../utils/LoopNode.js';
|
||||
import { uniform } from '../core/UniformNode.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { threshold } from './ColorAdjustmentNode.js';
|
||||
import { uv } from '../accessors/UVNode.js';
|
||||
import { texturePass } from './PassNode.js';
|
||||
import { Vector2, RenderTarget } from 'three';
|
||||
import QuadMesh from '../../objects/QuadMesh.js';
|
||||
|
||||
const quadMesh = new QuadMesh();
|
||||
|
||||
class AnamorphicNode extends TempNode {
|
||||
|
||||
constructor( textureNode, tresholdNode, scaleNode, samples ) {
|
||||
|
||||
super( 'vec4' );
|
||||
|
||||
this.textureNode = textureNode;
|
||||
this.tresholdNode = tresholdNode;
|
||||
this.scaleNode = scaleNode;
|
||||
this.colorNode = vec3( 0.1, 0.0, 1.0 );
|
||||
this.samples = samples;
|
||||
this.resolution = new Vector2( 1, 1 );
|
||||
|
||||
this._renderTarget = new RenderTarget();
|
||||
this._renderTarget.texture.name = 'anamorphic';
|
||||
|
||||
this._invSize = uniform( new Vector2() );
|
||||
|
||||
this._textureNode = texturePass( this, this._renderTarget.texture );
|
||||
|
||||
this.updateBeforeType = NodeUpdateType.RENDER;
|
||||
|
||||
}
|
||||
|
||||
getTextureNode() {
|
||||
|
||||
return this._textureNode;
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this._invSize.value.set( 1 / width, 1 / height );
|
||||
|
||||
width = Math.max( Math.round( width * this.resolution.x ), 1 );
|
||||
height = Math.max( Math.round( height * this.resolution.y ), 1 );
|
||||
|
||||
this._renderTarget.setSize( width, height );
|
||||
|
||||
}
|
||||
|
||||
updateBefore( frame ) {
|
||||
|
||||
const { renderer } = frame;
|
||||
|
||||
const textureNode = this.textureNode;
|
||||
const map = textureNode.value;
|
||||
|
||||
this._renderTarget.texture.type = map.type;
|
||||
|
||||
const currentRenderTarget = renderer.getRenderTarget();
|
||||
const currentTexture = textureNode.value;
|
||||
|
||||
quadMesh.material = this._material;
|
||||
|
||||
this.setSize( map.image.width, map.image.height );
|
||||
|
||||
// render
|
||||
|
||||
renderer.setRenderTarget( this._renderTarget );
|
||||
|
||||
quadMesh.render( renderer );
|
||||
|
||||
// restore
|
||||
|
||||
renderer.setRenderTarget( currentRenderTarget );
|
||||
textureNode.value = currentTexture;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const textureNode = this.textureNode;
|
||||
|
||||
if ( textureNode.isTextureNode !== true ) {
|
||||
|
||||
console.error( 'AnamorphNode requires a TextureNode.' );
|
||||
|
||||
return vec4();
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const uvNode = textureNode.uvNode || uv();
|
||||
|
||||
const sampleTexture = ( uv ) => textureNode.cache().context( { getUV: () => uv, forceUVContext: true } );
|
||||
|
||||
const anamorph = tslFn( () => {
|
||||
|
||||
const samples = this.samples;
|
||||
const halfSamples = Math.floor( samples / 2 );
|
||||
|
||||
const total = vec3( 0 ).toVar();
|
||||
|
||||
loop( { start: - halfSamples, end: halfSamples }, ( { i } ) => {
|
||||
|
||||
const softness = float( i ).abs().div( halfSamples ).oneMinus();
|
||||
|
||||
const uv = vec2( uvNode.x.add( this._invSize.x.mul( i ).mul( this.scaleNode ) ), uvNode.y );
|
||||
const color = sampleTexture( uv );
|
||||
const pass = threshold( color, this.tresholdNode ).mul( softness );
|
||||
|
||||
total.addAssign( pass );
|
||||
|
||||
} );
|
||||
|
||||
return total.mul( this.colorNode );
|
||||
|
||||
} );
|
||||
|
||||
//
|
||||
|
||||
const material = this._material || ( this._material = builder.createNodeMaterial() );
|
||||
material.fragmentNode = anamorph();
|
||||
|
||||
//
|
||||
|
||||
const properties = builder.getNodeProperties( this );
|
||||
properties.textureNode = textureNode;
|
||||
|
||||
//
|
||||
|
||||
return this._textureNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const anamorphic = ( node, threshold = .9, scale = 3, samples = 32 ) => nodeObject( new AnamorphicNode( nodeObject( node ), nodeObject( threshold ), nodeObject( scale ), samples ) );
|
||||
|
||||
addNodeElement( 'anamorphic', anamorphic );
|
||||
|
||||
export default AnamorphicNode;
|
||||
|
128
dist/electron/static/sdk/three/jsm/nodes/display/BlendModeNode.js
vendored
Normal file
128
dist/electron/static/sdk/three/jsm/nodes/display/BlendModeNode.js
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { /*mix, step,*/ EPSILON } from '../math/MathNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, tslFn, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
|
||||
|
||||
export const BurnNode = tslFn( ( { base, blend } ) => {
|
||||
|
||||
const fn = ( c ) => blend[ c ].lessThan( EPSILON ).cond( blend[ c ], base[ c ].oneMinus().div( blend[ c ] ).oneMinus().max( 0 ) );
|
||||
|
||||
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
|
||||
|
||||
} ).setLayout( {
|
||||
name: 'burnColor',
|
||||
type: 'vec3',
|
||||
inputs: [
|
||||
{ name: 'base', type: 'vec3' },
|
||||
{ name: 'blend', type: 'vec3' }
|
||||
]
|
||||
} );
|
||||
|
||||
export const DodgeNode = tslFn( ( { base, blend } ) => {
|
||||
|
||||
const fn = ( c ) => blend[ c ].equal( 1.0 ).cond( blend[ c ], base[ c ].div( blend[ c ].oneMinus() ).max( 0 ) );
|
||||
|
||||
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
|
||||
|
||||
} ).setLayout( {
|
||||
name: 'dodgeColor',
|
||||
type: 'vec3',
|
||||
inputs: [
|
||||
{ name: 'base', type: 'vec3' },
|
||||
{ name: 'blend', type: 'vec3' }
|
||||
]
|
||||
} );
|
||||
|
||||
export const ScreenNode = tslFn( ( { base, blend } ) => {
|
||||
|
||||
const fn = ( c ) => base[ c ].oneMinus().mul( blend[ c ].oneMinus() ).oneMinus();
|
||||
|
||||
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
|
||||
|
||||
} ).setLayout( {
|
||||
name: 'screenColor',
|
||||
type: 'vec3',
|
||||
inputs: [
|
||||
{ name: 'base', type: 'vec3' },
|
||||
{ name: 'blend', type: 'vec3' }
|
||||
]
|
||||
} );
|
||||
|
||||
export const OverlayNode = tslFn( ( { base, blend } ) => {
|
||||
|
||||
const fn = ( c ) => base[ c ].lessThan( 0.5 ).cond( base[ c ].mul( blend[ c ], 2.0 ), base[ c ].oneMinus().mul( blend[ c ].oneMinus() ).oneMinus() );
|
||||
//const fn = ( c ) => mix( base[ c ].oneMinus().mul( blend[ c ].oneMinus() ).oneMinus(), base[ c ].mul( blend[ c ], 2.0 ), step( base[ c ], 0.5 ) );
|
||||
|
||||
return vec3( fn( 'x' ), fn( 'y' ), fn( 'z' ) );
|
||||
|
||||
} ).setLayout( {
|
||||
name: 'overlayColor',
|
||||
type: 'vec3',
|
||||
inputs: [
|
||||
{ name: 'base', type: 'vec3' },
|
||||
{ name: 'blend', type: 'vec3' }
|
||||
]
|
||||
} );
|
||||
|
||||
class BlendModeNode extends TempNode {
|
||||
|
||||
constructor( blendMode, baseNode, blendNode ) {
|
||||
|
||||
super();
|
||||
|
||||
this.blendMode = blendMode;
|
||||
|
||||
this.baseNode = baseNode;
|
||||
this.blendNode = blendNode;
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
const { blendMode, baseNode, blendNode } = this;
|
||||
const params = { base: baseNode, blend: blendNode };
|
||||
|
||||
let outputNode = null;
|
||||
|
||||
if ( blendMode === BlendModeNode.BURN ) {
|
||||
|
||||
outputNode = BurnNode( params );
|
||||
|
||||
} else if ( blendMode === BlendModeNode.DODGE ) {
|
||||
|
||||
outputNode = DodgeNode( params );
|
||||
|
||||
} else if ( blendMode === BlendModeNode.SCREEN ) {
|
||||
|
||||
outputNode = ScreenNode( params );
|
||||
|
||||
} else if ( blendMode === BlendModeNode.OVERLAY ) {
|
||||
|
||||
outputNode = OverlayNode( params );
|
||||
|
||||
}
|
||||
|
||||
return outputNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BlendModeNode.BURN = 'burn';
|
||||
BlendModeNode.DODGE = 'dodge';
|
||||
BlendModeNode.SCREEN = 'screen';
|
||||
BlendModeNode.OVERLAY = 'overlay';
|
||||
|
||||
export default BlendModeNode;
|
||||
|
||||
export const burn = nodeProxy( BlendModeNode, BlendModeNode.BURN );
|
||||
export const dodge = nodeProxy( BlendModeNode, BlendModeNode.DODGE );
|
||||
export const overlay = nodeProxy( BlendModeNode, BlendModeNode.OVERLAY );
|
||||
export const screen = nodeProxy( BlendModeNode, BlendModeNode.SCREEN );
|
||||
|
||||
addNodeElement( 'burn', burn );
|
||||
addNodeElement( 'dodge', dodge );
|
||||
addNodeElement( 'overlay', overlay );
|
||||
addNodeElement( 'screen', screen );
|
||||
|
||||
addNodeClass( 'BlendModeNode', BlendModeNode );
|
80
dist/electron/static/sdk/three/jsm/nodes/display/BumpMapNode.js
vendored
Normal file
80
dist/electron/static/sdk/three/jsm/nodes/display/BumpMapNode.js
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { uv } from '../accessors/UVNode.js';
|
||||
import { normalView } from '../accessors/NormalNode.js';
|
||||
import { positionView } from '../accessors/PositionNode.js';
|
||||
import { faceDirection } from './FrontFacingNode.js';
|
||||
import { addNodeElement, tslFn, nodeProxy, float, vec2 } from '../shadernode/ShaderNode.js';
|
||||
|
||||
// Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen
|
||||
// https://mmikk.github.io/papers3d/mm_sfgrad_bump.pdf
|
||||
|
||||
const dHdxy_fwd = tslFn( ( { textureNode, bumpScale } ) => {
|
||||
|
||||
// It's used to preserve the same TextureNode instance
|
||||
const sampleTexture = ( callback ) => textureNode.cache().context( { getUV: ( texNode ) => callback( texNode.uvNode || uv() ), forceUVContext: true } );
|
||||
|
||||
const Hll = float( sampleTexture( ( uvNode ) => uvNode ) );
|
||||
|
||||
return vec2(
|
||||
float( sampleTexture( ( uvNode ) => uvNode.add( uvNode.dFdx() ) ) ).sub( Hll ),
|
||||
float( sampleTexture( ( uvNode ) => uvNode.add( uvNode.dFdy() ) ) ).sub( Hll )
|
||||
).mul( bumpScale );
|
||||
|
||||
} );
|
||||
|
||||
// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
|
||||
|
||||
const perturbNormalArb = tslFn( ( inputs ) => {
|
||||
|
||||
const { surf_pos, surf_norm, dHdxy } = inputs;
|
||||
|
||||
// normalize is done to ensure that the bump map looks the same regardless of the texture's scale
|
||||
const vSigmaX = surf_pos.dFdx().normalize();
|
||||
const vSigmaY = surf_pos.dFdy().normalize();
|
||||
const vN = surf_norm; // normalized
|
||||
|
||||
const R1 = vSigmaY.cross( vN );
|
||||
const R2 = vN.cross( vSigmaX );
|
||||
|
||||
const fDet = vSigmaX.dot( R1 ).mul( faceDirection );
|
||||
|
||||
const vGrad = fDet.sign().mul( dHdxy.x.mul( R1 ).add( dHdxy.y.mul( R2 ) ) );
|
||||
|
||||
return fDet.abs().mul( surf_norm ).sub( vGrad ).normalize();
|
||||
|
||||
} );
|
||||
|
||||
class BumpMapNode extends TempNode {
|
||||
|
||||
constructor( textureNode, scaleNode = null ) {
|
||||
|
||||
super( 'vec3' );
|
||||
|
||||
this.textureNode = textureNode;
|
||||
this.scaleNode = scaleNode;
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
const bumpScale = this.scaleNode !== null ? this.scaleNode : 1;
|
||||
const dHdxy = dHdxy_fwd( { textureNode: this.textureNode, bumpScale } );
|
||||
|
||||
return perturbNormalArb( {
|
||||
surf_pos: positionView,
|
||||
surf_norm: normalView,
|
||||
dHdxy
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BumpMapNode;
|
||||
|
||||
export const bumpMap = nodeProxy( BumpMapNode );
|
||||
|
||||
addNodeElement( 'bumpMap', bumpMap );
|
||||
|
||||
addNodeClass( 'BumpMapNode', BumpMapNode );
|
99
dist/electron/static/sdk/three/jsm/nodes/display/ColorAdjustmentNode.js
vendored
Normal file
99
dist/electron/static/sdk/three/jsm/nodes/display/ColorAdjustmentNode.js
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { dot, mix } from '../math/MathNode.js';
|
||||
import { add } from '../math/OperatorNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, tslFn, nodeProxy, float, vec3 } from '../shadernode/ShaderNode.js';
|
||||
|
||||
const saturationNode = tslFn( ( { color, adjustment } ) => {
|
||||
|
||||
return adjustment.mix( luminance( color.rgb ), color.rgb );
|
||||
|
||||
} );
|
||||
|
||||
const vibranceNode = tslFn( ( { color, adjustment } ) => {
|
||||
|
||||
const average = add( color.r, color.g, color.b ).div( 3.0 );
|
||||
|
||||
const mx = color.r.max( color.g.max( color.b ) );
|
||||
const amt = mx.sub( average ).mul( adjustment ).mul( - 3.0 );
|
||||
|
||||
return mix( color.rgb, mx, amt );
|
||||
|
||||
} );
|
||||
|
||||
const hueNode = tslFn( ( { color, adjustment } ) => {
|
||||
|
||||
const k = vec3( 0.57735, 0.57735, 0.57735 );
|
||||
|
||||
const cosAngle = adjustment.cos();
|
||||
|
||||
return vec3( color.rgb.mul( cosAngle ).add( k.cross( color.rgb ).mul( adjustment.sin() ).add( k.mul( dot( k, color.rgb ).mul( cosAngle.oneMinus() ) ) ) ) );
|
||||
|
||||
} );
|
||||
|
||||
class ColorAdjustmentNode extends TempNode {
|
||||
|
||||
constructor( method, colorNode, adjustmentNode = float( 1 ) ) {
|
||||
|
||||
super( 'vec3' );
|
||||
|
||||
this.method = method;
|
||||
|
||||
this.colorNode = colorNode;
|
||||
this.adjustmentNode = adjustmentNode;
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
const { method, colorNode, adjustmentNode } = this;
|
||||
|
||||
const callParams = { color: colorNode, adjustment: adjustmentNode };
|
||||
|
||||
let outputNode = null;
|
||||
|
||||
if ( method === ColorAdjustmentNode.SATURATION ) {
|
||||
|
||||
outputNode = saturationNode( callParams );
|
||||
|
||||
} else if ( method === ColorAdjustmentNode.VIBRANCE ) {
|
||||
|
||||
outputNode = vibranceNode( callParams );
|
||||
|
||||
} else if ( method === ColorAdjustmentNode.HUE ) {
|
||||
|
||||
outputNode = hueNode( callParams );
|
||||
|
||||
} else {
|
||||
|
||||
console.error( `${ this.type }: Method "${ this.method }" not supported!` );
|
||||
|
||||
}
|
||||
|
||||
return outputNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ColorAdjustmentNode.SATURATION = 'saturation';
|
||||
ColorAdjustmentNode.VIBRANCE = 'vibrance';
|
||||
ColorAdjustmentNode.HUE = 'hue';
|
||||
|
||||
export default ColorAdjustmentNode;
|
||||
|
||||
export const saturation = nodeProxy( ColorAdjustmentNode, ColorAdjustmentNode.SATURATION );
|
||||
export const vibrance = nodeProxy( ColorAdjustmentNode, ColorAdjustmentNode.VIBRANCE );
|
||||
export const hue = nodeProxy( ColorAdjustmentNode, ColorAdjustmentNode.HUE );
|
||||
|
||||
export const lumaCoeffs = vec3( 0.2125, 0.7154, 0.0721 );
|
||||
export const luminance = ( color, luma = lumaCoeffs ) => dot( color, luma );
|
||||
|
||||
export const threshold = ( color, threshold ) => mix( vec3( 0.0 ), color, luminance( color ).sub( threshold ).max( 0 ) );
|
||||
|
||||
addNodeElement( 'saturation', saturation );
|
||||
addNodeElement( 'vibrance', vibrance );
|
||||
addNodeElement( 'hue', hue );
|
||||
addNodeElement( 'threshold', threshold );
|
||||
|
||||
addNodeClass( 'ColorAdjustmentNode', ColorAdjustmentNode );
|
108
dist/electron/static/sdk/three/jsm/nodes/display/ColorSpaceNode.js
vendored
Normal file
108
dist/electron/static/sdk/three/jsm/nodes/display/ColorSpaceNode.js
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { mix } from '../math/MathNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, tslFn, nodeObject, nodeProxy, vec4 } from '../shadernode/ShaderNode.js';
|
||||
|
||||
import { LinearSRGBColorSpace, SRGBColorSpace } from 'three';
|
||||
|
||||
const sRGBToLinearShader = tslFn( ( inputs ) => {
|
||||
|
||||
const { value } = inputs;
|
||||
const { rgb } = value;
|
||||
|
||||
const a = rgb.mul( 0.9478672986 ).add( 0.0521327014 ).pow( 2.4 );
|
||||
const b = rgb.mul( 0.0773993808 );
|
||||
const factor = rgb.lessThanEqual( 0.04045 );
|
||||
|
||||
const rgbResult = mix( a, b, factor );
|
||||
|
||||
return vec4( rgbResult, value.a );
|
||||
|
||||
} );
|
||||
|
||||
const LinearTosRGBShader = tslFn( ( inputs ) => {
|
||||
|
||||
const { value } = inputs;
|
||||
const { rgb } = value;
|
||||
|
||||
const a = rgb.pow( 0.41666 ).mul( 1.055 ).sub( 0.055 );
|
||||
const b = rgb.mul( 12.92 );
|
||||
const factor = rgb.lessThanEqual( 0.0031308 );
|
||||
|
||||
const rgbResult = mix( a, b, factor );
|
||||
|
||||
return vec4( rgbResult, value.a );
|
||||
|
||||
} );
|
||||
|
||||
const getColorSpaceMethod = ( colorSpace ) => {
|
||||
|
||||
let method = null;
|
||||
|
||||
if ( colorSpace === LinearSRGBColorSpace ) {
|
||||
|
||||
method = 'Linear';
|
||||
|
||||
} else if ( colorSpace === SRGBColorSpace ) {
|
||||
|
||||
method = 'sRGB';
|
||||
|
||||
}
|
||||
|
||||
return method;
|
||||
|
||||
};
|
||||
|
||||
const getMethod = ( source, target ) => {
|
||||
|
||||
return getColorSpaceMethod( source ) + 'To' + getColorSpaceMethod( target );
|
||||
|
||||
};
|
||||
|
||||
class ColorSpaceNode extends TempNode {
|
||||
|
||||
constructor( method, node ) {
|
||||
|
||||
super( 'vec4' );
|
||||
|
||||
this.method = method;
|
||||
this.node = node;
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
const { method, node } = this;
|
||||
|
||||
if ( method === ColorSpaceNode.LINEAR_TO_LINEAR )
|
||||
return node;
|
||||
|
||||
return Methods[ method ]( { value: node } );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ColorSpaceNode.LINEAR_TO_LINEAR = 'LinearToLinear';
|
||||
ColorSpaceNode.LINEAR_TO_sRGB = 'LinearTosRGB';
|
||||
ColorSpaceNode.sRGB_TO_LINEAR = 'sRGBToLinear';
|
||||
|
||||
const Methods = {
|
||||
[ ColorSpaceNode.LINEAR_TO_sRGB ]: LinearTosRGBShader,
|
||||
[ ColorSpaceNode.sRGB_TO_LINEAR ]: sRGBToLinearShader
|
||||
};
|
||||
|
||||
export default ColorSpaceNode;
|
||||
|
||||
export const linearToColorSpace = ( node, colorSpace ) => nodeObject( new ColorSpaceNode( getMethod( LinearSRGBColorSpace, colorSpace ), nodeObject( node ) ) );
|
||||
export const colorSpaceToLinear = ( node, colorSpace ) => nodeObject( new ColorSpaceNode( getMethod( colorSpace, LinearSRGBColorSpace ), nodeObject( node ) ) );
|
||||
|
||||
export const linearTosRGB = nodeProxy( ColorSpaceNode, ColorSpaceNode.LINEAR_TO_sRGB );
|
||||
export const sRGBToLinear = nodeProxy( ColorSpaceNode, ColorSpaceNode.sRGB_TO_LINEAR );
|
||||
|
||||
addNodeElement( 'linearTosRGB', linearTosRGB );
|
||||
addNodeElement( 'sRGBToLinear', sRGBToLinear );
|
||||
addNodeElement( 'linearToColorSpace', linearToColorSpace );
|
||||
addNodeElement( 'colorSpaceToLinear', colorSpaceToLinear );
|
||||
|
||||
addNodeClass( 'ColorSpaceNode', ColorSpaceNode );
|
40
dist/electron/static/sdk/three/jsm/nodes/display/FrontFacingNode.js
vendored
Normal file
40
dist/electron/static/sdk/three/jsm/nodes/display/FrontFacingNode.js
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { nodeImmutable, float } from '../shadernode/ShaderNode.js';
|
||||
import { BackSide, WebGLCoordinateSystem } from 'three';
|
||||
|
||||
class FrontFacingNode extends Node {
|
||||
|
||||
constructor() {
|
||||
|
||||
super( 'bool' );
|
||||
|
||||
this.isFrontFacingNode = true;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const { renderer, material } = builder;
|
||||
|
||||
if ( renderer.coordinateSystem === WebGLCoordinateSystem ) {
|
||||
|
||||
if ( material.side === BackSide ) {
|
||||
|
||||
return 'false';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return builder.getFrontFacing();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default FrontFacingNode;
|
||||
|
||||
export const frontFacing = nodeImmutable( FrontFacingNode );
|
||||
export const faceDirection = float( frontFacing ).mul( 2.0 ).sub( 1.0 );
|
||||
|
||||
addNodeClass( 'FrontFacingNode', FrontFacingNode );
|
190
dist/electron/static/sdk/three/jsm/nodes/display/GaussianBlurNode.js
vendored
Normal file
190
dist/electron/static/sdk/three/jsm/nodes/display/GaussianBlurNode.js
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { nodeObject, addNodeElement, tslFn, float, vec2, vec4 } from '../shadernode/ShaderNode.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { mul } from '../math/OperatorNode.js';
|
||||
import { uv } from '../accessors/UVNode.js';
|
||||
import { texturePass } from './PassNode.js';
|
||||
import { uniform } from '../core/UniformNode.js';
|
||||
import { Vector2, RenderTarget } from 'three';
|
||||
import QuadMesh from '../../objects/QuadMesh.js';
|
||||
|
||||
// WebGPU: The use of a single QuadMesh for both gaussian blur passes results in a single RenderObject with a SampledTexture binding that
|
||||
// alternates between source textures and triggers creation of new BindGroups and BindGroupLayouts every frame.
|
||||
|
||||
const quadMesh1 = new QuadMesh();
|
||||
const quadMesh2 = new QuadMesh();
|
||||
|
||||
class GaussianBlurNode extends TempNode {
|
||||
|
||||
constructor( textureNode, sigma = 2 ) {
|
||||
|
||||
super( 'vec4' );
|
||||
|
||||
this.textureNode = textureNode;
|
||||
this.sigma = sigma;
|
||||
|
||||
this.directionNode = vec2( 1 );
|
||||
|
||||
this._invSize = uniform( new Vector2() );
|
||||
this._passDirection = uniform( new Vector2() );
|
||||
|
||||
this._horizontalRT = new RenderTarget();
|
||||
this._horizontalRT.texture.name = 'GaussianBlurNode.horizontal';
|
||||
this._verticalRT = new RenderTarget();
|
||||
this._verticalRT.texture.name = 'GaussianBlurNode.vertical';
|
||||
|
||||
this._textureNode = texturePass( this, this._verticalRT.texture );
|
||||
|
||||
this.updateBeforeType = NodeUpdateType.RENDER;
|
||||
|
||||
this.resolution = new Vector2( 1, 1 );
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
width = Math.max( Math.round( width * this.resolution.x ), 1 );
|
||||
height = Math.max( Math.round( height * this.resolution.y ), 1 );
|
||||
|
||||
this._invSize.value.set( 1 / width, 1 / height );
|
||||
this._horizontalRT.setSize( width, height );
|
||||
this._verticalRT.setSize( width, height );
|
||||
|
||||
}
|
||||
|
||||
updateBefore( frame ) {
|
||||
|
||||
const { renderer } = frame;
|
||||
|
||||
const textureNode = this.textureNode;
|
||||
const map = textureNode.value;
|
||||
|
||||
const currentRenderTarget = renderer.getRenderTarget();
|
||||
const currentTexture = textureNode.value;
|
||||
|
||||
quadMesh1.material = this._material;
|
||||
quadMesh2.material = this._material;
|
||||
|
||||
this.setSize( map.image.width, map.image.height );
|
||||
|
||||
const textureType = map.type;
|
||||
|
||||
this._horizontalRT.texture.type = textureType;
|
||||
this._verticalRT.texture.type = textureType;
|
||||
|
||||
// horizontal
|
||||
|
||||
renderer.setRenderTarget( this._horizontalRT );
|
||||
|
||||
this._passDirection.value.set( 1, 0 );
|
||||
|
||||
quadMesh1.render( renderer );
|
||||
|
||||
// vertical
|
||||
|
||||
textureNode.value = this._horizontalRT.texture;
|
||||
renderer.setRenderTarget( this._verticalRT );
|
||||
|
||||
this._passDirection.value.set( 0, 1 );
|
||||
|
||||
quadMesh2.render( renderer );
|
||||
|
||||
// restore
|
||||
|
||||
renderer.setRenderTarget( currentRenderTarget );
|
||||
textureNode.value = currentTexture;
|
||||
|
||||
}
|
||||
|
||||
getTextureNode() {
|
||||
|
||||
return this._textureNode;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const textureNode = this.textureNode;
|
||||
|
||||
if ( textureNode.isTextureNode !== true ) {
|
||||
|
||||
console.error( 'GaussianBlurNode requires a TextureNode.' );
|
||||
|
||||
return vec4();
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const uvNode = textureNode.uvNode || uv();
|
||||
|
||||
const sampleTexture = ( uv ) => textureNode.cache().context( { getUV: () => uv, forceUVContext: true } );
|
||||
|
||||
const blur = tslFn( () => {
|
||||
|
||||
const kernelSize = 3 + ( 2 * this.sigma );
|
||||
const gaussianCoefficients = this._getCoefficients( kernelSize );
|
||||
|
||||
const invSize = this._invSize;
|
||||
const direction = vec2( this.directionNode ).mul( this._passDirection );
|
||||
|
||||
const weightSum = float( gaussianCoefficients[ 0 ] ).toVar();
|
||||
const diffuseSum = vec4( sampleTexture( uvNode ).mul( weightSum ) ).toVar();
|
||||
|
||||
for ( let i = 1; i < kernelSize; i ++ ) {
|
||||
|
||||
const x = float( i );
|
||||
const w = float( gaussianCoefficients[ i ] );
|
||||
|
||||
const uvOffset = vec2( direction.mul( invSize.mul( x ) ) ).toVar();
|
||||
|
||||
const sample1 = vec4( sampleTexture( uvNode.add( uvOffset ) ) );
|
||||
const sample2 = vec4( sampleTexture( uvNode.sub( uvOffset ) ) );
|
||||
|
||||
diffuseSum.addAssign( sample1.add( sample2 ).mul( w ) );
|
||||
weightSum.addAssign( mul( 2.0, w ) );
|
||||
|
||||
}
|
||||
|
||||
return diffuseSum.div( weightSum );
|
||||
|
||||
} );
|
||||
|
||||
//
|
||||
|
||||
const material = this._material || ( this._material = builder.createNodeMaterial() );
|
||||
material.fragmentNode = blur();
|
||||
|
||||
//
|
||||
|
||||
const properties = builder.getNodeProperties( this );
|
||||
properties.textureNode = textureNode;
|
||||
|
||||
//
|
||||
|
||||
return this._textureNode;
|
||||
|
||||
}
|
||||
|
||||
_getCoefficients( kernelRadius ) {
|
||||
|
||||
const coefficients = [];
|
||||
|
||||
for ( let i = 0; i < kernelRadius; i ++ ) {
|
||||
|
||||
coefficients.push( 0.39894 * Math.exp( - 0.5 * i * i / ( kernelRadius * kernelRadius ) ) / kernelRadius );
|
||||
|
||||
}
|
||||
|
||||
return coefficients;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const gaussianBlur = ( node, sigma ) => nodeObject( new GaussianBlurNode( nodeObject( node ), sigma ) );
|
||||
|
||||
addNodeElement( 'gaussianBlur', gaussianBlur );
|
||||
|
||||
export default GaussianBlurNode;
|
||||
|
106
dist/electron/static/sdk/three/jsm/nodes/display/NormalMapNode.js
vendored
Normal file
106
dist/electron/static/sdk/three/jsm/nodes/display/NormalMapNode.js
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { add } from '../math/OperatorNode.js';
|
||||
|
||||
import { modelNormalMatrix } from '../accessors/ModelNode.js';
|
||||
import { normalView } from '../accessors/NormalNode.js';
|
||||
import { positionView } from '../accessors/PositionNode.js';
|
||||
import { TBNViewMatrix } from '../accessors/AccessorsUtils.js';
|
||||
import { uv } from '../accessors/UVNode.js';
|
||||
import { faceDirection } from './FrontFacingNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, tslFn, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
|
||||
|
||||
import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from 'three';
|
||||
|
||||
// Normal Mapping Without Precomputed Tangents
|
||||
// http://www.thetenthplanet.de/archives/1180
|
||||
|
||||
const perturbNormal2Arb = tslFn( ( inputs ) => {
|
||||
|
||||
const { eye_pos, surf_norm, mapN, uv } = inputs;
|
||||
|
||||
const q0 = eye_pos.dFdx();
|
||||
const q1 = eye_pos.dFdy();
|
||||
const st0 = uv.dFdx();
|
||||
const st1 = uv.dFdy();
|
||||
|
||||
const N = surf_norm; // normalized
|
||||
|
||||
const q1perp = q1.cross( N );
|
||||
const q0perp = N.cross( q0 );
|
||||
|
||||
const T = q1perp.mul( st0.x ).add( q0perp.mul( st1.x ) );
|
||||
const B = q1perp.mul( st0.y ).add( q0perp.mul( st1.y ) );
|
||||
|
||||
const det = T.dot( T ).max( B.dot( B ) );
|
||||
const scale = faceDirection.mul( det.inverseSqrt() );
|
||||
|
||||
return add( T.mul( mapN.x, scale ), B.mul( mapN.y, scale ), N.mul( mapN.z ) ).normalize();
|
||||
|
||||
} );
|
||||
|
||||
class NormalMapNode extends TempNode {
|
||||
|
||||
constructor( node, scaleNode = null ) {
|
||||
|
||||
super( 'vec3' );
|
||||
|
||||
this.node = node;
|
||||
this.scaleNode = scaleNode;
|
||||
|
||||
this.normalMapType = TangentSpaceNormalMap;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const { normalMapType, scaleNode } = this;
|
||||
|
||||
let normalMap = this.node.mul( 2.0 ).sub( 1.0 );
|
||||
|
||||
if ( scaleNode !== null ) {
|
||||
|
||||
normalMap = vec3( normalMap.xy.mul( scaleNode ), normalMap.z );
|
||||
|
||||
}
|
||||
|
||||
let outputNode = null;
|
||||
|
||||
if ( normalMapType === ObjectSpaceNormalMap ) {
|
||||
|
||||
outputNode = modelNormalMatrix.mul( normalMap ).normalize();
|
||||
|
||||
} else if ( normalMapType === TangentSpaceNormalMap ) {
|
||||
|
||||
const tangent = builder.hasGeometryAttribute( 'tangent' );
|
||||
|
||||
if ( tangent === true ) {
|
||||
|
||||
outputNode = TBNViewMatrix.mul( normalMap ).normalize();
|
||||
|
||||
} else {
|
||||
|
||||
outputNode = perturbNormal2Arb( {
|
||||
eye_pos: positionView,
|
||||
surf_norm: normalView,
|
||||
mapN: normalMap,
|
||||
uv: uv()
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return outputNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NormalMapNode;
|
||||
|
||||
export const normalMap = nodeProxy( NormalMapNode );
|
||||
|
||||
addNodeElement( 'normalMap', normalMap );
|
||||
|
||||
addNodeClass( 'NormalMapNode', NormalMapNode );
|
199
dist/electron/static/sdk/three/jsm/nodes/display/PassNode.js
vendored
Normal file
199
dist/electron/static/sdk/three/jsm/nodes/display/PassNode.js
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import TextureNode from '../accessors/TextureNode.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
import { uniform } from '../core/UniformNode.js';
|
||||
import { viewZToOrthographicDepth, perspectiveDepthToViewZ } from './ViewportDepthNode.js';
|
||||
import { RenderTarget, Vector2, HalfFloatType, DepthTexture, NoToneMapping/*, FloatType*/ } from 'three';
|
||||
|
||||
class PassTextureNode extends TextureNode {
|
||||
|
||||
constructor( passNode, texture ) {
|
||||
|
||||
super( texture );
|
||||
|
||||
this.passNode = passNode;
|
||||
|
||||
this.setUpdateMatrix( false );
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
this.passNode.build( builder );
|
||||
|
||||
return super.setup( builder );
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
return new this.constructor( this.passNode, this.value );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PassNode extends TempNode {
|
||||
|
||||
constructor( scope, scene, camera ) {
|
||||
|
||||
super( 'vec4' );
|
||||
|
||||
this.scope = scope;
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
|
||||
this._pixelRatio = 1;
|
||||
this._width = 1;
|
||||
this._height = 1;
|
||||
|
||||
const depthTexture = new DepthTexture();
|
||||
depthTexture.isRenderTargetTexture = true;
|
||||
//depthTexture.type = FloatType;
|
||||
depthTexture.name = 'PostProcessingDepth';
|
||||
|
||||
const renderTarget = new RenderTarget( this._width * this._pixelRatio, this._height * this._pixelRatio, { type: HalfFloatType } );
|
||||
renderTarget.texture.name = 'PostProcessing';
|
||||
renderTarget.depthTexture = depthTexture;
|
||||
|
||||
this.renderTarget = renderTarget;
|
||||
|
||||
this.updateBeforeType = NodeUpdateType.FRAME;
|
||||
|
||||
this._textureNode = nodeObject( new PassTextureNode( this, renderTarget.texture ) );
|
||||
this._depthTextureNode = nodeObject( new PassTextureNode( this, depthTexture ) );
|
||||
|
||||
this._depthNode = null;
|
||||
this._viewZNode = null;
|
||||
this._cameraNear = uniform( 0 );
|
||||
this._cameraFar = uniform( 0 );
|
||||
|
||||
this.isPassNode = true;
|
||||
|
||||
}
|
||||
|
||||
isGlobal() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
getTextureNode() {
|
||||
|
||||
return this._textureNode;
|
||||
|
||||
}
|
||||
|
||||
getTextureDepthNode() {
|
||||
|
||||
return this._depthTextureNode;
|
||||
|
||||
}
|
||||
|
||||
getViewZNode() {
|
||||
|
||||
if ( this._viewZNode === null ) {
|
||||
|
||||
const cameraNear = this._cameraNear;
|
||||
const cameraFar = this._cameraFar;
|
||||
|
||||
this._viewZNode = perspectiveDepthToViewZ( this._depthTextureNode, cameraNear, cameraFar );
|
||||
|
||||
}
|
||||
|
||||
return this._viewZNode;
|
||||
|
||||
}
|
||||
|
||||
getDepthNode() {
|
||||
|
||||
if ( this._depthNode === null ) {
|
||||
|
||||
const cameraNear = this._cameraNear;
|
||||
const cameraFar = this._cameraFar;
|
||||
|
||||
this._depthNode = viewZToOrthographicDepth( this.getViewZNode(), cameraNear, cameraFar );
|
||||
|
||||
}
|
||||
|
||||
return this._depthNode;
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
return this.scope === PassNode.COLOR ? this.getTextureNode() : this.getDepthNode();
|
||||
|
||||
}
|
||||
|
||||
updateBefore( frame ) {
|
||||
|
||||
const { renderer } = frame;
|
||||
const { scene, camera } = this;
|
||||
|
||||
this._pixelRatio = renderer.getPixelRatio();
|
||||
|
||||
const size = renderer.getSize( new Vector2() );
|
||||
|
||||
this.setSize( size.width, size.height );
|
||||
|
||||
const currentToneMapping = renderer.toneMapping;
|
||||
const currentToneMappingNode = renderer.toneMappingNode;
|
||||
const currentRenderTarget = renderer.getRenderTarget();
|
||||
|
||||
this._cameraNear.value = camera.near;
|
||||
this._cameraFar.value = camera.far;
|
||||
|
||||
renderer.toneMapping = NoToneMapping;
|
||||
renderer.toneMappingNode = null;
|
||||
renderer.setRenderTarget( this.renderTarget );
|
||||
|
||||
renderer.render( scene, camera );
|
||||
|
||||
renderer.toneMapping = currentToneMapping;
|
||||
renderer.toneMappingNode = currentToneMappingNode;
|
||||
renderer.setRenderTarget( currentRenderTarget );
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height ) {
|
||||
|
||||
this._width = width;
|
||||
this._height = height;
|
||||
|
||||
const effectiveWidth = this._width * this._pixelRatio;
|
||||
const effectiveHeight = this._height * this._pixelRatio;
|
||||
|
||||
this.renderTarget.setSize( effectiveWidth, effectiveHeight );
|
||||
|
||||
}
|
||||
|
||||
setPixelRatio( pixelRatio ) {
|
||||
|
||||
this._pixelRatio = pixelRatio;
|
||||
|
||||
this.setSize( this._width, this._height );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.renderTarget.dispose();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
PassNode.COLOR = 'color';
|
||||
PassNode.DEPTH = 'depth';
|
||||
|
||||
export default PassNode;
|
||||
|
||||
export const pass = ( scene, camera ) => nodeObject( new PassNode( PassNode.COLOR, scene, camera ) );
|
||||
export const texturePass = ( pass, texture ) => nodeObject( new PassTextureNode( pass, texture ) );
|
||||
export const depthPass = ( scene, camera ) => nodeObject( new PassNode( PassNode.DEPTH, scene, camera ) );
|
||||
|
||||
addNodeClass( 'PassNode', PassNode );
|
32
dist/electron/static/sdk/three/jsm/nodes/display/PosterizeNode.js
vendored
Normal file
32
dist/electron/static/sdk/three/jsm/nodes/display/PosterizeNode.js
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class PosterizeNode extends TempNode {
|
||||
|
||||
constructor( sourceNode, stepsNode ) {
|
||||
|
||||
super();
|
||||
|
||||
this.sourceNode = sourceNode;
|
||||
this.stepsNode = stepsNode;
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
const { sourceNode, stepsNode } = this;
|
||||
|
||||
return sourceNode.mul( stepsNode ).floor().div( stepsNode );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default PosterizeNode;
|
||||
|
||||
export const posterize = nodeProxy( PosterizeNode );
|
||||
|
||||
addNodeElement( 'posterize', posterize );
|
||||
|
||||
addNodeClass( 'PosterizeNode', PosterizeNode );
|
188
dist/electron/static/sdk/three/jsm/nodes/display/ToneMappingNode.js
vendored
Normal file
188
dist/electron/static/sdk/three/jsm/nodes/display/ToneMappingNode.js
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, tslFn, nodeObject, float, mat3, vec3 } from '../shadernode/ShaderNode.js';
|
||||
import { rendererReference } from '../accessors/RendererReferenceNode.js';
|
||||
import { clamp, log2, max, pow } from '../math/MathNode.js';
|
||||
import { mul } from '../math/OperatorNode.js';
|
||||
|
||||
import { NoToneMapping, LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping, AgXToneMapping } from 'three';
|
||||
|
||||
// exposure only
|
||||
const LinearToneMappingNode = tslFn( ( { color, exposure } ) => {
|
||||
|
||||
return color.mul( exposure ).clamp();
|
||||
|
||||
} );
|
||||
|
||||
// source: https://www.cs.utah.edu/docs/techreports/2002/pdf/UUCS-02-001.pdf
|
||||
const ReinhardToneMappingNode = tslFn( ( { color, exposure } ) => {
|
||||
|
||||
color = color.mul( exposure );
|
||||
|
||||
return color.div( color.add( 1.0 ) ).clamp();
|
||||
|
||||
} );
|
||||
|
||||
// source: http://filmicworlds.com/blog/filmic-tonemapping-operators/
|
||||
const OptimizedCineonToneMappingNode = tslFn( ( { color, exposure } ) => {
|
||||
|
||||
// optimized filmic operator by Jim Hejl and Richard Burgess-Dawson
|
||||
color = color.mul( exposure );
|
||||
color = color.sub( 0.004 ).max( 0.0 );
|
||||
|
||||
const a = color.mul( color.mul( 6.2 ).add( 0.5 ) );
|
||||
const b = color.mul( color.mul( 6.2 ).add( 1.7 ) ).add( 0.06 );
|
||||
|
||||
return a.div( b ).pow( 2.2 );
|
||||
|
||||
} );
|
||||
|
||||
// source: https://github.com/selfshadow/ltc_code/blob/master/webgl/shaders/ltc/ltc_blit.fs
|
||||
const RRTAndODTFit = tslFn( ( { color } ) => {
|
||||
|
||||
const a = color.mul( color.add( 0.0245786 ) ).sub( 0.000090537 );
|
||||
const b = color.mul( color.add( 0.4329510 ).mul( 0.983729 ) ).add( 0.238081 );
|
||||
|
||||
return a.div( b );
|
||||
|
||||
} );
|
||||
|
||||
// source: https://github.com/selfshadow/ltc_code/blob/master/webgl/shaders/ltc/ltc_blit.fs
|
||||
const ACESFilmicToneMappingNode = tslFn( ( { color, exposure } ) => {
|
||||
|
||||
// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
|
||||
const ACESInputMat = mat3(
|
||||
0.59719, 0.35458, 0.04823,
|
||||
0.07600, 0.90834, 0.01566,
|
||||
0.02840, 0.13383, 0.83777
|
||||
);
|
||||
|
||||
// ODT_SAT => XYZ => D60_2_D65 => sRGB
|
||||
const ACESOutputMat = mat3(
|
||||
1.60475, - 0.53108, - 0.07367,
|
||||
- 0.10208, 1.10813, - 0.00605,
|
||||
- 0.00327, - 0.07276, 1.07602
|
||||
);
|
||||
|
||||
color = color.mul( exposure ).div( 0.6 );
|
||||
|
||||
color = ACESInputMat.mul( color );
|
||||
|
||||
// Apply RRT and ODT
|
||||
color = RRTAndODTFit( { color } );
|
||||
|
||||
color = ACESOutputMat.mul( color );
|
||||
|
||||
// Clamp to [0, 1]
|
||||
return color.clamp();
|
||||
|
||||
} );
|
||||
|
||||
|
||||
|
||||
const LINEAR_REC2020_TO_LINEAR_SRGB = mat3( vec3( 1.6605, - 0.1246, - 0.0182 ), vec3( - 0.5876, 1.1329, - 0.1006 ), vec3( - 0.0728, - 0.0083, 1.1187 ) );
|
||||
const LINEAR_SRGB_TO_LINEAR_REC2020 = mat3( vec3( 0.6274, 0.0691, 0.0164 ), vec3( 0.3293, 0.9195, 0.0880 ), vec3( 0.0433, 0.0113, 0.8956 ) );
|
||||
|
||||
const agxDefaultContrastApprox = tslFn( ( [ x_immutable ] ) => {
|
||||
|
||||
const x = vec3( x_immutable ).toVar();
|
||||
const x2 = vec3( x.mul( x ) ).toVar();
|
||||
const x4 = vec3( x2.mul( x2 ) ).toVar();
|
||||
|
||||
return float( 15.5 ).mul( x4.mul( x2 ) ).sub( mul( 40.14, x4.mul( x ) ) ).add( mul( 31.96, x4 ).sub( mul( 6.868, x2.mul( x ) ) ).add( mul( 0.4298, x2 ).add( mul( 0.1191, x ).sub( 0.00232 ) ) ) );
|
||||
|
||||
} );
|
||||
|
||||
const AGXToneMappingNode = tslFn( ( { color, exposure } ) => {
|
||||
|
||||
const colortone = vec3( color ).toVar();
|
||||
const AgXInsetMatrix = mat3( vec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ), vec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ), vec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 ) );
|
||||
const AgXOutsetMatrix = mat3( vec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ), vec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ), vec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 ) );
|
||||
const AgxMinEv = float( - 12.47393 );
|
||||
const AgxMaxEv = float( 4.026069 );
|
||||
colortone.mulAssign( exposure );
|
||||
colortone.assign( LINEAR_SRGB_TO_LINEAR_REC2020.mul( colortone ) );
|
||||
colortone.assign( AgXInsetMatrix.mul( colortone ) );
|
||||
colortone.assign( max( colortone, 1e-10 ) );
|
||||
colortone.assign( log2( colortone ) );
|
||||
colortone.assign( colortone.sub( AgxMinEv ).div( AgxMaxEv.sub( AgxMinEv ) ) );
|
||||
colortone.assign( clamp( colortone, 0.0, 1.0 ) );
|
||||
colortone.assign( agxDefaultContrastApprox( colortone ) );
|
||||
colortone.assign( AgXOutsetMatrix.mul( colortone ) );
|
||||
colortone.assign( pow( max( vec3( 0.0 ), colortone ), vec3( 2.2 ) ) );
|
||||
colortone.assign( LINEAR_REC2020_TO_LINEAR_SRGB.mul( colortone ) );
|
||||
colortone.assign( clamp( colortone, 0.0, 1.0 ) );
|
||||
|
||||
return colortone;
|
||||
|
||||
} );
|
||||
|
||||
|
||||
const toneMappingLib = {
|
||||
[ LinearToneMapping ]: LinearToneMappingNode,
|
||||
[ ReinhardToneMapping ]: ReinhardToneMappingNode,
|
||||
[ CineonToneMapping ]: OptimizedCineonToneMappingNode,
|
||||
[ ACESFilmicToneMapping ]: ACESFilmicToneMappingNode,
|
||||
[ AgXToneMapping ]: AGXToneMappingNode
|
||||
};
|
||||
|
||||
class ToneMappingNode extends TempNode {
|
||||
|
||||
constructor( toneMapping = NoToneMapping, exposureNode = toneMappingExposure, colorNode = null ) {
|
||||
|
||||
super( 'vec3' );
|
||||
|
||||
this.toneMapping = toneMapping;
|
||||
|
||||
this.exposureNode = exposureNode;
|
||||
this.colorNode = colorNode;
|
||||
|
||||
}
|
||||
|
||||
getCacheKey() {
|
||||
|
||||
let cacheKey = super.getCacheKey();
|
||||
cacheKey = '{toneMapping:' + this.toneMapping + ',nodes:' + cacheKey + '}';
|
||||
|
||||
return cacheKey;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const colorNode = this.colorNode || builder.context.color;
|
||||
const toneMapping = this.toneMapping;
|
||||
|
||||
if ( toneMapping === NoToneMapping ) return colorNode;
|
||||
|
||||
const toneMappingParams = { exposure: this.exposureNode, color: colorNode };
|
||||
const toneMappingNode = toneMappingLib[ toneMapping ];
|
||||
|
||||
let outputNode = null;
|
||||
|
||||
if ( toneMappingNode ) {
|
||||
|
||||
outputNode = toneMappingNode( toneMappingParams );
|
||||
|
||||
} else {
|
||||
|
||||
console.error( 'ToneMappingNode: Unsupported Tone Mapping configuration.', toneMapping );
|
||||
|
||||
outputNode = colorNode;
|
||||
|
||||
}
|
||||
|
||||
return outputNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ToneMappingNode;
|
||||
|
||||
export const toneMapping = ( mapping, exposure, color ) => nodeObject( new ToneMappingNode( mapping, nodeObject( exposure ), nodeObject( color ) ) );
|
||||
export const toneMappingExposure = rendererReference( 'toneMappingExposure', 'float' );
|
||||
|
||||
addNodeElement( 'toneMapping', ( color, mapping, exposure ) => toneMapping( mapping, exposure, color ) );
|
||||
|
||||
addNodeClass( 'ToneMappingNode', ToneMappingNode );
|
97
dist/electron/static/sdk/three/jsm/nodes/display/ViewportDepthNode.js
vendored
Normal file
97
dist/electron/static/sdk/three/jsm/nodes/display/ViewportDepthNode.js
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { nodeImmutable, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
import { cameraNear, cameraFar } from '../accessors/CameraNode.js';
|
||||
import { positionView } from '../accessors/PositionNode.js';
|
||||
import { viewportDepthTexture } from './ViewportDepthTextureNode.js';
|
||||
|
||||
class ViewportDepthNode extends Node {
|
||||
|
||||
constructor( scope, valueNode = null ) {
|
||||
|
||||
super( 'float' );
|
||||
|
||||
this.scope = scope;
|
||||
this.valueNode = valueNode;
|
||||
|
||||
this.isViewportDepthNode = true;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const { scope } = this;
|
||||
|
||||
if ( scope === ViewportDepthNode.DEPTH_PIXEL ) {
|
||||
|
||||
return builder.getFragDepth();
|
||||
|
||||
}
|
||||
|
||||
return super.generate( builder );
|
||||
|
||||
}
|
||||
|
||||
setup( /*builder*/ ) {
|
||||
|
||||
const { scope } = this;
|
||||
|
||||
let node = null;
|
||||
|
||||
if ( scope === ViewportDepthNode.DEPTH ) {
|
||||
|
||||
node = viewZToOrthographicDepth( positionView.z, cameraNear, cameraFar );
|
||||
|
||||
} else if ( scope === ViewportDepthNode.DEPTH_TEXTURE ) {
|
||||
|
||||
const texture = this.valueNode || viewportDepthTexture();
|
||||
|
||||
const viewZ = perspectiveDepthToViewZ( texture, cameraNear, cameraFar );
|
||||
node = viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
|
||||
|
||||
} else if ( scope === ViewportDepthNode.DEPTH_PIXEL ) {
|
||||
|
||||
if ( this.valueNode !== null ) {
|
||||
|
||||
node = depthPixelBase().assign( this.valueNode );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// NOTE: viewZ, the z-coordinate in camera space, is negative for points in front of the camera
|
||||
|
||||
// -near maps to 0; -far maps to 1
|
||||
export const viewZToOrthographicDepth = ( viewZ, near, far ) => viewZ.add( near ).div( near.sub( far ) );
|
||||
|
||||
// maps orthographic depth in [ 0, 1 ] to viewZ
|
||||
export const orthographicDepthToViewZ = ( depth, near, far ) => near.sub( far ).mul( depth ).sub( near );
|
||||
|
||||
// NOTE: https://twitter.com/gonnavis/status/1377183786949959682
|
||||
|
||||
// -near maps to 0; -far maps to 1
|
||||
export const viewZToPerspectiveDepth = ( viewZ, near, far ) => near.add( viewZ ).mul( far ).div( far.sub( near ).mul( viewZ ) );
|
||||
|
||||
// maps perspective depth in [ 0, 1 ] to viewZ
|
||||
export const perspectiveDepthToViewZ = ( depth, near, far ) => near.mul( far ).div( far.sub( near ).mul( depth ).sub( far ) );
|
||||
|
||||
ViewportDepthNode.DEPTH = 'depth';
|
||||
ViewportDepthNode.DEPTH_TEXTURE = 'depthTexture';
|
||||
ViewportDepthNode.DEPTH_PIXEL = 'depthPixel';
|
||||
|
||||
export default ViewportDepthNode;
|
||||
|
||||
const depthPixelBase = nodeProxy( ViewportDepthNode, ViewportDepthNode.DEPTH_PIXEL );
|
||||
|
||||
export const depth = nodeImmutable( ViewportDepthNode, ViewportDepthNode.DEPTH );
|
||||
export const depthTexture = nodeProxy( ViewportDepthNode, ViewportDepthNode.DEPTH_TEXTURE );
|
||||
export const depthPixel = nodeImmutable( ViewportDepthNode, ViewportDepthNode.DEPTH_PIXEL );
|
||||
|
||||
depthPixel.assign = ( value ) => depthPixelBase( value );
|
||||
|
||||
addNodeClass( 'ViewportDepthNode', ViewportDepthNode );
|
31
dist/electron/static/sdk/three/jsm/nodes/display/ViewportDepthTextureNode.js
vendored
Normal file
31
dist/electron/static/sdk/three/jsm/nodes/display/ViewportDepthTextureNode.js
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
import ViewportTextureNode from './ViewportTextureNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
import { viewportTopLeft } from './ViewportNode.js';
|
||||
import { DepthTexture } from 'three';
|
||||
|
||||
let sharedDepthbuffer = null;
|
||||
|
||||
class ViewportDepthTextureNode extends ViewportTextureNode {
|
||||
|
||||
constructor( uvNode = viewportTopLeft, levelNode = null ) {
|
||||
|
||||
if ( sharedDepthbuffer === null ) {
|
||||
|
||||
sharedDepthbuffer = new DepthTexture();
|
||||
|
||||
}
|
||||
|
||||
super( uvNode, levelNode, sharedDepthbuffer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ViewportDepthTextureNode;
|
||||
|
||||
export const viewportDepthTexture = nodeProxy( ViewportDepthTextureNode );
|
||||
|
||||
addNodeElement( 'viewportDepthTexture', viewportDepthTexture );
|
||||
|
||||
addNodeClass( 'ViewportDepthTextureNode', ViewportDepthTextureNode );
|
136
dist/electron/static/sdk/three/jsm/nodes/display/ViewportNode.js
vendored
Normal file
136
dist/electron/static/sdk/three/jsm/nodes/display/ViewportNode.js
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { uniform } from '../core/UniformNode.js';
|
||||
import { nodeImmutable, vec2 } from '../shadernode/ShaderNode.js';
|
||||
|
||||
import { Vector2, Vector4 } from 'three';
|
||||
|
||||
let resolution, viewportResult;
|
||||
|
||||
class ViewportNode extends Node {
|
||||
|
||||
constructor( scope ) {
|
||||
|
||||
super();
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
this.isViewportNode = true;
|
||||
|
||||
}
|
||||
|
||||
getNodeType() {
|
||||
|
||||
if ( this.scope === ViewportNode.VIEWPORT ) return 'vec4';
|
||||
else if ( this.scope === ViewportNode.COORDINATE ) return 'vec3';
|
||||
else return 'vec2';
|
||||
|
||||
}
|
||||
|
||||
getUpdateType() {
|
||||
|
||||
let updateType = NodeUpdateType.NONE;
|
||||
|
||||
if ( this.scope === ViewportNode.RESOLUTION || this.scope === ViewportNode.VIEWPORT ) {
|
||||
|
||||
updateType = NodeUpdateType.FRAME;
|
||||
|
||||
}
|
||||
|
||||
this.updateType = updateType;
|
||||
|
||||
return updateType;
|
||||
|
||||
}
|
||||
|
||||
update( { renderer } ) {
|
||||
|
||||
if ( this.scope === ViewportNode.VIEWPORT ) {
|
||||
|
||||
renderer.getViewport( viewportResult );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.getDrawingBufferSize( resolution );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setup( /*builder*/ ) {
|
||||
|
||||
const scope = this.scope;
|
||||
|
||||
let output = null;
|
||||
|
||||
if ( scope === ViewportNode.RESOLUTION ) {
|
||||
|
||||
output = uniform( resolution || ( resolution = new Vector2() ) );
|
||||
|
||||
} else if ( scope === ViewportNode.VIEWPORT ) {
|
||||
|
||||
output = uniform( viewportResult || ( viewportResult = new Vector4() ) );
|
||||
|
||||
} else {
|
||||
|
||||
output = viewportCoordinate.div( viewportResolution );
|
||||
|
||||
let outX = output.x;
|
||||
let outY = output.y;
|
||||
|
||||
if ( /bottom/i.test( scope ) ) outY = outY.oneMinus();
|
||||
if ( /right/i.test( scope ) ) outX = outX.oneMinus();
|
||||
|
||||
output = vec2( outX, outY );
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
if ( this.scope === ViewportNode.COORDINATE ) {
|
||||
|
||||
let coord = builder.getFragCoord();
|
||||
|
||||
if ( builder.isFlipY() ) {
|
||||
|
||||
// follow webgpu standards
|
||||
|
||||
const resolution = builder.getNodeProperties( viewportResolution ).outputNode.build( builder );
|
||||
|
||||
coord = `${ builder.getType( 'vec3' ) }( ${ coord }.x, ${ resolution }.y - ${ coord }.y, ${ coord }.z )`;
|
||||
|
||||
}
|
||||
|
||||
return coord;
|
||||
|
||||
}
|
||||
|
||||
return super.generate( builder );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ViewportNode.COORDINATE = 'coordinate';
|
||||
ViewportNode.RESOLUTION = 'resolution';
|
||||
ViewportNode.VIEWPORT = 'viewport';
|
||||
ViewportNode.TOP_LEFT = 'topLeft';
|
||||
ViewportNode.BOTTOM_LEFT = 'bottomLeft';
|
||||
ViewportNode.TOP_RIGHT = 'topRight';
|
||||
ViewportNode.BOTTOM_RIGHT = 'bottomRight';
|
||||
|
||||
export default ViewportNode;
|
||||
|
||||
export const viewportCoordinate = nodeImmutable( ViewportNode, ViewportNode.COORDINATE );
|
||||
export const viewportResolution = nodeImmutable( ViewportNode, ViewportNode.RESOLUTION );
|
||||
export const viewport = nodeImmutable( ViewportNode, ViewportNode.VIEWPORT );
|
||||
export const viewportTopLeft = nodeImmutable( ViewportNode, ViewportNode.TOP_LEFT );
|
||||
export const viewportBottomLeft = nodeImmutable( ViewportNode, ViewportNode.BOTTOM_LEFT );
|
||||
export const viewportTopRight = nodeImmutable( ViewportNode, ViewportNode.TOP_RIGHT );
|
||||
export const viewportBottomRight = nodeImmutable( ViewportNode, ViewportNode.BOTTOM_RIGHT );
|
||||
|
||||
addNodeClass( 'ViewportNode', ViewportNode );
|
37
dist/electron/static/sdk/three/jsm/nodes/display/ViewportSharedTextureNode.js
vendored
Normal file
37
dist/electron/static/sdk/three/jsm/nodes/display/ViewportSharedTextureNode.js
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
import ViewportTextureNode from './ViewportTextureNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
import { viewportTopLeft } from './ViewportNode.js';
|
||||
import { FramebufferTexture } from 'three';
|
||||
|
||||
let _sharedFramebuffer = null;
|
||||
|
||||
class ViewportSharedTextureNode extends ViewportTextureNode {
|
||||
|
||||
constructor( uvNode = viewportTopLeft, levelNode = null ) {
|
||||
|
||||
if ( _sharedFramebuffer === null ) {
|
||||
|
||||
_sharedFramebuffer = new FramebufferTexture();
|
||||
|
||||
}
|
||||
|
||||
super( uvNode, levelNode, _sharedFramebuffer );
|
||||
|
||||
}
|
||||
|
||||
updateReference() {
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ViewportSharedTextureNode;
|
||||
|
||||
export const viewportSharedTexture = nodeProxy( ViewportSharedTextureNode );
|
||||
|
||||
addNodeElement( 'viewportSharedTexture', viewportSharedTexture );
|
||||
|
||||
addNodeClass( 'ViewportSharedTextureNode', ViewportSharedTextureNode );
|
78
dist/electron/static/sdk/three/jsm/nodes/display/ViewportTextureNode.js
vendored
Normal file
78
dist/electron/static/sdk/three/jsm/nodes/display/ViewportTextureNode.js
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
import TextureNode from '../accessors/TextureNode.js';
|
||||
import { NodeUpdateType } from '../core/constants.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
import { viewportTopLeft } from './ViewportNode.js';
|
||||
import { Vector2, FramebufferTexture, LinearMipmapLinearFilter } from 'three';
|
||||
|
||||
const _size = new Vector2();
|
||||
|
||||
class ViewportTextureNode extends TextureNode {
|
||||
|
||||
constructor( uvNode = viewportTopLeft, levelNode = null, framebufferTexture = null ) {
|
||||
|
||||
if ( framebufferTexture === null ) {
|
||||
|
||||
framebufferTexture = new FramebufferTexture();
|
||||
framebufferTexture.minFilter = LinearMipmapLinearFilter;
|
||||
|
||||
}
|
||||
|
||||
super( framebufferTexture, uvNode, levelNode );
|
||||
|
||||
this.generateMipmaps = false;
|
||||
|
||||
this.isOutputTextureNode = true;
|
||||
|
||||
this.updateBeforeType = NodeUpdateType.FRAME;
|
||||
|
||||
}
|
||||
|
||||
updateBefore( frame ) {
|
||||
|
||||
const renderer = frame.renderer;
|
||||
renderer.getDrawingBufferSize( _size );
|
||||
|
||||
//
|
||||
|
||||
const framebufferTexture = this.value;
|
||||
|
||||
if ( framebufferTexture.image.width !== _size.width || framebufferTexture.image.height !== _size.height ) {
|
||||
|
||||
framebufferTexture.image.width = _size.width;
|
||||
framebufferTexture.image.height = _size.height;
|
||||
framebufferTexture.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const currentGenerateMipmaps = framebufferTexture.generateMipmaps;
|
||||
framebufferTexture.generateMipmaps = this.generateMipmaps;
|
||||
|
||||
renderer.copyFramebufferToTexture( framebufferTexture );
|
||||
|
||||
framebufferTexture.generateMipmaps = currentGenerateMipmaps;
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
const viewportTextureNode = new this.constructor( this.uvNode, this.levelNode, this.value );
|
||||
viewportTextureNode.generateMipmaps = this.generateMipmaps;
|
||||
|
||||
return viewportTextureNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ViewportTextureNode;
|
||||
|
||||
export const viewportTexture = nodeProxy( ViewportTextureNode );
|
||||
export const viewportMipTexture = nodeProxy( ViewportTextureNode, null, null, { generateMipmaps: true } );
|
||||
|
||||
addNodeElement( 'viewportTexture', viewportTexture );
|
||||
addNodeElement( 'viewportMipTexture', viewportMipTexture );
|
||||
|
||||
addNodeClass( 'ViewportTextureNode', ViewportTextureNode );
|
34
dist/electron/static/sdk/three/jsm/nodes/fog/FogExp2Node.js
vendored
Normal file
34
dist/electron/static/sdk/three/jsm/nodes/fog/FogExp2Node.js
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
import FogNode from './FogNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class FogExp2Node extends FogNode {
|
||||
|
||||
constructor( colorNode, densityNode ) {
|
||||
|
||||
super( colorNode );
|
||||
|
||||
this.isFogExp2Node = true;
|
||||
|
||||
this.densityNode = densityNode;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const viewZ = this.getViewZNode( builder );
|
||||
const density = this.densityNode;
|
||||
|
||||
return density.mul( density, viewZ, viewZ ).negate().exp().oneMinus();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default FogExp2Node;
|
||||
|
||||
export const densityFog = nodeProxy( FogExp2Node );
|
||||
|
||||
addNodeElement( 'densityFog', densityFog );
|
||||
|
||||
addNodeClass( 'FogExp2Node', FogExp2Node );
|
48
dist/electron/static/sdk/three/jsm/nodes/fog/FogNode.js
vendored
Normal file
48
dist/electron/static/sdk/three/jsm/nodes/fog/FogNode.js
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
import Node, { addNodeClass } from '../core/Node.js';
|
||||
import { positionView } from '../accessors/PositionNode.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class FogNode extends Node {
|
||||
|
||||
constructor( colorNode, factorNode ) {
|
||||
|
||||
super( 'float' );
|
||||
|
||||
this.isFogNode = true;
|
||||
|
||||
this.colorNode = colorNode;
|
||||
this.factorNode = factorNode;
|
||||
|
||||
}
|
||||
|
||||
getViewZNode( builder ) {
|
||||
|
||||
let viewZ;
|
||||
|
||||
const getViewZ = builder.context.getViewZ;
|
||||
|
||||
if ( getViewZ !== undefined ) {
|
||||
|
||||
viewZ = getViewZ( this );
|
||||
|
||||
}
|
||||
|
||||
return ( viewZ || positionView.z ).negate();
|
||||
|
||||
}
|
||||
|
||||
setup() {
|
||||
|
||||
return this.factorNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default FogNode;
|
||||
|
||||
export const fog = nodeProxy( FogNode );
|
||||
|
||||
addNodeElement( 'fog', fog );
|
||||
|
||||
addNodeClass( 'FogNode', FogNode );
|
35
dist/electron/static/sdk/three/jsm/nodes/fog/FogRangeNode.js
vendored
Normal file
35
dist/electron/static/sdk/three/jsm/nodes/fog/FogRangeNode.js
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
import FogNode from './FogNode.js';
|
||||
import { smoothstep } from '../math/MathNode.js';
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class FogRangeNode extends FogNode {
|
||||
|
||||
constructor( colorNode, nearNode, farNode ) {
|
||||
|
||||
super( colorNode );
|
||||
|
||||
this.isFogRangeNode = true;
|
||||
|
||||
this.nearNode = nearNode;
|
||||
this.farNode = farNode;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const viewZ = this.getViewZNode( builder );
|
||||
|
||||
return smoothstep( this.nearNode, this.farNode, viewZ );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default FogRangeNode;
|
||||
|
||||
export const rangeFog = nodeProxy( FogRangeNode );
|
||||
|
||||
addNodeElement( 'rangeFog', rangeFog );
|
||||
|
||||
addNodeClass( 'FogRangeNode', FogRangeNode );
|
59
dist/electron/static/sdk/three/jsm/nodes/functions/BSDF/BRDF_GGX.js
vendored
Normal file
59
dist/electron/static/sdk/three/jsm/nodes/functions/BSDF/BRDF_GGX.js
vendored
Normal 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;
|
9
dist/electron/static/sdk/three/jsm/nodes/functions/BSDF/BRDF_Lambert.js
vendored
Normal file
9
dist/electron/static/sdk/three/jsm/nodes/functions/BSDF/BRDF_Lambert.js
vendored
Normal 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;
|
57
dist/electron/static/sdk/three/jsm/nodes/functions/BSDF/BRDF_Sheen.js
vendored
Normal file
57
dist/electron/static/sdk/three/jsm/nodes/functions/BSDF/BRDF_Sheen.js
vendored
Normal 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;
|
30
dist/electron/static/sdk/three/jsm/nodes/functions/BSDF/DFGApprox.js
vendored
Normal file
30
dist/electron/static/sdk/three/jsm/nodes/functions/BSDF/DFGApprox.js
vendored
Normal 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;
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user