Can this desert be done in threejs?
Three.js is a library that is extending WebGL/WebGPU.
So, sure, if CPU and GPU (OpenGL/Vulkan/Metal/DirectX) allow this, then it can be made.
Three.js doesn’t have any ready-made desert generator, so you would need to assemble such scene from smaller components that it has (Cube, Plane etc.).
I’m doing the entire earth, mars, moon, … with three.js. At the moment I’m working on an ocean.
The reason why my mountains look more like hills is only because my maps are not of high resolution. Since I have the entire earth in that resolution, that’s huge amounts of data.
Lens flares like with your sun are also possible. Meanwhile a lot is possible with three.js and with webgpu in three.js nearly everything. But you have to know what you’re doing.
Your desert would be something that could be created with the IFFT (inverse fast fourier transformation) system that I’m currently develop because of my ocean in combination with my CDLOD. But I’m probably going into too much detail.
Yes your desert can be realized with three.js
Yes. Download files and apply shaders.
My work on my ocean made me think back to your desert. Your desert would basically be a still image of my ocean surface with a sand shader or sand texture
For me, everything moves and it moves completely smoothly. Your desert is technically very possible with three.js.
However, my ocean still needs the option to use varyings in wgslFn so that I can implement some important things. But I’m in good spirits about that. The node system has developed a lot and I use it very extensively. I do all this with webgpu.
And there are still significant performance reserves left on my laptop, which only has an onboard graphics chip.
Water waves and sand dunes are both created by wind.
We aimed to create a virtual experience of desert safari for Arabian tourists, with a virtual safari we should be able to give a glimpse of the excitement on racing and jumping on and off the desert dunes.
Sample WebGL virtual island for open world
Whoa this is awesome, please share live demo.
let v0 = new vec3();
let v1 = new vec3();
let v2 = new vec3();
let v3 = new vec3();
let v4 = new vec3();
let noisefn=(x,y,seconds,v=v0)=>{
let z = sin((x*.1)+seconds)*cos((y*.13)+seconds);
let z1 = sin((y*.15)+seconds)*cos((x*.2)+seconds);
z -= z1;
return v.set(x,z*3,y)
}
let patchGeometry = new PlaneGeometry(50,50,99,99);
let material = new MeshStandardMaterial({color:'#ffbe67',dithering:true})
patchGeometry.rotateX(PI*-.5)
let createPatch=()=>{
let m1 = new Mesh(patchGeometry.clone(),material)
scene.add(m1)
return m1;
}
let generatePatch=(mesh,seconds,lod=0)=>{
let a = mesh.geometry.attributes.position.array;
let na = mesh.geometry.attributes.normal.array;
let sz=100;
let sz2=sz/2;
v3.set(-sz2,0,-sz2)
v4.set(sz2,0,sz2);
let bb = mesh.geometry.boundingBox || (mesh.geometry.boundingBox = new THREE.Box3())
let cutoff = 6*lod;
let outIndex = []
let gi=mesh.geometry.index.array;
for(let i=0,ai=0,c=(sz*sz);i<c;i++,ai+=3){
let ix=(i%sz);
let iy=((i/sz)|0);
let x = ix-sz2;
let y = iy-sz2;
let ax=abs(x);
let ay=abs(y);
if((ax<cutoff)&&(ay<cutoff)){
a[ai+0]=x;
a[ai+1]=0;
a[ai+2]=y;
continue;
}
if((ax<sz2)&&(ay<sz2))
{
let ei = ((iy*99)+ix)*6;
outIndex.push(gi[ei],gi[ei+1],gi[ei+2],gi[ei+3],gi[ei+4],gi[ei+5]);
}
let nx = (x*mesh.scale.x)+mesh.position.x;
let ny = (y*mesh.scale.z)+mesh.position.z;
let pp = noisefn(nx,ny,seconds);
let vx = noisefn(nx+(.0001*mesh.scale.x),ny,seconds,v1).sub(pp);
let vy = noisefn(nx,ny+(.0001*mesh.scale.z),seconds,v2).sub(pp);
let vn = vy.cross(vx)
vn.y /= 1+lod;
vn.normalize();
if(!i){
v3.y=v4.y=pp.y
}else{
if(pp.y<v2.y)v3.y=pp.y
if(pp.y>v3.y)v4.y=pp.y
}
a[ai ]=x;//pp.x;
a[ai+1]=pp.y;
a[ai+2]=y;//pp.z;
na[ai ]=vn.x;
na[ai+1]=vn.y;
na[ai+2]=vn.z;
}
mesh.geometry.setIndex(outIndex);
mesh.geometry.boundingBox.set(v3,v4);
mesh.geometry.attributes.position.needsUpdate = true;
mesh.geometry.attributes.normal.needsUpdate = true;
}
//debugger
let lods = []
for(let i=0;i<4;i++){
let m = createPatch();
let scl = (i+1)**3;
m.scale.x=scl;
m.scale.z=scl;
m.scale.y=i+1;
//m.position.y += i;
lods.push(m);
generatePatch(m,0,i);
}
Haha nice… you’re actually looks better than mine. Nice work.
In my code, i was trying to do something fancy with level of detail so I could get better draw distance, but I punted on the seams.
Also the wierd rocky bits in my picture were a separate algorithm using marching cubes + perlin noise that was too bulky/unfinished to paste into an answer.
I’d have liked to share a working example but its all tied up in an experimental framework connected to my localstorage… appreciate you doing that @seanwasere