pmndrs / lamina

🍰 An extensible, layer based shader material for ThreeJS
MIT License
1.01k stars 41 forks source link

LayerMaterial should create it's base by default #8

Closed DennisSmolek closed 2 years ago

DennisSmolek commented 2 years ago

The base can only be called once and at the origin

<LayerMaterial>
    <Base color="#603295" >
</LayerMaterial>

becomes:

<LayerMaterial color="#603295" >
...
</LayerMaterial>

Similar to how R3f handles camera. Now base only has 3 arguments and only 1 will regularly be set, but if they had a specific requirement or need and really wanted they still could still do:

<LayerMaterial>
    <Base color={compareAllyColors{userColorVar, safeColorVar)} alpha={() => isDarkMode ? 1 : .5}  blend={/**No idea why base blends?**/} >
</LayerMaterial>

R3F Canvas & Camera:

<Canvas camera={{ positon: [0,5,0] }}>
    <Lights >
        <mesh></mesh>
</Canvas>
<Canvas>
    <perspectiveCamera ref="camRef" position={ [0,5,0 }>
        <Lights >
        <mesh></mesh>
</Canvas>
FarazzShaikh commented 2 years ago

The <Base /> layer is more of a <Color /> layer. It provides a nice solid color. This is useful to, for example, darken a given material. You could do:

<Base color="black" alpha={0.3} />

Or fi you want to give something a specific tint.

Maybe we should rename <Base /> to <Color />

DennisSmolek commented 2 years ago
<Base color="black" alpha={0.3} />

Maybe we should rename <Base /> to <Color />

I REALLY like the concept of a Color and agree that Base would be one, but the concept of it being a "base" is important

Many layers (Noise, displacement, etc) require a base color to be set and it's often something people mess up and get confused/frustrated when the stack doesn't seem to be "working"

One method is to require that a ColorLayer (or one that satisfies the requirement) be present somewhere in the stack, order being irrelevant.

<LayerMaterial>
    <Nosie />
    <Color value="red" mode="multiply" />
    <Texture />
</LayerMaterial>

A 100% opaque Color will block the alpha values of subsequent color layers like Gradient

<LayerMaterial>
    <Color value="red" />
    <Texture />
    <Gradient type=”circular” colors={[rgba(0,0,0,100), rgba(0,0,0,0)] />
</LayerMaterial>

So if one is present and not otherwise called, the base should be ignored baseColorBlocking

But I think the biggest things are

  1. if people forget to define it defauting to the most likely need keeps the stack safe:

    <LayerMaterial>
    <!-- baseline <Color value="black" /> -->
    <Texture />
    </LayerMaterial>
  2. Keeps things cleaner when doing simple colors:

    const [baseColor, setBaseColor] = useState('#32A0CF');
    <LayerMaterial color={baseColor}>
    <Texture mode="screen" />
    </LayerMaterial>
FarazzShaikh commented 2 years ago

Yeah that sounds good to me. Having a color prop on the layer material itself could be the "base" color. And we could rename <Base /> to <Color /> Like this:

<LayerMaterial color="lightblue"> 👈 Base color
    <Noise mode="screen" />
    <Color color="red" mode="multiply" /> 👈 Give the noise red tint
</LayerMaterial>
FarazzShaikh commented 2 years ago

Addressed in 1.1.0