diff --git a/.changeset/empty-games-rescue.md b/.changeset/empty-games-rescue.md new file mode 100644 index 000000000..18215776d --- /dev/null +++ b/.changeset/empty-games-rescue.md @@ -0,0 +1,5 @@ +--- +"@material-composer/patch-material": patch +--- + +Now also supports the `patched_Emissive` color value (`emissiveColor` in the `PatchedMaterialMaster`.) diff --git a/.changeset/rare-walls-notice.md b/.changeset/rare-walls-notice.md new file mode 100644 index 000000000..9bc59738a --- /dev/null +++ b/.changeset/rare-walls-notice.md @@ -0,0 +1,5 @@ +--- +"shader-composer-r3f": minor +--- + +**Breaking Change:** Removed the `Custom.*` proxy for CustomShaderMaterial. (You were probably not using it, but who knows!) For a similar proxy-based system, please use `@material-composer/patched`. diff --git a/apps/shader-composer-examples/package.json b/apps/shader-composer-examples/package.json index 783d7140c..4fb6e342a 100644 --- a/apps/shader-composer-examples/package.json +++ b/apps/shader-composer-examples/package.json @@ -10,6 +10,8 @@ }, "dependencies": { "@hmans/r3f-animate": "^0.0.4", + "@material-composer/patch-material": "workspace:^0.1.1", + "@material-composer/patched": "workspace:^0.1.1", "@react-three/drei": "^9.25.3", "@react-three/fiber": "^8.6.2", "fp-ts": "^2.12.3", @@ -20,8 +22,7 @@ "shader-composer": "^0.3.0", "shader-composer-r3f": "^0.2.0", "shader-composer-toybox": "^0.1.0", - "three": "^0.143.0", - "three-custom-shader-material": "^4.0.0" + "three": "^0.143.0" }, "devDependencies": { "@types/react": "^18.0.18", diff --git a/apps/shader-composer-examples/src/examples/DiscoCube.tsx b/apps/shader-composer-examples/src/examples/DiscoCube.tsx index 91351fb5d..aa259cfec 100644 --- a/apps/shader-composer-examples/src/examples/DiscoCube.tsx +++ b/apps/shader-composer-examples/src/examples/DiscoCube.tsx @@ -1,10 +1,11 @@ +import { PatchedMaterialMaster } from "@material-composer/patch-material" +import { patched } from "@material-composer/patched" import { Environment } from "@react-three/drei" import { useFrame } from "@react-three/fiber" import { pipe } from "fp-ts/function" import { useRef } from "react" import { Add, - CustomShaderMaterialMaster, Div, Floor, Fract, @@ -13,10 +14,9 @@ import { NormalizePlusMinusOne, OneMinus, Sub, - Time, VertexPosition } from "shader-composer" -import { Custom, useShader } from "shader-composer-r3f" +import { useShader } from "shader-composer-r3f" import { PSRDNoise3D } from "shader-composer-toybox" import { Color, Mesh } from "three" @@ -39,8 +39,8 @@ export default function DiscoCube() { (v) => Fract(v) ) - return CustomShaderMaterialMaster({ - diffuseColor: Mul(new Color("#abf"), noise), + return PatchedMaterialMaster({ + color: Mul(new Color("#abf"), noise), metalness: noise, roughness: OneMinus(noise) }) @@ -57,7 +57,7 @@ export default function DiscoCube() { - + ) diff --git a/apps/shader-composer-examples/src/examples/Dissolve.tsx b/apps/shader-composer-examples/src/examples/Dissolve.tsx index 915c57095..00774ce18 100644 --- a/apps/shader-composer-examples/src/examples/Dissolve.tsx +++ b/apps/shader-composer-examples/src/examples/Dissolve.tsx @@ -1,7 +1,9 @@ +import { PatchedMaterialMaster } from "@material-composer/patch-material" +import { patched } from "@material-composer/patched" import { pipe } from "fp-ts/function" import { useControls } from "leva" -import { CustomShaderMaterialMaster, Mix } from "shader-composer" -import { Custom, useShader, useUniformUnit } from "shader-composer-r3f" +import { Mix } from "shader-composer" +import { useShader, useUniformUnit } from "shader-composer-r3f" import { Dissolve } from "shader-composer-toybox" import { Color, DoubleSide } from "three" @@ -39,10 +41,8 @@ export default function DissolveExample() { dissolveEdgeThickness ) - return CustomShaderMaterialMaster({ - diffuseColor: pipe(sphereColor, (v) => - Mix(v, dissolveEdgeColor, dissolve.edge) - ), + return PatchedMaterialMaster({ + color: pipe(sphereColor, (v) => Mix(v, dissolveEdgeColor, dissolve.edge)), alpha: dissolve.alpha }) }, []) @@ -51,7 +51,7 @@ export default function DissolveExample() { return ( - Texture2D(sampler2D, vec2(0, v)).color ) - return CustomShaderMaterialMaster({ + return PatchedMaterialMaster({ /* Modify the vertex position based on the displacement value. */ position: pipe( displacement, @@ -72,7 +73,7 @@ export default function Fireball() { ), /* Apply color values. */ - diffuseColor: color, + color, emissiveColor: Mul(color, 1.5) }) }, []) @@ -80,7 +81,7 @@ export default function Fireball() { return ( - + ) } diff --git a/apps/shader-composer-examples/src/examples/Flag.tsx b/apps/shader-composer-examples/src/examples/Flag.tsx index 0fcfa65ac..b5f3e7976 100644 --- a/apps/shader-composer-examples/src/examples/Flag.tsx +++ b/apps/shader-composer-examples/src/examples/Flag.tsx @@ -1,18 +1,17 @@ +import { PatchedMaterialMaster } from "@material-composer/patch-material" +import { patched } from "@material-composer/patched" import { useTexture } from "@react-three/drei" import { Add, - CustomShaderMaterialMaster, GlobalTime, Mul, Sin, - Time, UV, vec3, VertexPosition } from "shader-composer" -import { Custom, useShader } from "shader-composer-r3f" -import { DoubleSide, MeshStandardMaterial } from "three" -import CustomShaderMaterial from "three-custom-shader-material" +import { useShader } from "shader-composer-r3f" +import { DoubleSide } from "three" import textureUrl from "./textures/shader-composer-logo.jpg" export default function Flag() { @@ -21,7 +20,7 @@ export default function Flag() { const shader = useShader(() => { const time = GlobalTime - return CustomShaderMaterialMaster({ + return PatchedMaterialMaster({ position: vec3( VertexPosition.x, VertexPosition.y, @@ -33,7 +32,7 @@ export default function Flag() { return ( - { recalculating the position for every fragment. */ const position = varying(Displacement(displace).position) - return CustomShaderMaterialMaster({ + return PatchedMaterialMaster({ position, - diffuseColor: pipe(Vec3(new Color("#1982c4")), (v) => + color: pipe(Vec3(new Color("#1982c4")), (v) => pipe( v, (v) => Mix(new Color("#252422"), v, Step(-0.2, position.y)), @@ -120,7 +121,7 @@ const FloatingIsland = () => { - { /> {/* We don't need the fragment shader in the depth material. */} - ) diff --git a/apps/shader-composer-examples/src/examples/ForceField.tsx b/apps/shader-composer-examples/src/examples/ForceField.tsx index ea3aeaa64..d780ce24d 100644 --- a/apps/shader-composer-examples/src/examples/ForceField.tsx +++ b/apps/shader-composer-examples/src/examples/ForceField.tsx @@ -1,10 +1,12 @@ +import { PatchedMaterialMaster } from "@material-composer/patch-material" +import { patched } from "@material-composer/patched" import { Float } from "@react-three/drei" import { MeshProps } from "@react-three/fiber" +import { pipe } from "fp-ts/function" import { useControls } from "leva" import { Layers, useRenderPipeline } from "r3f-stage" import { Add, - CustomShaderMaterialMaster, Fresnel, GlobalTime, Mul, @@ -16,13 +18,11 @@ import { Sub, Texture2D, TilingUV, - Time, UV, vec2, VertexPosition } from "shader-composer" -import { pipe } from "fp-ts/function" -import { Custom, useShader, useUniformUnit } from "shader-composer-r3f" +import { useShader, useUniformUnit } from "shader-composer-r3f" import { Color } from "three" import { useRepeatingTexture } from "./helpers" @@ -66,7 +66,7 @@ export default function ForceField() { (v) => Smoothstep(0, 1, v) ) - return CustomShaderMaterialMaster({ + return PatchedMaterialMaster({ emissiveColor: Mul(color, intensity), alpha: pipe( @@ -85,7 +85,7 @@ export default function ForceField() { - ) => (v: Input<"vec3">) => Mix(v, color, Step(height, totalHeight)) - return CustomShaderMaterialMaster({ + return PatchedMaterialMaster({ position: pipe( totalHeight, (v) => Add(1.0, v), (v) => Mul(VertexPosition, v) ), - diffuseColor: pipe( + color: pipe( Vec3(new Color("#336")), applyColor(new Color("yellow"), water), applyColor(new Color("#484"), 0.04), @@ -81,7 +82,7 @@ function Planet() { return ( - + ) } @@ -108,7 +109,7 @@ function Atmosphere() { const fresnel = Mul(Fresnel(), 0.3) - return CustomShaderMaterialMaster({ + return PatchedMaterialMaster({ alpha: pipe( Float(atmosphereDensity), (v) => Add(v, clouds), @@ -120,7 +121,7 @@ function Atmosphere() { return ( - + ) } diff --git a/apps/shader-composer-examples/src/examples/Rotation.tsx b/apps/shader-composer-examples/src/examples/Rotation.tsx index 2945407c0..2ed499400 100644 --- a/apps/shader-composer-examples/src/examples/Rotation.tsx +++ b/apps/shader-composer-examples/src/examples/Rotation.tsx @@ -1,23 +1,25 @@ +import { PatchedMaterialMaster } from "@material-composer/patch-material" +import { patched } from "@material-composer/patched" import { - CustomShaderMaterialMaster, Input, Rotate3D, Time, VertexNormal, VertexPosition } from "shader-composer" -import { Custom, useShader } from "shader-composer-r3f" +import { useShader } from "shader-composer-r3f" import { Vector3 } from "three" export default function MatrixTransformations() { const shader = useShader(() => { /* Let's define a small function that takes a vec3 input and returns a Rotated version of it! */ - const rotate = (v: Input<"vec3">) => Rotate3D(v, new Vector3(0.5, 1, 0), Time()) + const rotate = (v: Input<"vec3">) => + Rotate3D(v, new Vector3(0.5, 1, 0), Time()) /* Rotate both the position and the normal using our rotation function. It's important to also update the normal so that the lighting is correct. */ - return CustomShaderMaterialMaster({ + return PatchedMaterialMaster({ position: rotate(VertexPosition), normal: rotate(VertexNormal) }) @@ -26,7 +28,7 @@ export default function MatrixTransformations() { return ( - + ) } diff --git a/apps/shader-composer-examples/src/examples/StylizedWater.tsx b/apps/shader-composer-examples/src/examples/StylizedWater.tsx index 86382119a..b7e59e74a 100644 --- a/apps/shader-composer-examples/src/examples/StylizedWater.tsx +++ b/apps/shader-composer-examples/src/examples/StylizedWater.tsx @@ -1,4 +1,6 @@ import { Animate, float, rotate } from "@hmans/r3f-animate" +import { PatchedMaterialMaster } from "@material-composer/patch-material" +import { patched } from "@material-composer/patched" import { Environment } from "@react-three/drei" import { MeshProps } from "@react-three/fiber" import { pipe } from "fp-ts/function" @@ -7,7 +9,6 @@ import { Layers, useRenderPipeline } from "r3f-stage" import { Add, Clamp, - CustomShaderMaterialMaster, GlobalTime, Input, Mix, @@ -24,7 +25,7 @@ import { VertexNormal, VertexPosition } from "shader-composer" -import { Custom, useShader, useUniformUnit } from "shader-composer-r3f" +import { useShader, useUniformUnit } from "shader-composer-r3f" import { PSRDNoise2D, PSRDNoise3D } from "shader-composer-toybox" import { Color } from "three" @@ -134,7 +135,7 @@ const Water = (props: MeshProps) => { return Add(position, Mul(normal, scaledNoise)) } - return CustomShaderMaterialMaster({ + return PatchedMaterialMaster({ /* Lerp between the new and the original position based on the value in the calmness variable. */ position: Mix( @@ -143,7 +144,7 @@ const Water = (props: MeshProps) => { calmness ), - diffuseColor: pipe( + color: pipe( /* Start with the "shallow water" color. */ colors.shallow, /* Mix in the original scene color! */ @@ -170,7 +171,7 @@ const Water = (props: MeshProps) => { rotation-x={-Math.PI / 2} > - - + ) } diff --git a/apps/shader-composer-examples/src/examples/Water.tsx b/apps/shader-composer-examples/src/examples/Water.tsx index 3bbb68125..9e3fa069e 100644 --- a/apps/shader-composer-examples/src/examples/Water.tsx +++ b/apps/shader-composer-examples/src/examples/Water.tsx @@ -1,7 +1,8 @@ +import { PatchedMaterialMaster } from "@material-composer/patch-material" +import { patched } from "@material-composer/patched" import { Environment } from "@react-three/drei" import { pipe } from "fp-ts/function" import { - CustomShaderMaterialMaster, GlobalTime, Input, Int, @@ -10,7 +11,7 @@ import { SplitVector3, vec2 } from "shader-composer" -import { Custom, useShader } from "shader-composer-r3f" +import { useShader } from "shader-composer-r3f" import { Displacement, FBMNoise, GerstnerWave } from "shader-composer-toybox" import { add } from "shader-composer/fun" import { Color, DoubleSide } from "three" @@ -19,7 +20,7 @@ const NormalizeNoise = (v: Input<"float">) => Remap(v, -1, 1, 0, 1) function Water() { const shader = useShader(() => { - const diffuseColor = new Color("#acd") + const color = new Color("#acd") const time = GlobalTime const { position, normal } = Displacement((v) => { @@ -55,17 +56,17 @@ function Water() { ) }) - return CustomShaderMaterialMaster({ + return PatchedMaterialMaster({ position, normal, - diffuseColor + color }) }) return ( - ( injectGlobalDefines(material), fragmentShader ? injectProgram(fragmentShader) : identity, injectRoughnessAndMetalness, - injectColorAndAlpha + injectColorAndAlpha, + injectEmissive ) material.onBeforeCompile = (shader) => { @@ -114,6 +115,19 @@ const injectColorAndAlpha = flow( ) ) +const injectEmissive = flow( + extend("void main() {").with(` + #if defined IS_MESHSTANDARDMATERIAL || defined IS_MESHPHYSICALMATERIAL + vec3 patched_Emissive = emissive; + #else + vec3 patched_Emissive = vec3(1.0, 1.0, 1.0); + #endif + `), + replace("vec3 totalEmissiveRadiance = emissive;").with( + "vec3 totalEmissiveRadiance = patched_Emissive;" + ) +) + const injectRoughnessAndMetalness = flow( extend("void main() {").with(` #if defined IS_MESHSTANDARDMATERIAL || defined IS_MESHPHYSICALMATERIAL diff --git a/packages/shader-composer-r3f/package.json b/packages/shader-composer-r3f/package.json index 970f9824b..fa24680a9 100644 --- a/packages/shader-composer-r3f/package.json +++ b/packages/shader-composer-r3f/package.json @@ -29,7 +29,6 @@ "three": ">=0.143.0" }, "dependencies": { - "shader-composer": "^0.3.0", - "three-custom-shader-material": "^4.0.0" + "shader-composer": "^0.3.0" } } diff --git a/packages/shader-composer-r3f/src/index.ts b/packages/shader-composer-r3f/src/index.ts index c2ea038d1..351e313d9 100644 --- a/packages/shader-composer-r3f/src/index.ts +++ b/packages/shader-composer-r3f/src/index.ts @@ -1,2 +1 @@ export * from "./hooks" -export * from "./materials" diff --git a/packages/shader-composer-r3f/src/materials.tsx b/packages/shader-composer-r3f/src/materials.tsx deleted file mode 100644 index ffa7bb750..000000000 --- a/packages/shader-composer-r3f/src/materials.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Node } from "@react-three/fiber" -import React, { forwardRef } from "react" -import { - IUniform, - MeshBasicMaterial, - MeshDepthMaterial, - MeshDistanceMaterial, - MeshLambertMaterial, - MeshMatcapMaterial, - MeshNormalMaterial, - MeshPhongMaterial, - MeshPhysicalMaterial, - MeshStandardMaterial, - MeshToonMaterial, - RGBADepthPacking -} from "three" -import CustomShaderMaterial from "three-custom-shader-material" -import CustomShaderMaterialImpl from "three-custom-shader-material/vanilla" - -export type MaterialConstructor = { new (...args: any[]): T } - -export type MaterialProps = Node> & { - vertexShader?: string - fragmentShader?: string - uniforms?: Record -} - -const makeMaterialComponent = ( - ctor: MaterialConstructor, - defaultProps?: MaterialProps -) => - forwardRef>((props, ref) => { - /* We still need to ts-ignore the next line, because something between - R3F's and CSM's props typings appears to be deeply incompatible. */ - - return ( - // @ts-ignore - - ) - }) - -export const Custom = { - MeshBasicMaterial: makeMaterialComponent(MeshBasicMaterial), - MeshDepthMaterial: makeMaterialComponent(MeshDepthMaterial, { - attach: "customDepthMaterial", - depthPacking: RGBADepthPacking - }), - MeshDistanceMaterial: makeMaterialComponent(MeshDistanceMaterial, { - attach: "customDistanceMaterial" - }), - MeshLambertMaterial: makeMaterialComponent(MeshLambertMaterial), - MeshMatapMaterial: makeMaterialComponent(MeshMatcapMaterial), - MeshNormalMaterial: makeMaterialComponent(MeshNormalMaterial), - MeshPhongMaterial: makeMaterialComponent(MeshPhongMaterial), - MeshPhysicalMaterial: makeMaterialComponent(MeshPhysicalMaterial), - MeshStandardMaterial: makeMaterialComponent(MeshStandardMaterial), - MeshToonMaterial: makeMaterialComponent(MeshToonMaterial) -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ddbfae9c0..d876735bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -221,6 +221,8 @@ importers: apps/shader-composer-examples: specifiers: '@hmans/r3f-animate': ^0.0.4 + '@material-composer/patch-material': workspace:^0.1.1 + '@material-composer/patched': workspace:^0.1.1 '@react-three/drei': ^9.25.3 '@react-three/fiber': ^8.6.2 '@types/react': ^18.0.18 @@ -236,11 +238,12 @@ importers: shader-composer-r3f: ^0.2.0 shader-composer-toybox: ^0.1.0 three: ^0.143.0 - three-custom-shader-material: ^4.0.0 typescript: ^4.8.2 vite: ^3.0.9 dependencies: '@hmans/r3f-animate': 0.0.4_zvfcrx6qs7myq74qxffhadzqgy + '@material-composer/patch-material': link:../../packages/material-composer-patch-material + '@material-composer/patched': link:../../packages/material-composer-patched '@react-three/drei': 9.25.3_kr35nn26kgyu6kavah7kd3pzxa '@react-three/fiber': 8.6.2_f72olm6mn3unzgg4exeiaoxanm fp-ts: 2.12.3 @@ -252,7 +255,6 @@ importers: shader-composer-r3f: link:../../packages/shader-composer-r3f shader-composer-toybox: link:../../packages/shader-composer-toybox three: 0.143.0 - three-custom-shader-material: 4.0.0_zvfcrx6qs7myq74qxffhadzqgy devDependencies: '@types/react': 18.0.18 '@types/react-dom': 18.0.6 @@ -479,10 +481,8 @@ importers: react-dom: ^18.2.0 shader-composer: ^0.3.0 three: ^0.143.0 - three-custom-shader-material: ^4.0.0 dependencies: shader-composer: link:../shader-composer - three-custom-shader-material: 4.0.0_zvfcrx6qs7myq74qxffhadzqgy devDependencies: '@react-three/fiber': 8.6.2_f72olm6mn3unzgg4exeiaoxanm react: 18.2.0