Giter VIP home page Giter VIP logo

three-landscape's Introduction

Three landscape

A growing collection of React-three-fiber compatible abstractions for rendering high quality, large scale landscapes scenes. I've been researching how AAA games render terrain and am replicating any browser compatible techniques here.

Note: this package is not capable of procedurally generating terrain. Height maps and other textures must be authored offline in programs such as WorldCreator or Blender.

Demo:

https://three-landscape.vercel.app/

Source code for example is available in the /examples/highlands directory

Installation

npm install three-landscape

Documentation

TerrainMaterial

Custom material that extends the meshStandardMaterial with additional properties for splat mapping. Splat mapping lets you blend and combine multiple surfaces(grass, rocks, sand etc) into one higher resolution material: http://wiki.polycount.com/wiki/Splat

Features:

  • all the props & behaviors of meshStandardMaterial
  • Splatmaps
  • Texture saturation and tint
  • Stochastic sampling
  • Triplanar mapping
  • Multiple material blending options
  • Automatic texture 'atlasing' allows more that 16 textures(max on most hardware by default)
function MySuperCoolTerrain() {
  const textures = useTexture([
    ... any number of textures
  ]);

  return (
    <mesh>
      <planeBufferGeometry args={[1024, 1024, 1024, 1024]} ref={geometry => {
        if(geometry){
          geometry.attributes.uv2 = geometry.attributes.uv.clone();
          geometry.needsUpdate = true;
        }
      }} />
      <TerrainMaterial
        splats={[textures[1]}
        surfaces={[rock, clif, mud, grass]}
        normalMap={textures[2]}
        displacementMap={textures[3]}
        displacementScale={100.0}
      />
    </mesh>
  );
}

New props:

  • splats: Texture[] (expects 4 channel splat data in rgba)
  • surfaceSamples: Number, defaults to 4.
  • surfaces: Surface[];
  • smoothness: Number > 0
  • distanceOptimizedRendering: Boolean, defaults to true

Most of the new features are configured by modifying surface properties.

Surfaces:

Surfaces are related groups of textures and properties that define how to render part of the terrain. Rock, grass, sand etc would all be separate surfaces.

example:

const grass = {
    diffuse: texture[1],
    normal: texture[2],
    normalStrength: 0.4,
    repeat: 200,
    gridless: true,
    saturation: 0.7,
    tint: new Vector4(0.8,1.0,0.8,1),
};

To get a better understanding of how each noise parameter effects the edge check out this interactive demo: https://www.redblobgames.com/x/1730-terrain-shader-experiments/noisy-hex-rendering.html

Please see the example directory for advanced usage and example textures.

Note: The textures are not covered by the MIT license and should not be used with out first acquiring the rights to do so.

useProgressiveTexture

Similar to useTexture from drie but progressively loads higher quality textures over time.

function Terrain(){
    const [quality, textures] = useProgressiveTextures([
      ['/heightmap.png','/normalmap.png'], // batch 1
      ['/hd/heightmap.png','/hd/normalmap.png'] // batch 2
    ])

    const [displacement, normal] = textures[quality]
    return(
      <mesh>
        <planeBufferGeometry/>
        <meshStandardMaterial 
          color="green" 
          normalMap={normal} 
          displacementMap={displacement} 
        />
      </mesH>
    )
}

It is a texture loader that accepts an array of url arrays and returns: Array of texture batches and an int holding the index of the highest quality texture batch that has been downloaded.

All textures in a batch (['/hd/heightmap.png','/hd/[email protected]']) are resolved before moving on to the next highest quality level To get performance benefits, resource batches should be of ordered by ascending quality.

Basis textures:

Note: as long as you serve provide a /basis_transcoder.js and /basis_transcoder.wasm useProgressiveTexture can also auto resolve highly compressed basis textures.

See the BasisTextureLoader and Basisu project for more details: https://github.com/BinomialLLC/basis_universal

MartiniMesh

Creates a non uniform error minimizing mesh with less geometry than a standard planeBufferGeometry. Acceptable error is measured in world units. Eg error 0 mesh will be nearly identical, a Error 10 mesh will be allowed to differ at most 10 world units at any point from the standard plane.

<mesh>
  <MartiniGeometry displacementMap={displacement} error={10} />
  <meshStandardMaterial color="red" wireframe>
</mesh>

Roadmap:

Thought it might be fun to let people vote on new feature ideas! If you're interested in a particular feature leave a thumbs up on the associated issue:

view issues sorted by most votes

Contributing:

project is setup using npm workspaces. package includes the library code and examples folder can be used to manually test changes to the library before publishing.

for convenience the following commands are setup in the root of the directory if you're unfamilar with npm workspaces:

npm run build
npm run dev

npm run dev starts the library and highlands example in watch mode. the highlands example starts on localhost:5173

before publishing

npm run build
npm publish -w package

testing npm packages

npm link does not work due to the use of peer dependencies. Use pack & install instead

~/workspace/package-name $ npm pack
~/workspace/package-name $ cp package-name-0.0.0.tgz ~
~/workspace/some-application $ npm install ~/package-name-0.0.0.tgz

License

MIT License does not apply to any of the image files in the examples directory

three-landscape's People

Contributors

nwpointer avatar natpoint avatar kenjinp avatar

Stargazers

Krtolica Vujadin avatar 某个大叔 avatar Mathias Kahl avatar  avatar Yi Zhe Ang avatar Zibx avatar ShihJyun Yeo avatar Ben Emma avatar  avatar H DLC avatar Zhazha_JiaYiZhen avatar yushuisheng avatar Amaan Bhati avatar Shreyas K R avatar Florian avatar  avatar Diederik van Remoortere avatar Ridy Franck Rich avatar Zai Santillan avatar AJ DeMarco avatar Can Delibas avatar WongSpark avatar Kevin Lobine avatar SteffanLee avatar yangAlan avatar Wasawat Somno avatar  avatar Steve Krichten avatar Leonardo Batista avatar Hòa (Vladimir Scarlet) avatar  avatar danielsdesk avatar Nikita Zhenev avatar Zdenko Klain avatar Moonjong-shin avatar  avatar  avatar Jonathan Chemla avatar João Faria avatar Thimo avatar jiangqi avatar Brad B. avatar Georgiana Marcu avatar Fortes avatar Florian Rohrweck avatar Anderson Mancini avatar Yugam Dhuriya avatar Neftaly Hernandez avatar Luís Freitas avatar Dario Sanchez avatar Mohit Kumar Toshniwal avatar Arttu Koskela avatar Milan Milanov avatar lew avatar Ustym Ukhman avatar Dale Watson avatar  avatar Michael Dobekidis avatar Ethan Chiu avatar Oleksandr Popov avatar  avatar  avatar J avatar Christoph Lindstädt avatar Mattèo Gauthier avatar Wouter Lucifer avatar Nico Kendrick avatar Robin Hawkes avatar Marcin Jerzak avatar Heagan Henry avatar Jonathan Mumm avatar Audifaxdev avatar Jaroslaw avatar  avatar Ethan Crann avatar James Homer avatar Brian avatar Taylor Hodge avatar Vico Erv avatar Eugene Upston avatar Nikita avatar Kayden T avatar Ben Follington avatar Dennis Smolek avatar walisonmatheus avatar Giulio Zausa avatar Hendrik Mans avatar Tim Rijkse avatar Smarthug avatar pjh_tomoya06 avatar Keri Lynn avatar Ian Jamieson avatar Akira Tanaka avatar Fabio Dias Rollo avatar Nathan Rugg avatar Pierre-Alexis M. avatar William McMurray avatar Alex Ionkov avatar  avatar Hunter MW avatar

Watchers

arpu avatar Jonathan Mumm avatar  avatar Vis avatar sinfzx avatar

three-landscape's Issues

Add support for vanilla Three.js

Vanilla support was rolled back with most recent large release. Consider supporting vanilla apps and so it can be used in frameworks other than r3f such as threlte.

pure threejs implementation not working

Having trouble getting this going. Seems onBeforeCompile does not run.

`new GLTFLoader().load('models/mesh.glb', (gltf) => {
model = gltf.scene
scene.add(model)
new TextureLoader().load('models/splatmap_01.jpg', (texture) => {
new TextureLoader().load('models/brush1.png', (brush1) => {
new TextureLoader().load('models/brush2.png', (brush2) => {
new TextureLoader().load('models/brush3.png', (brush3) => {
model.material = new SplatStandardMaterialImpl({_splats:[texture], _diffuseMaps:[brush1, brush2, brush3]});
console.log(model.material)

                model.material.needsUpdate = true
            }) 
        }) 
    }) 
})

})`

Consider physics

Would be nice if there were examples or helpful components for adding collision detection and or generating a navmesh for ai agents

Lightmaps and AOMaps

Will these work? Since the material extends from mesh standard material

Looks like it doesnt have any effect

Surface displacement maps

Grass or rocks should be displaceable to add additional details.

Doing to performantly is dependent on adaptive mesh density.
alternatively instead of actually displacing the objects, use parallax occlusion.

Texture atlas support

Texture atlas are single files with multiple textures in them. This will be helpful if you are nearing the 16 texture per material limit or trying to reduce total number of files downloaded

Adaptive mesh density

using a BTree + based longest edge subdivision would allow for dynamically controlling mesh density either by distance from camera or some other criteria while avoiding gaps caused by T-junctions in quad-tree based solutions.

Support for other Three Materials (Lambert, Basic, Phong)

Thought I'd open this as suggestion for a potential next feature :)

Less expensive Materials

I've noticed that Standard Materials covering large portions of the screen can already bring my Laptop to < 60 fps (without PP or anything else going on in the scene). Since I'm going for a stylized look in my game with potentially fully baked environment lighting, I'm either looking to use sth like a LambertMaterial, or outright full BasicMaterials.

Would be great to be able to still use three-landscape with that!


Potentially unrelated(?)
I think for a lot of us the Splatmap is the most important feature, since using a real geometry instead of a heightmap makes some things easier to get started (i.e. physics / raycasting). So maybe there is room for a slimmed down version of the TerrainMaterial, i.e. sth like a SplatMaterial?

Cheers!

Tri-planar projection

This would help reduce texture stretching on part of the terrain with extreme hight differentials

Virtual Textures

implement a sparse virtual texture to reduce performance impact of combining expensive operations such as triplanar mapping + gridless pass.

Infinite mirror grid

helper to tile a terrain sector in an grid, using mirroring to avoid sharp edged between sectors.

usefull for faking infinite terrain in self similar environments (mountains, sand dunes etc)

No matching export in "node_modules/three/build/three.module.js" for import "sRGBEncoding"

Hi!

First of all, amazing library you created here! Great work!
I want to play around with it a bit, but I'm having issues,
I'm using these dependencies:

"devDependencies": {
    "@types/react-dom": "^18.2.25",
    "@types/three": "^0.164.0",
    "typescript": "^5.4.5"
  },
  "dependencies": {
    "@react-three/drei": "^9.105.4",
    "@react-three/fiber": "^8.16.2",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "three": "^0.164.1",
    "three-landscape": "^0.9.2",
    "vite": "^5.2.10"
  },

But vite is throwing errors when trying to import the library:

 No matching export in "node_modules/three/build/three.module.js" for import "sRGBEncoding"

    node_modules/three-landscape/dist/util/generateTextureArray.js:1:114:
      1 │ ...at, UnsignedByteType, LinearMipMapLinearFilter, NearestFilter, RepeatWrapping, sRGBEncoding } from "three";
        ╵       

No matching export in "node_modules/three/build/three.module.js" for import "sRGBEncoding"

    node_modules/three-landscape/dist/util/util.js:69:67:
      69 │ import { RepeatWrapping, NearestFilter, LinearMipmapNearestFilter, sRGBEncoding } from "three";

It looks like maybe THREE renamend sRGBEncoding to sRGBColorSpace and the encoding property on textures to colorSpace.

I guess the way to fix this is upgrading the dependencies of the library and making use of those new names, right?
Well, I'll give it a try.

GLSL tile transitions

Currently tile textures(rock, grass ect) just blend smoothly into one another. This is ok but requires large splat maps to make terrain look good and can look smudgy / low fidelity in certain cases.

It would be ideal if the respective texture weights were used as input to user supplied glsl that applied arbitrary shaping functions to the edges of terrain transitions

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.