Skip to content

Commit

Permalink
Shader Composer: New shader injection API (#306)
Browse files Browse the repository at this point in the history
  • Loading branch information
hmans authored Sep 27, 2022
1 parent 18fe663 commit d3e2b88
Show file tree
Hide file tree
Showing 17 changed files with 163 additions and 91 deletions.
27 changes: 27 additions & 0 deletions .changeset/friendly-plums-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
"shader-composer-r3f": patch
---

**New:** `shader-composer-r3f` now provides its own mechanism for patching Three.js materials through its new `ShaderMaster` master unit and `<Shader>` React component:

```tsx
function MyShadedThingy() {
const shader = useShader(() => {
return ShaderMaster({
color: /* ... */
position: /* ... */
/* etc. */
})
}, [])

return (
<mesh>
<boxGeometry />

<meshStandardMaterial>
<Shader {...shader} />
</meshStandardMaterial>
</mesh>
)
}
```
2 changes: 0 additions & 2 deletions apps/shader-composer-examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
},
"dependencies": {
"@hmans/r3f-animate": "^0.0.4",
"@material-composer/patch-material": "0.1.3",
"@material-composer/patched": "0.1.2",
"@react-three/drei": "^9.29.1",
"@react-three/fiber": "^8.7.0",
"fp-ts": "^2.12.3",
Expand Down
10 changes: 5 additions & 5 deletions apps/shader-composer-examples/src/examples/DiscoCube.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
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"
Expand All @@ -16,7 +14,7 @@ import {
Sub,
VertexPosition
} from "shader-composer"
import { useShader } from "shader-composer-r3f"
import { Shader, ShaderMaster, useShader } from "shader-composer-r3f"
import { PSRDNoise3D } from "shader-composer-toybox"
import { Color, Mesh } from "three"

Expand All @@ -39,7 +37,7 @@ export default function DiscoCube() {
(v) => Fract(v)
)

return PatchedMaterialMaster({
return ShaderMaster({
color: Mul(new Color("#abf"), noise),
metalness: noise,
roughness: OneMinus(noise)
Expand All @@ -57,7 +55,9 @@ export default function DiscoCube() {
<Environment preset="city" />
<mesh ref={mesh}>
<boxGeometry args={[1.5, 1.5, 1.5]} />
<patched.meshPhysicalMaterial clearcoat={0.2} {...shader} />
<meshPhysicalMaterial clearcoat={0.2}>
<Shader {...shader} />
</meshPhysicalMaterial>
</mesh>
</>
)
Expand Down
18 changes: 11 additions & 7 deletions apps/shader-composer-examples/src/examples/Dissolve.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { PatchedMaterialMaster } from "@material-composer/patch-material"
import { patched } from "@material-composer/patched"
import { pipe } from "fp-ts/function"
import { useControls } from "leva"
import { Mix } from "shader-composer"
import { useShader, useUniformUnit } from "shader-composer-r3f"
import {
Shader,
ShaderMaster,
useShader,
useUniformUnit
} from "shader-composer-r3f"
import { Dissolve } from "shader-composer-toybox"
import { Color, DoubleSide } from "three"

Expand Down Expand Up @@ -41,7 +44,7 @@ export default function DissolveExample() {
dissolveEdgeThickness
)

return PatchedMaterialMaster({
return ShaderMaster({
color: pipe(sphereColor, (v) => Mix(v, dissolveEdgeColor, dissolve.edge)),
alpha: dissolve.alpha
})
Expand All @@ -51,13 +54,14 @@ export default function DissolveExample() {
return (
<mesh>
<icosahedronGeometry args={[1, 10]} />
<patched.meshPhysicalMaterial
{...shader}
<meshPhysicalMaterial
transparent
side={DoubleSide}
metalness={0.1}
roughness={0.2}
/>
>
<Shader {...shader} />
</meshPhysicalMaterial>
</mesh>
)
}
15 changes: 10 additions & 5 deletions apps/shader-composer-examples/src/examples/Fireball.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { PatchedMaterialMaster } from "@material-composer/patch-material"
import { patched } from "@material-composer/patched"
import { useTexture } from "@react-three/drei"
import { pipe } from "fp-ts/function"
import { useControls } from "leva"
Expand All @@ -15,7 +13,12 @@ import {
VertexNormal,
VertexPosition
} from "shader-composer"
import { useShader, useUniformUnit } from "shader-composer-r3f"
import {
Shader,
ShaderMaster,
useShader,
useUniformUnit
} from "shader-composer-r3f"
import { PSRDNoise3D, Turbulence3D } from "shader-composer-toybox"
import textureUrl from "./textures/explosion.png"

Expand Down Expand Up @@ -64,7 +67,7 @@ export default function Fireball() {
(v) => Texture2D(sampler2D, Vec2([0, v])).color
)

return PatchedMaterialMaster({
return ShaderMaster({
/* Modify the vertex position based on the displacement value. */
position: pipe(
displacement,
Expand All @@ -81,7 +84,9 @@ export default function Fireball() {
return (
<mesh>
<icosahedronGeometry args={[1, 5]} />
<patched.meshStandardMaterial {...shader} />
<meshStandardMaterial>
<Shader {...shader} />
</meshStandardMaterial>
</mesh>
)
}
14 changes: 5 additions & 9 deletions apps/shader-composer-examples/src/examples/Flag.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { PatchedMaterialMaster } from "@material-composer/patch-material"
import { patched } from "@material-composer/patched"
import { useTexture } from "@react-three/drei"
import {
Add,
Expand All @@ -10,7 +8,7 @@ import {
Vec3,
VertexPosition
} from "shader-composer"
import { useShader } from "shader-composer-r3f"
import { Shader, ShaderMaster, useShader } from "shader-composer-r3f"
import { DoubleSide } from "three"
import textureUrl from "./textures/shader-composer-logo.jpg"

Expand All @@ -20,7 +18,7 @@ export default function Flag() {
const shader = useShader(() => {
const time = GlobalTime

return PatchedMaterialMaster({
return ShaderMaster({
position: Vec3([
VertexPosition.x,
VertexPosition.y,
Expand All @@ -32,11 +30,9 @@ export default function Flag() {
return (
<mesh>
<planeGeometry args={[4, 2, 40, 20]} />
<patched.meshStandardMaterial
map={texture}
side={DoubleSide}
{...shader}
/>
<meshStandardMaterial map={texture} side={DoubleSide}>
<Shader {...shader} />
</meshStandardMaterial>
</mesh>
)
}
28 changes: 14 additions & 14 deletions apps/shader-composer-examples/src/examples/FloatingIsland.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { PatchedMaterialMaster } from "@material-composer/patch-material"
import { patched } from "@material-composer/patched"
import { Environment, Float as Floating } from "@react-three/drei"
import { pipe } from "fp-ts/function"
import { useControls } from "leva"
Expand All @@ -23,7 +21,12 @@ import {
Vec2,
Vec3
} from "shader-composer"
import { useShader, useUniformUnit } from "shader-composer-r3f"
import {
Shader,
ShaderMaster,
useShader,
useUniformUnit
} from "shader-composer-r3f"
import { Displacement, PSRDNoise2D } from "shader-composer-toybox"
import { Color, RGBADepthPacking, Vector2 } from "three"

Expand Down Expand Up @@ -100,7 +103,7 @@ const FloatingIsland = () => {
recalculating the position for every fragment. */
const position = varying(Displacement(displace).position)

return PatchedMaterialMaster({
return ShaderMaster({
position,

color: pipe(Vec3(new Color("#1982c4")), (v) =>
Expand All @@ -120,20 +123,17 @@ const FloatingIsland = () => {
<mesh castShadow receiveShadow>
<dodecahedronGeometry args={[2, 5]} />

<patched.meshStandardMaterial
{...shader}
flatShading
metalness={0.5}
roughness={0.5}
/>
<meshStandardMaterial flatShading metalness={0.5} roughness={0.5}>
<Shader {...shader} />
</meshStandardMaterial>

{/* We don't need the fragment shader in the depth material. */}
<patched.meshDepthMaterial
vertexShader={shader.vertexShader}
uniforms={shader.uniforms}
<meshDepthMaterial
attach="customDepthMaterial"
depthPacking={RGBADepthPacking}
/>
>
<Shader vertexShader={shader.vertexShader} uniforms={shader.uniforms} />
</meshDepthMaterial>
</mesh>
)
}
19 changes: 10 additions & 9 deletions apps/shader-composer-examples/src/examples/ForceField.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
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"
Expand All @@ -22,7 +20,12 @@ import {
Vec2,
VertexPosition
} from "shader-composer"
import { useShader, useUniformUnit } from "shader-composer-r3f"
import {
Shader,
ShaderMaster,
useShader,
useUniformUnit
} from "shader-composer-r3f"
import { Color } from "three"
import { useRepeatingTexture } from "./helpers"

Expand Down Expand Up @@ -66,7 +69,7 @@ export default function ForceField() {
(v) => Smoothstep(0, 1, v)
)

return PatchedMaterialMaster({
return ShaderMaster({
emissiveColor: Mul(color, intensity),

alpha: pipe(
Expand All @@ -85,11 +88,9 @@ export default function ForceField() {
<Float floatIntensity={1} speed={2}>
<mesh layers-mask={1 << Layers.TransparentFX}>
<icosahedronGeometry args={[1.3, 8]} />
<patched.meshStandardMaterial
transparent
depthWrite={false}
{...shader}
/>
<meshStandardMaterial transparent depthWrite={false}>
<Shader {...shader} />
</meshStandardMaterial>
</mesh>

<pointLight
Expand Down
16 changes: 9 additions & 7 deletions apps/shader-composer-examples/src/examples/Planet.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { PatchedMaterialMaster } from "@material-composer/patch-material"
import { patched } from "@material-composer/patched"
import { pipe } from "fp-ts/function"
import {
Add,
Expand All @@ -17,7 +15,7 @@ import {
Vec3,
VertexPosition
} from "shader-composer"
import { useShader } from "shader-composer-r3f"
import { Shader, ShaderMaster, useShader } from "shader-composer-r3f"
import { Simplex3DNoise } from "shader-composer-toybox"
import { Color } from "three"

Expand Down Expand Up @@ -59,7 +57,7 @@ function Planet() {
(color: Color, height: Input<"float">) => (v: Input<"vec3">) =>
Mix(v, color, Step(height, totalHeight))

return PatchedMaterialMaster({
return ShaderMaster({
position: pipe(
totalHeight,
(v) => Add(1.0, v),
Expand All @@ -81,7 +79,9 @@ function Planet() {
return (
<mesh>
<icosahedronGeometry args={[1, 12]} />
<patched.meshStandardMaterial {...shader} />
<meshStandardMaterial>
<Shader {...shader} />
</meshStandardMaterial>
</mesh>
)
}
Expand All @@ -108,7 +108,7 @@ function Atmosphere() {

const fresnel = Mul(Fresnel(), 0.3)

return PatchedMaterialMaster({
return ShaderMaster({
alpha: pipe(
Float(atmosphereDensity),
(v) => Add(v, clouds),
Expand All @@ -120,7 +120,9 @@ function Atmosphere() {
return (
<mesh>
<icosahedronGeometry args={[1.15, 12]} />
<patched.meshStandardMaterial color="white" {...shader} transparent />
<meshStandardMaterial color="white" transparent>
<Shader {...shader} />
</meshStandardMaterial>
</mesh>
)
}
Expand Down
10 changes: 5 additions & 5 deletions apps/shader-composer-examples/src/examples/Rotation.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { PatchedMaterialMaster } from "@material-composer/patch-material"
import { patched } from "@material-composer/patched"
import {
Input,
Rotate3D,
Time,
VertexNormal,
VertexPosition
} from "shader-composer"
import { useShader } from "shader-composer-r3f"
import { Shader, ShaderMaster, useShader } from "shader-composer-r3f"
import { Vector3 } from "three"

export default function MatrixTransformations() {
Expand All @@ -19,7 +17,7 @@ export default function MatrixTransformations() {

/* 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 PatchedMaterialMaster({
return ShaderMaster({
position: rotate(VertexPosition),
normal: rotate(VertexNormal)
})
Expand All @@ -28,7 +26,9 @@ export default function MatrixTransformations() {
return (
<mesh>
<boxGeometry />
<patched.meshStandardMaterial color="orange" {...shader} />
<meshStandardMaterial color="orange">
<Shader {...shader} />
</meshStandardMaterial>
</mesh>
)
}
Loading

0 comments on commit d3e2b88

Please sign in to comment.