# Fabric shader on threejs

**URL:** <https://discourse.threejs.org/t/fabric-shader-on-threejs/33516>\
**Category:** Questions\
**Tags:** sheen\
**Created:** [January 11, 2022, 7:45pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516 "2022-01-11T19:45:14Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![mayyar](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@mayyar](https://discourse.threejs.org/u/mayyar)\
**Post date:** [January 11, 2022, 7:45pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/1 "2022-01-11T19:45:14Z")

</div>

Hello there, i try to make some thing like this photo or a random fabric on ground,  
 ![crumpled-red-cloth-fabric-on-260nw-1390099040](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/b/b/bb568d668d0c912e1278369809433a2191c5e27a.jpeg)  
is the best way is using shaders , cus any fabric on blender take a lot of vertices up to 30k,  
so i really try to start, write a shader with some some fabric look,but i wonder how i can get the same result, maybe some generator or somthing ! (i mean about that waves not the render)  
thanks  
demo:[Edit fiddle - JSFiddle - Code Playground](http://jsfiddle.net/w0q2fj93/17/)

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [January 11, 2022, 7:52pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/2 "2022-01-11T19:52:14Z")

</div>

For fabric and velvet materials you definitely want to have a look at the sheen implementation of `MeshPhysicalMaterial`: [three.js webgl - GLTFloader + sheen](https://threejs.org/examples/webgl_loader_gltf_sheen)

---

<div class="post-metadata">

**Author:** ![mayyar](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@mayyar](https://discourse.threejs.org/u/mayyar)\
**Post date:** [January 11, 2022, 8:03pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/3 "2022-01-11T20:03:37Z")

</div>

> [@Mugen87](#):
>
> velvet material

Thank you for replay, but i mean not the material the fabric it self, like create it from plane?

---

<div class="post-metadata">

**Author:** ![mayyar](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@mayyar](https://discourse.threejs.org/u/mayyar)\
**Post date:** [January 11, 2022, 8:08pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/4 "2022-01-11T20:08:48Z")

</div>

Sorry if i misexplain

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [January 11, 2022, 8:32pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/5 "2022-01-11T20:32:10Z")

</div>

> [@mayyar](#):
>
> Thank you for replay, but i mean not the material the fabric it self, like create it from plane?

You can fold a PlaneGeometry in the shader.  
[A dynamically deformable circle (+shader) - #6 by hofk](https://discourse.threejs.org/t/a-dynamically-deformable-circle-shader/33113/6)

But to get such a natural drape, such a curved shape is certainly not easy.

---

<div class="post-metadata">

**Author:** ![mayyar](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@mayyar](https://discourse.threejs.org/u/mayyar)\
**Post date:** [January 12, 2022, 2:10pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/6 "2022-01-12T14:10:10Z")

</div>

> [@hofk](#):
>
> But to get such a natural drape, such a curved shape is certainly not easy.

yah i see, so is there another solution for that ?

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [January 12, 2022, 2:35pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/7 "2022-01-12T14:35:35Z")

</div>

I took a look at [https://www.shadertoy.com/](https://www.shadertoy.com/). But it’s all way too geometric and doesn’t bring that natural fall of soft fabric.

_I don’t know if this is a thing better done with Blender, since I don’t use modeling software myself._

A very elaborate artistic way would be to specify for a number of points (vertices) their xyz coordinates and then determine the intermediate points with `CatmullRomCurve3`.

I have done something similar.  
However, with somewhat different specifications.

View there [Curved2Geometry](https://hofk.de/main/discourse.threejs/2021/Curved2Geometry/Curved2Geometry.html)

> [@Curved2Geometry - a twofold curved geometry](https://discourse.threejs.org/t/curved2geometry-a-twofold-curved-geometry/25580):
>
> Construction One defines with some 3D points the center curve and for some angles the orthogonal radial distances of the hull from these points. By specifying the maximum values, one determines the vertical and radial fineness of the representation. With a definition string of three characters one determines whether caps are to be generated and whether these are to be flat or smooth. The third character allows radial connection without seam or symmetrical geometry. For symmetrical geometry t…

---

<div class="post-metadata">

**Author:** ![Chaser\_Code](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/chaser_code/32/20199_2.png) [@Chaser\_Code](https://discourse.threejs.org/u/Chaser_Code)\
**Post date:** [January 12, 2022, 2:56pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/8 "2022-01-12T14:56:11Z")

</div>

If need for phisiq  
[https://threejs.org/examples/?q=ammo#physics\_ammo\_cloth](https://threejs.org/examples/?q=ammo#physics_ammo_cloth)  
[https://threejs.org/examples/physics\_ammo\_volume.html](https://threejs.org/examples/physics_ammo_volume.html)

---

<div class="post-metadata">

**Author:** ![mayyar](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@mayyar](https://discourse.threejs.org/u/mayyar)\
**Post date:** [January 12, 2022, 5:49pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/9 "2022-01-12T17:49:20Z")

</div>

> [@hofk](#):
>
> have done something similar.  
> However, with somewhat different specifications.

I will take a look thank you, i have to study it 😂

---

<div class="post-metadata">

**Author:** ![mayyar](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@mayyar](https://discourse.threejs.org/u/mayyar)\
**Post date:** [January 12, 2022, 5:50pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/10 "2022-01-12T17:50:24Z")

</div>

> [@Chaser\_Code](#):
>
> phisiq

Mmm, do you think is this a right way, if i need just an static fabric ?

---

<div class="post-metadata">

**Author:** ![Chaser\_Code](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/chaser_code/32/20199_2.png) [@Chaser\_Code](https://discourse.threejs.org/u/Chaser_Code)\
**Post date:** [January 12, 2022, 6:29pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/11 "2022-01-12T18:29:30Z")

</div>

For static u can use 3ds max, unity, unreal engine etc.

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [January 12, 2022, 7:26pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/12 "2022-01-12T19:26:56Z")

</div>

I have made an example of a corrugated fabric.

[CorrugatedFabric](https://hofk.de/main/discourse.threejs/2022/CorrugatedFabric/CorrugatedFabric.html)

 ![2022-01-12 20.23.03](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/1/4/14125adf62040f5e25643708673f6be68025e92b.png)

The position of the vertices is determined by three functions. If you now experiment with room curves or even better construct them beforehand, you might get a useful result.

```javascript

// use t for movement
const positionX = ( w, h, t ) => w / 20 - 4 + 0.1 * Math.cos( 2 * Math.PI * w / 100 + t );
const positionY = ( w, h, t ) => h / 10 + 0.1 * Math.cos( 4 * Math.PI * w / 100 + t );
const positionZ = ( w, h, t ) => 0.5 * Math.sin( 1.4 * Math.PI * ( w + h )/ 50 + t ) - 0.4;

```

I am using a custom geometry.

```javascript
function CustomGeometry( ws, hs, positionX, positionY, positionZ ) {

    const wss = ws + 1;
    const hss = hs + 1;
    
    const faceCount = ws * hs * 2;
    const vertexCount = wss * hss;
    
    const g = new THREE.BufferGeometry( );
    
    g.faceIndices = new Uint32Array( faceCount * 3 );
    g.vertices = new Float32Array( vertexCount * 3 );  
    g.uvs = new Float32Array( vertexCount * 2 );
    
    g.setIndex( new THREE.BufferAttribute( g.faceIndices, 1 ) );	
    g.setAttribute( 'position', new THREE.BufferAttribute( g.vertices, 3 ).setUsage( THREE.DynamicDrawUsage) );
    g.setAttribute( 'uv', new THREE.BufferAttribute( g.uvs, 2 ) );
    
    let idxCount = 0;
    
    let a, b1, b2, c1, c2;
    
    for ( let j = 0; j < ws; j ++ ) {
            
        for ( let i = 0; i < hs; i ++ ) {
            
            // 2 faces / segment, 3 vertex indices
            a = hss * j + i;
            b1 = hss * ( j + 1 ) + i; // right-bottom
            c1 = hss * ( j + 1 ) + 1 + i;
            //b2 = hss * ( j + 1 ) + 1 + i;	// left-top
            c2 = hss * j + 1 + i;
            
            g.faceIndices[idxCount] = a; // right-bottom
            g.faceIndices[idxCount + 1] = b1;
            g.faceIndices[idxCount + 2] = c1; 
            
            g.faceIndices[idxCount + 3] = a; // left-top
            g.faceIndices[idxCount + 4] = c1 // = b2
            g.faceIndices[idxCount + 5] = c2; 
            
            idxCount += 6;
            
        }
            
    }
    
    let x, y, z;
    let vIdx = 0; // vertex index
    let posIdx; // position index
    
    idxCount = 0;
    let u, v;
    
    for ( let j = 0; j < wss; j ++ ) {
        
        u = j / ws;
        
        for ( let i = 0; i < hss; i ++ ) {
            
            v = i / hs;
           
           g.uvs[idxCount] = u;
           g.uvs[idxCount + 1] = v;
           
           idxCount += 2; 
           
        }
        
    }
    
    g.calculateCoordinates = function ( t ) { 
        
        vIdx = 0;
    
        for ( let j = 0; j < wss; j ++ ) { // width 
                
            for ( let i = 0; i < hss; i ++ ) { // height 
                
                x = positionX( j, i, t );
                y = positionY( j, i, t );
                z = positionZ( j, i, t );
                
                xyzSet();
                
                vIdx ++;
                
            }
            
        }
        
        g.attributes.position.needsUpdate = true; // to change the positions of the vertices
        
    }
    
    // set vertex position
    function xyzSet() {
        
        posIdx = vIdx * 3;
        
        g.vertices[posIdx] = x;
        g.vertices[posIdx + 1] = y;
        g.vertices[posIdx + 2] = z;
        
    }
    
    return g;
    
}

```

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [January 13, 2022, 8:41pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/13 "2022-01-13T20:41:04Z")

</div>

Another idea would be to use raycaster to reshape a plane piece by piece.

One can take the two examples as a basis and create a specific solution from them.

From the [Collection of examples from discourse.threejs.org](https://discourse.threejs.org/t/collection-of-examples-from-discourse-threejs-org/4315)

see [Interaction with Points](https://hofk.de/main/discourse.threejs/2018/Interaction%20with%20Points/Interaction%20with%20Points.html)

 ![2022-01-13 21.15.39](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/0/d/0dde568434feae1e76362610c38394ecfcff14a6.png)

and

[Modify indexed BufferGeometry (mouse or input)](https://discourse.threejs.org/t/modify-indexed-buffergeometry-mouse-or-input/1674)  
see [modify Geo](https://hofk.de/main/threejs/modifyGeo/modifyGeo.html)

The drawing of points must be processed in such a way that it is only possible within certain limits. Points in a neighbourhood up to a specified distance must follow a compensation curve. The distances can vary in a small percentage. This corresponds to a slight stretching of the fabric during folding.

That doesn’t sound too difficult at first, but I know from experience that the problems are hidden in the details. In a way it has similarities to [Addon for triangulation of implicit surfaces/ forms with holes](https://discourse.threejs.org/t/addon-for-triangulation-of-implicit-surfaces-forms-with-holes/8722)

---

<div class="post-metadata">

**Author:** ![mayyar](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@mayyar](https://discourse.threejs.org/u/mayyar)\
**Post date:** [January 30, 2022, 2:36pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/14 "2022-01-30T14:36:26Z")

</div>

> [@hofk](#):
>
> Another idea would be to use raycaster to reshape a plane piece by piece.
> 
> One can take the two examples as a basis and create a specific solution from them.
> 
> From the [Collection of examples from discourse.threejs.org](https://discourse.threejs.org/t/collection-of-examples-from-discourse-threejs-org/4315)
> 
> see [Interaction with Points](https://hofk.de/main/discourse.threejs/2018/Interaction%20with%20Points/Interaction%20with%20Points.html)

Thank you for your help!, really thank you very much , i tried the ways that you suggested , but the result is systemic (my mistake) maybe the only way is modeling it ! 🥲

---

<div class="post-metadata">

**Author:** ![mayyar](https://avatars.discourse-cdn.com/v4/letter/m/ce7236/32.png) [@mayyar](https://discourse.threejs.org/u/mayyar)\
**Post date:** [January 30, 2022, 8:08pm UTC](https://discourse.threejs.org/t/fabric-shader-on-threejs/33516/15 "2022-01-30T20:08:47Z")

</div>

Maybe i have to say that i already use cannon in my project, is this may help ?
