diff --git a/examples/files.json b/examples/files.json index 14a8ae11c2209e..241a529bdd6e61 100644 --- a/examples/files.json +++ b/examples/files.json @@ -344,6 +344,7 @@ "webgpu_materials", "webgpu_materials_displacementmap", "webgpu_materials_lightmap", + "webgpu_materials_matcap", "webgpu_materials_sss", "webgpu_materials_transmission", "webgpu_materials_video", diff --git a/examples/jsm/nodes/materials/Materials.js b/examples/jsm/nodes/materials/Materials.js index 2577ca75eb36b2..62a57c36e7a985 100644 --- a/examples/jsm/nodes/materials/Materials.js +++ b/examples/jsm/nodes/materials/Materials.js @@ -12,6 +12,7 @@ export { default as MeshPhongNodeMaterial } from './MeshPhongNodeMaterial.js'; export { default as MeshStandardNodeMaterial } from './MeshStandardNodeMaterial.js'; export { default as MeshPhysicalNodeMaterial } from './MeshPhysicalNodeMaterial.js'; export { default as MeshSSSNodeMaterial } from './MeshSSSNodeMaterial.js'; +export { default as MeshMatcapNodeMaterial } from './MeshMatcapNodeMaterial.js'; export { default as PointsNodeMaterial } from './PointsNodeMaterial.js'; export { default as SpriteNodeMaterial } from './SpriteNodeMaterial.js'; export { default as ShadowNodeMaterial } from './ShadowNodeMaterial.js'; diff --git a/examples/jsm/nodes/materials/MeshMatcapNodeMaterial.js b/examples/jsm/nodes/materials/MeshMatcapNodeMaterial.js new file mode 100644 index 00000000000000..a697d45c310698 --- /dev/null +++ b/examples/jsm/nodes/materials/MeshMatcapNodeMaterial.js @@ -0,0 +1,56 @@ +import NodeMaterial, { addNodeMaterial } from './NodeMaterial.js'; +import { materialReference } from '../accessors/MaterialReferenceNode.js'; +import { diffuseColor } from '../core/PropertyNode.js'; +import { vec2, vec3 } from '../shadernode/ShaderNode.js'; +import { positionViewDirection } from '../accessors/PositionNode.js'; +import { MeshMatcapMaterial } from 'three'; +import { transformedNormalView } from '../accessors/NormalNode.js'; +import { mix } from '../math/MathNode.js'; + +const defaultValues = new MeshMatcapMaterial(); + +class MeshMatcapNodeMaterial extends NodeMaterial { + + constructor( parameters ) { + + super(); + + this.isMeshMatcapNodeMaterial = true; + + this.lights = false; + + this.setDefaultValues( defaultValues ); + + this.setValues( parameters ); + + } + + setupVariants( builder ) { + + const x = vec3( positionViewDirection.z, 0.0, positionViewDirection.x.negate() ).normalize(); + const y = positionViewDirection.cross( x ); + + const uv = vec2( x.dot( transformedNormalView ), y.dot( transformedNormalView ) ).mul( 0.495 ).add( 0.5 ) ; // 0.495 to remove artifacts caused by undersized matcap disks + + let matcapColor; + + if ( builder.material.matcap ) { + + matcapColor = materialReference( 'matcap', 'texture' ).context( { getUV: () => uv } ); + + } else { + + matcapColor = vec3( mix( 0.2, 0.8, uv.y ) ); // default if matcap is missing + + } + + diffuseColor.rgb.mulAssign( matcapColor.rgb ); + + } + +} + + +export default MeshMatcapNodeMaterial; + +addNodeMaterial( 'MeshMatcapNodeMaterial', MeshMatcapNodeMaterial ); diff --git a/examples/screenshots/webgpu_materials_matcap.jpg b/examples/screenshots/webgpu_materials_matcap.jpg new file mode 100644 index 00000000000000..088a1f0f091d5d Binary files /dev/null and b/examples/screenshots/webgpu_materials_matcap.jpg differ diff --git a/examples/webgpu_materials_matcap.html b/examples/webgpu_materials_matcap.html new file mode 100644 index 00000000000000..9b99156be3dd26 --- /dev/null +++ b/examples/webgpu_materials_matcap.html @@ -0,0 +1,274 @@ + + + + three.js webgpu - materials - matcap + + + + + + +
+ three.js - webgpu materials matcap
+ Drag-and-drop JPG, PNG, WebP, AVIF, or EXR MatCap image files
+
+ + + + + + +