Hello there, i try to make some thing like this photo or a random fabric on ground,
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
For fabric and velvet materials you definitely want to have a look at the sheen implementation of MeshPhysicalMaterial
: three.js webgl - GLTFloader + sheen
Thank you for replay, but i mean not the material the fabric it self, like create it from plane?
Sorry if i misexplain
You can fold a PlaneGeometry in the shader.
A dynamically deformable circle (+shader) - #6 by 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 ?
I took a look at 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
If need for phisiq
https://threejs.org/examples/?q=ammo#physics_ammo_cloth
https://threejs.org/examples/physics_ammo_volume.html
I will take a look thank you, i have to study it
Mmm, do you think is this a right way, if i need just an static fabric ?
For static u can use 3ds max, unity, unreal engine etc.
I have made an example of a corrugated fabric.
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.
// 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.
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;
}
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
and
Modify indexed BufferGeometry (mouse or input)
see modify Geo
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
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 !
Maybe i have to say that i already use cannon in my project, is this may help ?