All Projects → pmndrs → Component Material

pmndrs / Component Material

Licence: mit
🧩 Compose modular materials in React

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Component Material

Wagner
Effects composer for three.js
Stars: ✭ 930 (+730.36%)
Mutual labels:  threejs, shaders
Aframe Effects
A VR Ready Post processing framework for Three.js and/or A-Frame
Stars: ✭ 176 (+57.14%)
Mutual labels:  threejs, shaders
Threejs Sandbox
Set of experiments and extensions to THREE.js.
Stars: ✭ 163 (+45.54%)
Mutual labels:  threejs, shaders
cellular-automata-explorer
(WIP) An interactive web app for exploring cellular automata.
Stars: ✭ 18 (-83.93%)
Mutual labels:  threejs, shaders
webgl-image-processing-playground
Image processing shaders with WebGL
Stars: ✭ 15 (-86.61%)
Mutual labels:  threejs, shaders
Filament
Interactive Music Visualizer
Stars: ✭ 22 (-80.36%)
Mutual labels:  threejs, shaders
Terrain Builder
🏔 Procedural terrain using Three.js and perlin noise, Now Accelerated by your GPU!
Stars: ✭ 228 (+103.57%)
Mutual labels:  threejs, shaders
Vue Vr
A framework for building VR applications with Vue
Stars: ✭ 348 (+210.71%)
Mutual labels:  threejs, shaders
Solarsys
Realistic Solar System simulation with three.js
Stars: ✭ 49 (-56.25%)
Mutual labels:  threejs, shaders
Gdx Vfx
LibGDX post-processing visual effects
Stars: ✭ 105 (-6.25%)
Mutual labels:  shaders
Phenomenon
⚡️ A fast 2kB low-level WebGL API.
Stars: ✭ 1,551 (+1284.82%)
Mutual labels:  shaders
Openshadinglanguage
Advanced shading language for production GI renderers
Stars: ✭ 1,382 (+1133.93%)
Mutual labels:  shaders
Portfolio
💼 My personal portfolio built with React and three.js.
Stars: ✭ 106 (-5.36%)
Mutual labels:  threejs
Three.meshline
Mesh replacement for THREE.Line
Stars: ✭ 1,644 (+1367.86%)
Mutual labels:  threejs
Whoosh
[Prototype] Control a 3D spaceship with hand movements
Stars: ✭ 104 (-7.14%)
Mutual labels:  threejs
Actools
Alternative launcher for Assetto Corsa named Content Manager, and some utils as well.
Stars: ✭ 109 (-2.68%)
Mutual labels:  shaders
React 3d Viewer
A 3D model viewer component based on react.js 一个基于react.js的组件化3d模型查看工具
Stars: ✭ 100 (-10.71%)
Mutual labels:  threejs
Unityvolumerendering
Volume rendering, implemented in Unity3D.
Stars: ✭ 102 (-8.93%)
Mutual labels:  shaders
Decoraki
🏠 3D Simulator for interior design
Stars: ✭ 110 (-1.79%)
Mutual labels:  threejs
Partykals
Particles system library for THREE.js
Stars: ✭ 109 (-2.68%)
Mutual labels:  threejs

Version Downloads Discord Shield

Component Material

Material is a React utility that helps you compose and modify materials in react-three-fiber and threejs.

Examples

Quick start

yarn add component-material
import Material from 'component-material'

function CustomMaterial(props) {
  return (
    <Material
      {...props}
      // 1️⃣ declare uniforms with the correct type
      uniforms={{
        r: { value: 1, type: 'float' },
        g: { value: 0.5, type: 'float' },
        b: { value: 0, type: 'float' },
      }}>
      <Material.Frag.Body
        // 2️⃣ Access the uniforms in your shader
        children={`gl_FragColor = vec4(r, g, b, 1.0);`}
      />
    </Material>
  )
}

function Sphere() {
  return (
    <mesh>
      <sphereBufferGeometry />
      <CustomMaterial />
    </mesh>

Features

<Material/>

from

By default Material extends three's MeshPhysicalMaterial. If you want to extend a different material just use the from prop passing the desired material constructor.

<Material from={THREE.MeshPhongMaterial} />

uniforms

Uniforms used inside shaders can be defined via the uniforms prop as follows

<Material
  uniforms={{
    myUniform1: { value: 0, type: 'float' },
    myUniform2: { value: [0, 1], type: 'vec2' },
  }}
/>

This will also create setters and getters for the uniforms automatically, allowing you to mutate them using props and effectively making the material reactive:

function CustomMaterial({ color }) {
  return (
    <Material
      uniforms={{ color: { value: color, type: 'vec3' } }}
      color={color} // color uniform will have the value of the color prop
    />
  • The correspondences between glsl and javascript types can be seen here
  • Uniforms cannot be defined twice in the same shader. So be careful not to define the same uniforms inside the head tag.

varyings

Varying variables can be defined directly inside the shader head tag or they can be declared as prop:

<Material
  varyings={{
    myVarying1: { type: 'float' },
    myVarying2: { type: 'vec2' },
  }}
/>

This is equivalent to adding this code to both your vertex and fragment shaders heads:

float myVarying1;
vec2 myVarying2;
  • Varyings don't have an initial value, only a type definition
  • As uniforms, varyings cannot be defined twice in the same shader, this will give a glsl error. So be careful not to define the same varyings inside the head tag.

Fragment- and vertex-shader composition

The Frag and Vert tags have the function of injecting the shader text, passed as children, into the preconfigured shader of the threejs material. Let's see what it means with an example:

<Material uniforms={{ time: { value: 0, type: 'float' } }}>
  <Material.Frag.Head
    children={`
    float quadraticInOut(float t) {
      float p = 2.0 * t * t;
      return t < 0.5 ? p : -p + (4.0 * t) - 1.0;
    }`}
  />
  <Material.Frag.Body
    children={`
    gl_FragColor.a = gl_FragColor.a * quadraticInOut((sin(time) + 1.0) / 2.0);`}
  />

In the code above the Frag.Head component adds an easing function quadraticInOut to the fragment shader of the material, prepending it before the main function of the shader.

The Frag.Body component instead adds a line of code that modify the gl_FragColor alpha value, appending it after the last operation of the main function.

In particular, if we take as an example the fragment shader of the MeshPhysicalMaterial, Frag.Head prepends the code before this shader line, Frag.Body instead posts the code after this shader line (the dithering_fragment chunk).

The same goes for the Vert component, which however acts on the vertex shader. In particular, Vert.Head prepends the code to this shader line, while Vert.Body appends the code to this shader line (the project_vertex chunk).

It is possible to inject the code after a particular chunk just by doing

<Material.Frag.my_chunk children={`// my custom shader`} />

where my_chunk must be replaced with the name of the chunk concerned.

If we wanted to insert some code just after the emissivemap_fragment chunk (here the reference for the MeshPhysicalMaterial) then just use the following code

<Material.Frag.emissivemap_fragment children={`// my custom shader`} />

replaceChunk

The replaceChunk prop is a boolean that allows you to completely replace the chosen chunk, so instead of append the custom shader code after the chunk it will be replaced directly.

<Material.Frag.emissivemap_fragment replaceChunk children={`// my custom shader`} />

Common chunks

The Common tag is useful in case vertex shader and fragment shader share some functions.

❌ If both the fragment shader and the vertex shader share the easing function quadraticInOut, instead of writing

<Material.Vert.Head
  children={`
  float quadraticInOut(float t) {
    float p = 2.0 * t * t;
    return t < 0.5 ? p : -p + (4.0 * t) - 1.0;
  }`}
/>
<Material.Frag.Head
  children={`
  float quadraticInOut(float t) {
    float p = 2.0 * t * t;
    return t < 0.5 ? p : -p + (4.0 * t) - 1.0;
  }`}
/>

✅ we will write

<Material.Common
  children={`
  float quadraticInOut(float t) {
    float p = 2.0 * t * t;
    return t < 0.5 ? p : -p + (4.0 * t) - 1.0;
  }`}
/>
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].