@3driseai/3drise-viewer 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Clouds.d.ts.map +1 -1
- package/dist/components/Clouds.js +0 -1
- package/dist/components/CloudsGenerator.d.ts +32 -0
- package/dist/components/CloudsGenerator.d.ts.map +1 -0
- package/dist/components/CloudsGenerator.js +58 -0
- package/dist/components/CustomPrimitive.js +1 -1
- package/dist/components/EnvironmentManager.d.ts +47 -5
- package/dist/components/EnvironmentManager.d.ts.map +1 -1
- package/dist/components/EnvironmentManager.js +35 -66
- package/dist/components/GeometryShape.d.ts.map +1 -1
- package/dist/components/GeometryShape.js +19 -3
- package/dist/components/HdrEnvironment.d.ts +20 -0
- package/dist/components/HdrEnvironment.d.ts.map +1 -0
- package/dist/components/HdrEnvironment.js +44 -0
- package/dist/components/LandscapeBuilder.d.ts +23 -0
- package/dist/components/LandscapeBuilder.d.ts.map +1 -0
- package/dist/components/LandscapeBuilder.js +25 -0
- package/dist/components/LandscapeObject.d.ts +24 -0
- package/dist/components/LandscapeObject.d.ts.map +1 -0
- package/dist/components/LandscapeObject.js +27 -0
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +11 -9
- package/dist/components/OceanBuilder.d.ts +35 -0
- package/dist/components/OceanBuilder.d.ts.map +1 -0
- package/dist/components/OceanBuilder.js +53 -0
- package/dist/components/ParticlesR3f.d.ts.map +1 -1
- package/dist/components/ParticlesR3f.js +63 -12
- package/dist/components/PointCloud.d.ts.map +1 -1
- package/dist/components/PointCloud.js +50 -10
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SkySystem.d.ts +27 -6
- package/dist/components/SkySystem.d.ts.map +1 -1
- package/dist/components/SkySystem.js +6 -5
- package/dist/components/SunLight.d.ts.map +1 -1
- package/dist/components/SunLight.js +4 -1
- package/dist/components/TerrainBuilder.d.ts +30 -0
- package/dist/components/TerrainBuilder.d.ts.map +1 -0
- package/dist/components/TerrainBuilder.js +44 -0
- package/dist/components/index.d.ts +17 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +10 -0
- package/dist/components/landscape/LandscapeMesh.d.ts +18 -0
- package/dist/components/landscape/LandscapeMesh.d.ts.map +1 -0
- package/dist/components/landscape/LandscapeMesh.js +278 -0
- package/dist/components/landscape/index.d.ts +3 -0
- package/dist/components/landscape/index.d.ts.map +1 -0
- package/dist/components/landscape/index.js +1 -0
- package/dist/components/landscape/types.d.ts +13 -0
- package/dist/components/landscape/types.d.ts.map +1 -0
- package/dist/components/landscape/types.js +1 -0
- package/dist/components/terrain/Canyon.d.ts +23 -0
- package/dist/components/terrain/Canyon.d.ts.map +1 -0
- package/dist/components/terrain/Canyon.js +29 -0
- package/dist/components/terrain/Dunes.d.ts +22 -0
- package/dist/components/terrain/Dunes.d.ts.map +1 -0
- package/dist/components/terrain/Dunes.js +25 -0
- package/dist/components/terrain/Hills.d.ts +17 -0
- package/dist/components/terrain/Hills.d.ts.map +1 -0
- package/dist/components/terrain/Hills.js +20 -0
- package/dist/components/terrain/Mountains.d.ts +19 -0
- package/dist/components/terrain/Mountains.d.ts.map +1 -0
- package/dist/components/terrain/Mountains.js +22 -0
- package/dist/components/terrain/TerrainSurface.d.ts +22 -0
- package/dist/components/terrain/TerrainSurface.d.ts.map +1 -0
- package/dist/components/terrain/TerrainSurface.js +94 -0
- package/dist/components/terrain/index.d.ts +7 -0
- package/dist/components/terrain/index.d.ts.map +1 -0
- package/dist/components/terrain/index.js +7 -0
- package/dist/components/terrain/types.d.ts +17 -0
- package/dist/components/terrain/types.d.ts.map +1 -0
- package/dist/components/terrain/types.js +1 -0
- package/dist/components/volumetricClouds/Cirrus.d.ts +14 -0
- package/dist/components/volumetricClouds/Cirrus.d.ts.map +1 -0
- package/dist/components/volumetricClouds/Cirrus.js +13 -0
- package/dist/components/volumetricClouds/Cumulonimbus.d.ts +17 -0
- package/dist/components/volumetricClouds/Cumulonimbus.d.ts.map +1 -0
- package/dist/components/volumetricClouds/Cumulonimbus.js +20 -0
- package/dist/components/volumetricClouds/Cumulus.d.ts +14 -0
- package/dist/components/volumetricClouds/Cumulus.d.ts.map +1 -0
- package/dist/components/volumetricClouds/Cumulus.js +17 -0
- package/dist/components/volumetricClouds/Stratocumulus.d.ts +12 -0
- package/dist/components/volumetricClouds/Stratocumulus.d.ts.map +1 -0
- package/dist/components/volumetricClouds/Stratocumulus.js +16 -0
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts +42 -0
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -0
- package/dist/components/volumetricClouds/VolumetricCloudsPass.js +298 -0
- package/dist/components/volumetricClouds/index.d.ts +8 -0
- package/dist/components/volumetricClouds/index.d.ts.map +1 -0
- package/dist/components/volumetricClouds/index.js +7 -0
- package/dist/components/volumetricClouds/types.d.ts +17 -0
- package/dist/components/volumetricClouds/types.d.ts.map +1 -0
- package/dist/components/volumetricClouds/types.js +1 -0
- package/dist/components/water/Host.d.ts +12 -0
- package/dist/components/water/Host.d.ts.map +1 -0
- package/dist/components/water/Host.js +12 -0
- package/dist/components/water/Lake.d.ts +18 -0
- package/dist/components/water/Lake.d.ts.map +1 -0
- package/dist/components/water/Lake.js +21 -0
- package/dist/components/water/OceanSurface.d.ts +27 -0
- package/dist/components/water/OceanSurface.d.ts.map +1 -0
- package/dist/components/water/OceanSurface.js +60 -0
- package/dist/components/water/Sea.d.ts +18 -0
- package/dist/components/water/Sea.d.ts.map +1 -0
- package/dist/components/water/Sea.js +17 -0
- package/dist/components/water/Shore.d.ts +16 -0
- package/dist/components/water/Shore.d.ts.map +1 -0
- package/dist/components/water/Shore.js +15 -0
- package/dist/components/water/Storm.d.ts +14 -0
- package/dist/components/water/Storm.d.ts.map +1 -0
- package/dist/components/water/Storm.js +13 -0
- package/dist/components/water/WaterBody.d.ts +31 -0
- package/dist/components/water/WaterBody.d.ts.map +1 -0
- package/dist/components/water/WaterBody.js +76 -0
- package/dist/components/water/index.d.ts +9 -0
- package/dist/components/water/index.d.ts.map +1 -0
- package/dist/components/water/index.js +11 -0
- package/dist/components/water/types.d.ts +20 -0
- package/dist/components/water/types.d.ts.map +1 -0
- package/dist/components/water/types.js +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +15 -0
- package/dist/hooks/index.d.ts +24 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +12 -0
- package/dist/hooks/useClipmap.d.ts +71 -0
- package/dist/hooks/useClipmap.d.ts.map +1 -0
- package/dist/hooks/useClipmap.js +81 -0
- package/dist/hooks/useCloudLive.d.ts +29 -0
- package/dist/hooks/useCloudLive.d.ts.map +1 -0
- package/dist/hooks/useCloudLive.js +43 -0
- package/dist/hooks/useCloudNoise.d.ts +28 -0
- package/dist/hooks/useCloudNoise.d.ts.map +1 -0
- package/dist/hooks/useCloudNoise.js +128 -0
- package/dist/hooks/useCloudSun.d.ts +49 -0
- package/dist/hooks/useCloudSun.d.ts.map +1 -0
- package/dist/hooks/useCloudSun.js +84 -0
- package/dist/hooks/useCubeCamera.d.ts +27 -9
- package/dist/hooks/useCubeCamera.d.ts.map +1 -1
- package/dist/hooks/useCubeCamera.js +28 -70
- package/dist/hooks/useEnvironmentProbe.d.ts +32 -0
- package/dist/hooks/useEnvironmentProbe.d.ts.map +1 -0
- package/dist/hooks/useEnvironmentProbe.js +35 -0
- package/dist/hooks/useFrameRenderer.d.ts +15 -0
- package/dist/hooks/useFrameRenderer.d.ts.map +1 -0
- package/dist/hooks/useFrameRenderer.js +23 -0
- package/dist/hooks/useLandscapeLive.d.ts +29 -0
- package/dist/hooks/useLandscapeLive.d.ts.map +1 -0
- package/dist/hooks/useLandscapeLive.js +41 -0
- package/dist/hooks/useLandscapeMaps.d.ts +32 -0
- package/dist/hooks/useLandscapeMaps.d.ts.map +1 -0
- package/dist/hooks/useLandscapeMaps.js +138 -0
- package/dist/hooks/useMaterialApplication.d.ts.map +1 -1
- package/dist/hooks/useMaterialApplication.js +2 -3
- package/dist/hooks/useMaterialOptions.d.ts +2 -2
- package/dist/hooks/useMaterialOptions.d.ts.map +1 -1
- package/dist/hooks/useMaterialOptions.js +13 -31
- package/dist/hooks/useObjectEdges.d.ts.map +1 -1
- package/dist/hooks/useObjectEdges.js +3 -49
- package/dist/hooks/useOceanLive.d.ts +29 -0
- package/dist/hooks/useOceanLive.d.ts.map +1 -0
- package/dist/hooks/useOceanLive.js +38 -0
- package/dist/hooks/useOceanMaterial.d.ts +39 -0
- package/dist/hooks/useOceanMaterial.d.ts.map +1 -0
- package/dist/hooks/useOceanMaterial.js +65 -0
- package/dist/hooks/useTerrainClipmap.d.ts +12 -0
- package/dist/hooks/useTerrainClipmap.d.ts.map +1 -0
- package/dist/hooks/useTerrainClipmap.js +10 -0
- package/dist/hooks/useTerrainLive.d.ts +34 -0
- package/dist/hooks/useTerrainLive.d.ts.map +1 -0
- package/dist/hooks/useTerrainLive.js +45 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -0
- package/dist/presets/landscapePresets.d.ts +60 -0
- package/dist/presets/landscapePresets.d.ts.map +1 -0
- package/dist/presets/landscapePresets.js +194 -0
- package/dist/presets/landscapeTypes.d.ts +195 -0
- package/dist/presets/landscapeTypes.d.ts.map +1 -0
- package/dist/presets/landscapeTypes.js +315 -0
- package/dist/presets/oceanSurfacePresets.d.ts +33 -0
- package/dist/presets/oceanSurfacePresets.d.ts.map +1 -0
- package/dist/presets/oceanSurfacePresets.js +245 -0
- package/dist/presets/terrainPresets.d.ts +28 -0
- package/dist/presets/terrainPresets.d.ts.map +1 -0
- package/dist/presets/terrainPresets.js +293 -0
- package/dist/presets/volumetricCloudPresets.d.ts +38 -0
- package/dist/presets/volumetricCloudPresets.d.ts.map +1 -0
- package/dist/presets/volumetricCloudPresets.js +480 -0
- package/dist/shaders/clouds/CirrusMaterial.d.ts +84 -0
- package/dist/shaders/clouds/CirrusMaterial.d.ts.map +1 -0
- package/dist/shaders/clouds/CirrusMaterial.js +167 -0
- package/dist/shaders/clouds/CloudCompositeMaterial.d.ts +20 -0
- package/dist/shaders/clouds/CloudCompositeMaterial.d.ts.map +1 -0
- package/dist/shaders/clouds/CloudCompositeMaterial.js +82 -0
- package/dist/shaders/clouds/CloudResolveMaterial.d.ts +22 -0
- package/dist/shaders/clouds/CloudResolveMaterial.d.ts.map +1 -0
- package/dist/shaders/clouds/CloudResolveMaterial.js +77 -0
- package/dist/shaders/clouds/CloudVolumeMaterial.d.ts +143 -0
- package/dist/shaders/clouds/CloudVolumeMaterial.d.ts.map +1 -0
- package/dist/shaders/clouds/CloudVolumeMaterial.js +249 -0
- package/dist/shaders/clouds/SkyBackgroundMaterial.d.ts +21 -0
- package/dist/shaders/clouds/SkyBackgroundMaterial.d.ts.map +1 -0
- package/dist/shaders/clouds/SkyBackgroundMaterial.js +42 -0
- package/dist/shaders/glsl/cloudCore.glsl.d.ts +24 -0
- package/dist/shaders/glsl/cloudCore.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/cloudCore.glsl.js +348 -0
- package/dist/shaders/glsl/landscapeCore.glsl.d.ts +49 -0
- package/dist/shaders/glsl/landscapeCore.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/landscapeCore.glsl.js +518 -0
- package/dist/shaders/glsl/noiseBake.glsl.d.ts +30 -0
- package/dist/shaders/glsl/noiseBake.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/noiseBake.glsl.js +164 -0
- package/dist/shaders/glsl/oceanCore.glsl.d.ts +52 -0
- package/dist/shaders/glsl/oceanCore.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/oceanCore.glsl.js +421 -0
- package/dist/shaders/glsl/terrainCore.glsl.d.ts +78 -0
- package/dist/shaders/glsl/terrainCore.glsl.d.ts.map +1 -0
- package/dist/shaders/glsl/terrainCore.glsl.js +625 -0
- package/dist/shaders/landscape/LandscapeMaterial.d.ts +73 -0
- package/dist/shaders/landscape/LandscapeMaterial.d.ts.map +1 -0
- package/dist/shaders/landscape/LandscapeMaterial.js +136 -0
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts +57 -0
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts.map +1 -0
- package/dist/shaders/ocean/OceanSurfaceMaterial.js +268 -0
- package/dist/shaders/terrain/TerrainMaterial.d.ts +80 -0
- package/dist/shaders/terrain/TerrainMaterial.d.ts.map +1 -0
- package/dist/shaders/terrain/TerrainMaterial.js +291 -0
- package/dist/types/cloudConfigs.d.ts +244 -0
- package/dist/types/cloudConfigs.d.ts.map +1 -0
- package/dist/types/cloudConfigs.js +282 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -1
- package/dist/types/landscapeConfigs.d.ts +218 -0
- package/dist/types/landscapeConfigs.d.ts.map +1 -0
- package/dist/types/landscapeConfigs.js +256 -0
- package/dist/types/oceanConfigs.d.ts +290 -0
- package/dist/types/oceanConfigs.d.ts.map +1 -0
- package/dist/types/oceanConfigs.js +380 -0
- package/dist/types/terrainConfigs.d.ts +251 -0
- package/dist/types/terrainConfigs.d.ts.map +1 -0
- package/dist/types/terrainConfigs.js +292 -0
- package/dist/utils/cloudUniforms.d.ts +14 -0
- package/dist/utils/cloudUniforms.d.ts.map +1 -0
- package/dist/utils/cloudUniforms.js +122 -0
- package/dist/utils/frameRenderer.d.ts +33 -0
- package/dist/utils/frameRenderer.d.ts.map +1 -0
- package/dist/utils/frameRenderer.js +24 -0
- package/dist/utils/handleCloudsAnimations.d.ts +16 -0
- package/dist/utils/handleCloudsAnimations.d.ts.map +1 -0
- package/dist/utils/handleCloudsAnimations.js +64 -0
- package/dist/utils/landscapeGeometry.d.ts +61 -0
- package/dist/utils/landscapeGeometry.d.ts.map +1 -0
- package/dist/utils/landscapeGeometry.js +126 -0
- package/dist/utils/landscapeHeight.d.ts +44 -0
- package/dist/utils/landscapeHeight.d.ts.map +1 -0
- package/dist/utils/landscapeHeight.js +65 -0
- package/dist/utils/landscapeTextures.d.ts +94 -0
- package/dist/utils/landscapeTextures.d.ts.map +1 -0
- package/dist/utils/landscapeTextures.js +290 -0
- package/dist/utils/landscapeUniforms.d.ts +20 -0
- package/dist/utils/landscapeUniforms.d.ts.map +1 -0
- package/dist/utils/landscapeUniforms.js +61 -0
- package/dist/utils/oceanUniforms.d.ts +47 -0
- package/dist/utils/oceanUniforms.d.ts.map +1 -0
- package/dist/utils/oceanUniforms.js +216 -0
- package/dist/utils/pointsMaterialOwnership.d.ts +9 -0
- package/dist/utils/pointsMaterialOwnership.d.ts.map +1 -0
- package/dist/utils/pointsMaterialOwnership.js +14 -0
- package/dist/utils/rtin.d.ts +63 -0
- package/dist/utils/rtin.d.ts.map +1 -0
- package/dist/utils/rtin.js +202 -0
- package/dist/utils/terrainUniforms.d.ts +14 -0
- package/dist/utils/terrainUniforms.d.ts.map +1 -0
- package/dist/utils/terrainUniforms.js +196 -0
- package/package.json +2 -2
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Landscape GLSL — heightmap displacement, splat resolve, and the surface
|
|
3
|
+
* sampling that turns eight tiling materials into ground.
|
|
4
|
+
*
|
|
5
|
+
* Injected into a stock `MeshStandardMaterial` through `onBeforeCompile`, so
|
|
6
|
+
* every one of these snippets has to coexist with three's own chunks. Two
|
|
7
|
+
* consequences worth knowing before editing:
|
|
8
|
+
*
|
|
9
|
+
* - **three r163+ compiles every material as `#version 300 es`** and prepends
|
|
10
|
+
* `#define varying in/out`, `#define texture2D texture` and a `gl_FragColor`
|
|
11
|
+
* alias. So `sampler2DArray` and `textureGrad` are available with no
|
|
12
|
+
* `glslVersion` override — and setting `glslVersion: GLSL3` would REMOVE the
|
|
13
|
+
* `gl_FragColor` alias and break the stock chunks. Write GLSL1-flavoured code
|
|
14
|
+
* and let the prefix do the conversion.
|
|
15
|
+
* - Anything declared here shares a namespace with `<common>`. Everything is
|
|
16
|
+
* `ls`-prefixed or `u_ls`-prefixed for that reason.
|
|
17
|
+
*
|
|
18
|
+
* A backtick inside one of these template literals terminates the string. It has
|
|
19
|
+
* cost this codebase a debug cycle twice.
|
|
20
|
+
*/
|
|
21
|
+
/** Uniforms and helpers the vertex stage needs. Shared with the depth material,
|
|
22
|
+
* which must displace identically or the landscape's shadow will not match it. */
|
|
23
|
+
export const landscapeVertexPars = /* glsl */ `
|
|
24
|
+
uniform sampler2D u_lsHeight;
|
|
25
|
+
uniform vec2 u_lsHeightSize;
|
|
26
|
+
uniform float u_lsSmoothness;
|
|
27
|
+
uniform float u_lsElevation;
|
|
28
|
+
uniform float u_lsElevationBias;
|
|
29
|
+
uniform float u_lsSize;
|
|
30
|
+
|
|
31
|
+
varying vec3 vLsWorld;
|
|
32
|
+
varying vec3 vLsNormalW;
|
|
33
|
+
varying float vLsHeight01;
|
|
34
|
+
|
|
35
|
+
// B-spline bicubic through four bilinear taps. What it is for is 8-bit
|
|
36
|
+
// heightmaps: 256 discrete levels over a kilometre of relief is a staircase, and
|
|
37
|
+
// a bilinear tap keeps every step. Widening the footprint by u_lsSmoothness
|
|
38
|
+
// turns the steps into slopes.
|
|
39
|
+
vec4 lsCubic(float v) {
|
|
40
|
+
vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v;
|
|
41
|
+
vec4 s = n * n * n;
|
|
42
|
+
float x = s.x;
|
|
43
|
+
float y = s.y - 4.0 * s.x;
|
|
44
|
+
float z = s.z - 4.0 * s.y + 6.0 * s.x;
|
|
45
|
+
float w = 6.0 - x - y - z;
|
|
46
|
+
return vec4(x, y, z, w) * (1.0 / 6.0);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
float lsHeightBicubic(vec2 uv, vec2 texSize) {
|
|
50
|
+
vec2 invSize = 1.0 / texSize;
|
|
51
|
+
vec2 coord = uv * texSize - 0.5;
|
|
52
|
+
vec2 f = fract(coord);
|
|
53
|
+
coord -= f;
|
|
54
|
+
|
|
55
|
+
vec4 xc = lsCubic(f.x);
|
|
56
|
+
vec4 yc = lsCubic(f.y);
|
|
57
|
+
vec4 c = coord.xxyy + vec2(-0.5, 1.5).xyxy;
|
|
58
|
+
vec4 s = vec4(xc.xz + xc.yw, yc.xz + yc.yw);
|
|
59
|
+
vec4 o = (c + vec4(xc.yw, yc.yw) / s) * invSize.xxyy;
|
|
60
|
+
|
|
61
|
+
float s0 = texture2D(u_lsHeight, o.xz).r;
|
|
62
|
+
float s1 = texture2D(u_lsHeight, o.yz).r;
|
|
63
|
+
float s2 = texture2D(u_lsHeight, o.xw).r;
|
|
64
|
+
float s3 = texture2D(u_lsHeight, o.yw).r;
|
|
65
|
+
float sx = s.x / (s.x + s.y);
|
|
66
|
+
float sy = s.z / (s.z + s.w);
|
|
67
|
+
return mix(mix(s3, s2, sx), mix(s1, s0, sx), sy);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Normalised height at a UV. NOT wrapped in abs() — the reference does that and
|
|
71
|
+
// it folds every below-zero basin upward, which matters the moment there is
|
|
72
|
+
// water in the scene.
|
|
73
|
+
// Single exit, and the result is initialised at its declaration. Every function
|
|
74
|
+
// in this file is written that way deliberately: ANGLE translates GLSL to HLSL on
|
|
75
|
+
// Windows and rewrites an early return into an assignment plus a jump, which
|
|
76
|
+
// D3D's compiler then reports as X4000 "use of potentially uninitialized
|
|
77
|
+
// variable" naming the function's own result. It is a warning rather than an
|
|
78
|
+
// error and the shader links either way, but the pattern is worth avoiding — the
|
|
79
|
+
// analysis that produces the warning is the same one that decides what to
|
|
80
|
+
// initialise.
|
|
81
|
+
float lsHeightAt(vec2 uv) {
|
|
82
|
+
vec2 c = clamp(uv, 0.0, 1.0);
|
|
83
|
+
float h = 0.0;
|
|
84
|
+
if (u_lsSmoothness > 0.001) {
|
|
85
|
+
h = lsHeightBicubic(c, u_lsHeightSize / max(u_lsSmoothness, 0.001));
|
|
86
|
+
} else {
|
|
87
|
+
h = texture2D(u_lsHeight, c).r;
|
|
88
|
+
}
|
|
89
|
+
return h;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
float lsWorldHeight(vec2 uv) {
|
|
93
|
+
return lsHeightAt(uv) * u_lsElevation + u_lsElevationBias;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Surface normal by central difference at the heightmap's real texel size and
|
|
97
|
+
// the real elevation scale. The reference hardcodes both (1.0/1024.0 and 120.0),
|
|
98
|
+
// so its normals are only correct for one map at one scale, and its smoothed
|
|
99
|
+
// variant returns abs(cross(...)) — a normal with the sign stripped, which is
|
|
100
|
+
// why that API needs per-surface normal-flipping flags to paper over it.
|
|
101
|
+
vec3 lsSurfaceNormal(vec2 uv) {
|
|
102
|
+
vec2 texel = 1.0 / u_lsHeightSize;
|
|
103
|
+
float hL = lsWorldHeight(uv - vec2(texel.x, 0.0));
|
|
104
|
+
float hR = lsWorldHeight(uv + vec2(texel.x, 0.0));
|
|
105
|
+
float hD = lsWorldHeight(uv - vec2(0.0, texel.y));
|
|
106
|
+
float hU = lsWorldHeight(uv + vec2(0.0, texel.y));
|
|
107
|
+
// World distance spanned by the two taps on each axis.
|
|
108
|
+
float dx = 2.0 * texel.x * u_lsSize;
|
|
109
|
+
float dz = 2.0 * texel.y * u_lsSize;
|
|
110
|
+
return normalize(vec3(-(hR - hL) * dz, dx * dz, -(hU - hD) * dx));
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
113
|
+
/** Replaces `<begin_vertex>`. Displaces along local +Y and fills the varyings. */
|
|
114
|
+
export const landscapeVertexBody = /* glsl */ `
|
|
115
|
+
vec3 transformed = vec3(position);
|
|
116
|
+
float lsH01 = lsHeightAt(uv);
|
|
117
|
+
transformed.y += lsH01 * u_lsElevation + u_lsElevationBias;
|
|
118
|
+
vLsHeight01 = lsH01;
|
|
119
|
+
vLsWorld = (modelMatrix * vec4(transformed, 1.0)).xyz;
|
|
120
|
+
vLsNormalW = normalize(mat3(modelMatrix) * lsSurfaceNormal(uv));
|
|
121
|
+
`;
|
|
122
|
+
/** Replaces `<beginnormal_vertex>`. The geometry carries a flat up-normal — the
|
|
123
|
+
* shape is entirely in the heightmap — so the real normal is evaluated here and
|
|
124
|
+
* three's lighting sees a correctly shaded surface with no extra chunk. */
|
|
125
|
+
export const landscapeNormalBody = /* glsl */ `
|
|
126
|
+
vec3 objectNormal = lsSurfaceNormal(uv);
|
|
127
|
+
`;
|
|
128
|
+
/**
|
|
129
|
+
* Fragment uniforms, samplers and the surface sampling machinery.
|
|
130
|
+
*
|
|
131
|
+
* Compile-time counts rather than runtime loops: LS_COUNT is the actual surface
|
|
132
|
+
* count and LS_SAMPLES the blend width, so every loop here has constant bounds
|
|
133
|
+
* and unrolls. The reference runs an eight-element insertion sort in a dynamic
|
|
134
|
+
* while loop on every pixel of the screen.
|
|
135
|
+
*/
|
|
136
|
+
export const landscapeFragmentPars = /* glsl */ `
|
|
137
|
+
uniform sampler2DArray u_lsDiffuse;
|
|
138
|
+
uniform sampler2DArray u_lsNormal; // rgb tangent-space normal, a surface height
|
|
139
|
+
uniform sampler2D u_lsSplat0;
|
|
140
|
+
uniform sampler2D u_lsSplat1;
|
|
141
|
+
uniform sampler2D u_lsAo;
|
|
142
|
+
// The height field as the fragment stage sees it: RG the one-texel gradient,
|
|
143
|
+
// biased by u_lsGradScale, B the height. One fetch replaces two interpolated
|
|
144
|
+
// varyings that were quantising both the splat and the shading to the
|
|
145
|
+
// triangulation. See buildFieldTexture.
|
|
146
|
+
uniform sampler2D u_lsField;
|
|
147
|
+
uniform float u_lsGradScale;
|
|
148
|
+
uniform vec2 u_lsFieldTexel;
|
|
149
|
+
|
|
150
|
+
// repeat, normalStrength, roughness, heightBlend
|
|
151
|
+
uniform vec4 u_lsSurfA[LS_COUNT];
|
|
152
|
+
// tint.rgb, saturation
|
|
153
|
+
uniform vec4 u_lsSurfB[LS_COUNT];
|
|
154
|
+
// triplanar, flipNormalY, metalness, aperiodic
|
|
155
|
+
uniform vec4 u_lsSurfC[LS_COUNT];
|
|
156
|
+
// mean colour per diffuse layer, for the variance-preserving stochastic blend
|
|
157
|
+
uniform vec3 u_lsSurfMean[LS_COUNT];
|
|
158
|
+
|
|
159
|
+
uniform vec4 u_lsAuto; // bandWidth, slopeStart, slopeEnd, noise
|
|
160
|
+
uniform float u_lsAutoBands[LS_COUNT];
|
|
161
|
+
uniform float u_lsNoiseScale; // 1 / noiseSize, world units
|
|
162
|
+
uniform float u_lsMacro;
|
|
163
|
+
uniform float u_lsMacroScale;
|
|
164
|
+
uniform float u_lsAoIntensity;
|
|
165
|
+
uniform float u_lsSize;
|
|
166
|
+
uniform float u_lsElevation;
|
|
167
|
+
|
|
168
|
+
varying vec3 vLsWorld;
|
|
169
|
+
varying vec3 vLsNormalW;
|
|
170
|
+
varying float vLsHeight01;
|
|
171
|
+
|
|
172
|
+
// Arithmetic hash. Never fract(sin(dot(...))): four hashes an octave with two
|
|
173
|
+
// sines each is most of a frame on its own, and this codebase has paid for that
|
|
174
|
+
// lesson once already in the terrain.
|
|
175
|
+
vec2 lsHash2(vec2 p) {
|
|
176
|
+
vec3 p3 = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));
|
|
177
|
+
p3 += dot(p3, p3.yzx + 33.33);
|
|
178
|
+
return fract((p3.xx + p3.yz) * p3.zy);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
float lsHash1(vec2 p) {
|
|
182
|
+
vec3 p3 = fract(vec3(p.xyx) * 0.1031);
|
|
183
|
+
p3 += dot(p3, p3.yzx + 33.33);
|
|
184
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
float lsValueNoise(vec2 p) {
|
|
188
|
+
vec2 i = floor(p);
|
|
189
|
+
vec2 f = fract(p);
|
|
190
|
+
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
191
|
+
return mix(
|
|
192
|
+
mix(lsHash1(i), lsHash1(i + vec2(1.0, 0.0)), u.x),
|
|
193
|
+
mix(lsHash1(i + vec2(0.0, 1.0)), lsHash1(i + vec2(1.0, 1.0)), u.x),
|
|
194
|
+
u.y
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
#ifdef LS_STOCHASTIC
|
|
199
|
+
// Triangle-grid stochastic tiling. Three taps at hashed offsets, weighted by the
|
|
200
|
+
// barycentric coordinate of the point in its cell, so the repeat grid stops
|
|
201
|
+
// existing. The blend is variance-preserving: a straight weighted sum of three
|
|
202
|
+
// samples pulls every pixel toward the texture's mean and visibly washes out
|
|
203
|
+
// contrast, which is what the reference's two-tap smoothstep blend does. Dividing
|
|
204
|
+
// the deviation by sqrt(sum(w^2)) restores it. The mean comes from the CPU, where
|
|
205
|
+
// the pixels were already in hand when the array was packed.
|
|
206
|
+
// Cell size, in texture tiles. The point of stochastic tiling is to randomise
|
|
207
|
+
// PATCHES of texture, so a cell wants to be a tile or two across: smaller and it
|
|
208
|
+
// scrambles within a tile, which shows as noise rather than as break-up, and
|
|
209
|
+
// goes sub-pixel almost immediately.
|
|
210
|
+
//
|
|
211
|
+
// The first version used the bare 3.4641 grid on already-tiled UVs, so a cell was
|
|
212
|
+
// a THIRD of a tile — a fraction of a metre on the ground. It went sub-pixel at
|
|
213
|
+
// any distance, the fade dropped it back to plain sampling, and the repeat grid
|
|
214
|
+
// came straight back at exactly the range it exists to hide.
|
|
215
|
+
#define LS_CELL_TILES 1.5
|
|
216
|
+
|
|
217
|
+
void lsTriGrid(vec2 uv, out vec3 w, out vec2 v1, out vec2 v2, out vec2 v3) {
|
|
218
|
+
w = vec3(0.0);
|
|
219
|
+
v1 = vec2(0.0);
|
|
220
|
+
v2 = vec2(0.0);
|
|
221
|
+
v3 = vec2(0.0);
|
|
222
|
+
vec2 skewed = mat2(1.0, 0.0, -0.57735027, 1.15470054) * (uv * (3.4641016 / LS_CELL_TILES));
|
|
223
|
+
vec2 base = floor(skewed);
|
|
224
|
+
vec3 t = vec3(fract(skewed), 0.0);
|
|
225
|
+
t.z = 1.0 - t.x - t.y;
|
|
226
|
+
if (t.z > 0.0) {
|
|
227
|
+
w = vec3(t.z, t.y, t.x);
|
|
228
|
+
v1 = base;
|
|
229
|
+
v2 = base + vec2(0.0, 1.0);
|
|
230
|
+
v3 = base + vec2(1.0, 0.0);
|
|
231
|
+
} else {
|
|
232
|
+
w = vec3(-t.z, 1.0 - t.y, 1.0 - t.x);
|
|
233
|
+
v1 = base + vec2(1.0, 1.0);
|
|
234
|
+
v2 = base + vec2(1.0, 0.0);
|
|
235
|
+
v3 = base + vec2(0.0, 1.0);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
vec4 lsSampleStochastic(sampler2DArray tex, vec2 uv, float layer, vec3 mean) {
|
|
240
|
+
vec2 dx = dFdx(uv);
|
|
241
|
+
vec2 dy = dFdy(uv);
|
|
242
|
+
vec4 result = vec4(0.0);
|
|
243
|
+
|
|
244
|
+
// Stochastic cells per pixel. THIS FADE IS NOT OPTIONAL. A surface tiled 220
|
|
245
|
+
// times across a two-kilometre landscape has cells a metre or two wide, which
|
|
246
|
+
// is roughly a pixel by the time the ground is a few hundred metres away: the
|
|
247
|
+
// three taps then land in unrelated parts of the texture, the variance
|
|
248
|
+
// correction amplifies the difference, and the far field turns into a moire of
|
|
249
|
+
// black speckle. Rendered, that looked exactly like shadow acne and was not —
|
|
250
|
+
// turning shadows off changed nothing and turning stochastic sampling off
|
|
251
|
+
// fixed it. Past the fade this is a plain sample, which is what the mip chain
|
|
252
|
+
// is for. Gradients are explicit throughout, so the branch is safe.
|
|
253
|
+
float footprint = max(length(dx), length(dy)) * (3.4641016 / LS_CELL_TILES);
|
|
254
|
+
float fade = smoothstep(0.45, 1.10, footprint);
|
|
255
|
+
|
|
256
|
+
if (fade > 0.995) {
|
|
257
|
+
result = textureGrad(tex, vec3(uv, layer), dx, dy);
|
|
258
|
+
} else {
|
|
259
|
+
vec3 w;
|
|
260
|
+
vec2 v1, v2, v3;
|
|
261
|
+
lsTriGrid(uv, w, v1, v2, v3);
|
|
262
|
+
vec4 c1 = textureGrad(tex, vec3(uv + lsHash2(v1), layer), dx, dy);
|
|
263
|
+
vec4 c2 = textureGrad(tex, vec3(uv + lsHash2(v2), layer), dx, dy);
|
|
264
|
+
vec4 c3 = textureGrad(tex, vec3(uv + lsHash2(v3), layer), dx, dy);
|
|
265
|
+
vec4 m = vec4(mean, 0.5);
|
|
266
|
+
vec4 d = w.x * (c1 - m) + w.y * (c2 - m) + w.z * (c3 - m);
|
|
267
|
+
// Clamped: the correction multiplies the deviation by up to 1.73, which
|
|
268
|
+
// takes a dark texel below zero and a bright one past one.
|
|
269
|
+
result = clamp(m + d * inversesqrt(max(dot(w, w), 1e-4)), 0.0, 1.0);
|
|
270
|
+
if (fade >= 0.005) {
|
|
271
|
+
result = mix(result, textureGrad(tex, vec3(uv, layer), dx, dy), fade);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
#endif
|
|
277
|
+
|
|
278
|
+
// Per surface, not per material: stochastic tiling is three fetches instead of
|
|
279
|
+
// one, and only the surfaces a camera gets close to need it. The whole path
|
|
280
|
+
// compiles out when no surface asks for it.
|
|
281
|
+
vec4 lsSampleArray(sampler2DArray tex, vec2 uv, float layer, vec3 mean, float stochastic) {
|
|
282
|
+
vec4 result = vec4(0.0);
|
|
283
|
+
#ifdef LS_STOCHASTIC
|
|
284
|
+
if (stochastic > 0.5) {
|
|
285
|
+
result = lsSampleStochastic(tex, uv, layer, mean);
|
|
286
|
+
} else {
|
|
287
|
+
result = texture(tex, vec3(uv, layer));
|
|
288
|
+
}
|
|
289
|
+
#else
|
|
290
|
+
result = texture(tex, vec3(uv, layer));
|
|
291
|
+
#endif
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
#ifdef LS_TRIPLANAR
|
|
296
|
+
// Biplanar: the two strongest axes, not three. The third contributes a fraction
|
|
297
|
+
// of a percent on any surface that is not an exact 45 degree corner, and it costs
|
|
298
|
+
// a third of the fetches. The reference ships biplanar samplers and then calls
|
|
299
|
+
// the triplanar path anyway.
|
|
300
|
+
vec4 lsSampleWorld(sampler2DArray tex, vec3 wp, vec3 n, float scale, float layer, vec3 mean, float stochastic) {
|
|
301
|
+
vec3 an = abs(n);
|
|
302
|
+
an = an * an * an;
|
|
303
|
+
an /= max(an.x + an.y + an.z, 1e-4);
|
|
304
|
+
float lo = min(an.x, min(an.y, an.z));
|
|
305
|
+
vec3 w = max(an - lo, 0.0);
|
|
306
|
+
w /= max(w.x + w.y + w.z, 1e-4);
|
|
307
|
+
vec4 c = vec4(0.0);
|
|
308
|
+
if (w.x > 0.002) c += w.x * lsSampleArray(tex, wp.zy * scale, layer, mean, stochastic);
|
|
309
|
+
if (w.y > 0.002) c += w.y * lsSampleArray(tex, wp.xz * scale, layer, mean, stochastic);
|
|
310
|
+
if (w.z > 0.002) c += w.z * lsSampleArray(tex, wp.xy * scale, layer, mean, stochastic);
|
|
311
|
+
return c;
|
|
312
|
+
}
|
|
313
|
+
#endif
|
|
314
|
+
|
|
315
|
+
// Saturation as a luma lerp. The reference runs a full RGB->HSV->RGB round trip
|
|
316
|
+
// per sampled surface per pixel for this.
|
|
317
|
+
vec3 lsSaturate(vec3 c, float s) {
|
|
318
|
+
return mix(vec3(dot(c, vec3(0.2126, 0.7152, 0.0722))), c, s);
|
|
319
|
+
}
|
|
320
|
+
`;
|
|
321
|
+
/**
|
|
322
|
+
* The resolve, called from `<map_fragment>`. Fills `lsAlbedo`, `lsNormalW`,
|
|
323
|
+
* `lsRoughness` and `lsMetalness`, which the roughness, metalness and normal
|
|
324
|
+
* chunks then read.
|
|
325
|
+
*
|
|
326
|
+
* Order matters: the surface heights come out of the normal array's alpha
|
|
327
|
+
* channel, so the height blend is computed before a single diffuse texel is
|
|
328
|
+
* fetched, and the diffuse pass already knows its final weights.
|
|
329
|
+
*/
|
|
330
|
+
export const landscapeFragmentBody = /* glsl */ `
|
|
331
|
+
vec2 lsUv = vUv;
|
|
332
|
+
|
|
333
|
+
// PER FRAGMENT, not per vertex. The first version read an interpolated height
|
|
334
|
+
// and an interpolated normal out of varyings, and both are linear across a
|
|
335
|
+
// triangle: every splat threshold came out as a straight iso-line kinking at
|
|
336
|
+
// triangle edges — big polygonal patches of flat colour — and the shading normal
|
|
337
|
+
// was faceted to match. One fetch of the field texture fixes both, and makes the
|
|
338
|
+
// mesh resolution invisible to the shading: the ground reads smooth however
|
|
339
|
+
// coarse the triangles under it are.
|
|
340
|
+
vec4 lsField = texture2D(u_lsField, lsUv);
|
|
341
|
+
float lsHeight01 = lsField.b;
|
|
342
|
+
|
|
343
|
+
// Gradient back to a world-space normal. dx and dz are the world distance one
|
|
344
|
+
// field texel spans, so the normal is correct at any size and elevation rather
|
|
345
|
+
// than only at the one it was authored for.
|
|
346
|
+
vec2 lsGrad = (lsField.rg * 2.0 - 1.0) * u_lsGradScale;
|
|
347
|
+
float lsDx = u_lsFieldTexel.x * u_lsSize;
|
|
348
|
+
float lsDz = u_lsFieldTexel.y * u_lsSize;
|
|
349
|
+
vec3 lsN = normalize(vec3(
|
|
350
|
+
-lsGrad.x * u_lsElevation * lsDz,
|
|
351
|
+
lsDx * lsDz,
|
|
352
|
+
-lsGrad.y * u_lsElevation * lsDx
|
|
353
|
+
));
|
|
354
|
+
|
|
355
|
+
// Slope as a fraction of vertical rather than 1 - n.y: the naive form is badly
|
|
356
|
+
// compressed at the angles that matter, so every threshold crowds into the top
|
|
357
|
+
// of its range and rock never appears where it should. This way 0.5 IS 45
|
|
358
|
+
// degrees. Same reasoning as the terrain material.
|
|
359
|
+
float lsSlope = acos(clamp(lsN.y, -1.0, 1.0)) * 0.63661977;
|
|
360
|
+
|
|
361
|
+
// ---- surface weights ------------------------------------------------------
|
|
362
|
+
float lsW[LS_COUNT];
|
|
363
|
+
|
|
364
|
+
#ifdef LS_AUTO
|
|
365
|
+
// Generated from the heightmap's own height and slope, so a bare heightmap with
|
|
366
|
+
// no authored splat map still renders as ground. Same rule the procedural
|
|
367
|
+
// terrain shades by: everything by height, rock by slope, rock applied last.
|
|
368
|
+
float lsHJit = lsHeight01 + (lsValueNoise(vLsWorld.xz * u_lsNoiseScale) - 0.5) * u_lsAuto.w;
|
|
369
|
+
float lsRock = smoothstep(u_lsAuto.y, u_lsAuto.z, lsSlope);
|
|
370
|
+
for (int i = 0; i < LS_COUNT; i++) {
|
|
371
|
+
float d = abs(lsHJit - u_lsAutoBands[i]);
|
|
372
|
+
lsW[i] = max(1.0 - d / max(u_lsAuto.x, 1e-3), 0.0);
|
|
373
|
+
}
|
|
374
|
+
// The last surface is the rock layer.
|
|
375
|
+
for (int i = 0; i < LS_COUNT - 1; i++) lsW[i] *= (1.0 - lsRock);
|
|
376
|
+
lsW[LS_COUNT - 1] = max(lsW[LS_COUNT - 1], lsRock);
|
|
377
|
+
#else
|
|
378
|
+
vec4 lsS0 = texture2D(u_lsSplat0, lsUv);
|
|
379
|
+
lsW[0] = lsS0.r;
|
|
380
|
+
#if LS_COUNT > 1
|
|
381
|
+
lsW[1] = lsS0.g;
|
|
382
|
+
#endif
|
|
383
|
+
#if LS_COUNT > 2
|
|
384
|
+
lsW[2] = lsS0.b;
|
|
385
|
+
#endif
|
|
386
|
+
#if LS_COUNT > 3
|
|
387
|
+
lsW[3] = lsS0.a;
|
|
388
|
+
#endif
|
|
389
|
+
#if LS_COUNT > 4
|
|
390
|
+
vec4 lsS1 = texture2D(u_lsSplat1, lsUv);
|
|
391
|
+
lsW[4] = lsS1.r;
|
|
392
|
+
#endif
|
|
393
|
+
#if LS_COUNT > 5
|
|
394
|
+
lsW[5] = lsS1.g;
|
|
395
|
+
#endif
|
|
396
|
+
#if LS_COUNT > 6
|
|
397
|
+
lsW[6] = lsS1.b;
|
|
398
|
+
#endif
|
|
399
|
+
#if LS_COUNT > 7
|
|
400
|
+
lsW[7] = lsS1.a;
|
|
401
|
+
#endif
|
|
402
|
+
#endif
|
|
403
|
+
|
|
404
|
+
// ---- pick the heaviest LS_SAMPLES ----------------------------------------
|
|
405
|
+
// Constant bounds both ways, so this unrolls. No sort, no swaps, no dynamic
|
|
406
|
+
// loop: LS_SAMPLES passes each taking the largest remaining weight.
|
|
407
|
+
int lsIdx[LS_SAMPLES];
|
|
408
|
+
float lsWt[LS_SAMPLES];
|
|
409
|
+
for (int s = 0; s < LS_SAMPLES; s++) {
|
|
410
|
+
int best = 0;
|
|
411
|
+
float bw = -1.0;
|
|
412
|
+
for (int i = 0; i < LS_COUNT; i++) {
|
|
413
|
+
if (lsW[i] > bw) { bw = lsW[i]; best = i; }
|
|
414
|
+
}
|
|
415
|
+
lsIdx[s] = best;
|
|
416
|
+
lsWt[s] = max(bw, 0.0);
|
|
417
|
+
lsW[best] = -1.0;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// ---- normals and heights, then the height blend ---------------------------
|
|
421
|
+
vec4 lsNrm[LS_SAMPLES];
|
|
422
|
+
float lsBlendRange = 1.0;
|
|
423
|
+
float lsPeak = -1e9;
|
|
424
|
+
float lsV[LS_SAMPLES];
|
|
425
|
+
|
|
426
|
+
for (int s = 0; s < LS_SAMPLES; s++) {
|
|
427
|
+
int i = lsIdx[s];
|
|
428
|
+
float repeat = u_lsSurfA[i].x;
|
|
429
|
+
vec2 uv = lsUv * repeat;
|
|
430
|
+
vec3 mean = vec3(0.5, 0.5, 1.0);
|
|
431
|
+
float stoch = u_lsSurfC[i].w;
|
|
432
|
+
vec4 n;
|
|
433
|
+
#ifdef LS_TRIPLANAR
|
|
434
|
+
if (u_lsSurfC[i].x > 0.5) {
|
|
435
|
+
n = lsSampleWorld(u_lsNormal, vLsWorld, lsN, repeat / max(u_lsSize, 1e-3), float(i), mean, stoch);
|
|
436
|
+
} else {
|
|
437
|
+
n = lsSampleArray(u_lsNormal, uv, float(i), mean, stoch);
|
|
438
|
+
}
|
|
439
|
+
#else
|
|
440
|
+
n = lsSampleArray(u_lsNormal, uv, float(i), mean, stoch);
|
|
441
|
+
#endif
|
|
442
|
+
lsNrm[s] = n;
|
|
443
|
+
|
|
444
|
+
// Height blending. Two surfaces meeting no longer cross-fade: the one whose
|
|
445
|
+
// own height map is higher at this texel wins, so gravel comes through grass
|
|
446
|
+
// along the gravel's grain. The reference loads these height maps and never
|
|
447
|
+
// samples them.
|
|
448
|
+
float hb = u_lsSurfA[i].w;
|
|
449
|
+
lsBlendRange = min(lsBlendRange, mix(1.0, 0.04, hb));
|
|
450
|
+
lsV[s] = lsWt[s] + n.a * hb;
|
|
451
|
+
lsPeak = max(lsPeak, lsV[s]);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
float lsSum = 0.0;
|
|
455
|
+
for (int s = 0; s < LS_SAMPLES; s++) {
|
|
456
|
+
lsWt[s] = max(lsV[s] - (lsPeak - lsBlendRange), 0.0);
|
|
457
|
+
lsSum += lsWt[s];
|
|
458
|
+
}
|
|
459
|
+
lsSum = max(lsSum, 1e-4);
|
|
460
|
+
for (int s = 0; s < LS_SAMPLES; s++) lsWt[s] /= lsSum;
|
|
461
|
+
|
|
462
|
+
// ---- albedo, normal, roughness -------------------------------------------
|
|
463
|
+
vec3 lsAlbedo = vec3(0.0);
|
|
464
|
+
vec3 lsNsum = vec3(0.0);
|
|
465
|
+
float lsRoughness = 0.0;
|
|
466
|
+
float lsMetalness = 0.0;
|
|
467
|
+
|
|
468
|
+
for (int s = 0; s < LS_SAMPLES; s++) {
|
|
469
|
+
int i = lsIdx[s];
|
|
470
|
+
float w = lsWt[s];
|
|
471
|
+
float repeat = u_lsSurfA[i].x;
|
|
472
|
+
vec2 uv = lsUv * repeat;
|
|
473
|
+
|
|
474
|
+
float stoch = u_lsSurfC[i].w;
|
|
475
|
+
vec4 d;
|
|
476
|
+
#ifdef LS_TRIPLANAR
|
|
477
|
+
if (u_lsSurfC[i].x > 0.5) {
|
|
478
|
+
d = lsSampleWorld(u_lsDiffuse, vLsWorld, lsN, repeat / max(u_lsSize, 1e-3), float(i), u_lsSurfMean[i], stoch);
|
|
479
|
+
} else {
|
|
480
|
+
d = lsSampleArray(u_lsDiffuse, uv, float(i), u_lsSurfMean[i], stoch);
|
|
481
|
+
}
|
|
482
|
+
#else
|
|
483
|
+
d = lsSampleArray(u_lsDiffuse, uv, float(i), u_lsSurfMean[i], stoch);
|
|
484
|
+
#endif
|
|
485
|
+
|
|
486
|
+
vec3 col = lsSaturate(d.rgb, u_lsSurfB[i].w) * u_lsSurfB[i].rgb;
|
|
487
|
+
lsAlbedo += col * w;
|
|
488
|
+
|
|
489
|
+
// Whiteout-style blend: sum the tangent-space XY, keep Z positive, normalise
|
|
490
|
+
// once at the end. The reference slerps every surface against a flat normal
|
|
491
|
+
// and then RNM-blends the result — an acos and three sines per sampled
|
|
492
|
+
// surface, per pixel.
|
|
493
|
+
vec3 m = lsNrm[s].rgb * 2.0 - 1.0;
|
|
494
|
+
m.y *= u_lsSurfC[i].y;
|
|
495
|
+
m.xy *= u_lsSurfA[i].y;
|
|
496
|
+
lsNsum += m * w;
|
|
497
|
+
|
|
498
|
+
lsRoughness += u_lsSurfA[i].z * w;
|
|
499
|
+
lsMetalness += u_lsSurfC[i].z * w;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Large-scale albedo break-up, generated rather than sampled. Without it a splat
|
|
503
|
+
// layer is one flat colour across hundreds of metres and reads as untextured;
|
|
504
|
+
// the reference ships a 2.7 MB texture to do this.
|
|
505
|
+
if (u_lsMacro > 0.001) {
|
|
506
|
+
float macro = lsValueNoise(vLsWorld.xz * u_lsMacroScale) * 0.6
|
|
507
|
+
+ lsValueNoise(vLsWorld.xz * u_lsMacroScale * 2.7) * 0.4;
|
|
508
|
+
lsAlbedo *= mix(1.0, 0.6 + macro * 0.8, u_lsMacro);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
vec3 lsMapN = normalize(vec3(lsNsum.xy, max(1.0 - length(lsNsum.xy) * 0.5, 0.05)));
|
|
512
|
+
// Tangent frame for a heightfield with axis-aligned UVs: world X, orthogonalised
|
|
513
|
+
// against the surface normal. No tangent attribute and no derivative-based TBN
|
|
514
|
+
// needed, because the mapping is known.
|
|
515
|
+
vec3 lsT = normalize(vec3(1.0, 0.0, 0.0) - lsN * lsN.x);
|
|
516
|
+
vec3 lsB = cross(lsN, lsT);
|
|
517
|
+
vec3 lsNormalW = normalize(lsT * lsMapN.x + lsB * lsMapN.y + lsN * lsMapN.z);
|
|
518
|
+
`;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bake-time noise. Runs once at startup, never per frame.
|
|
3
|
+
*
|
|
4
|
+
* Everything here is *tileable*: the hash wraps its lattice with mod(p, freq) so the
|
|
5
|
+
* volumes repeat seamlessly under RepeatWrapping. Non-tileable noise in a repeating
|
|
6
|
+
* 3D texture produces a visible grid of seams across the sky, which is the single most
|
|
7
|
+
* common giveaway in a volumetric cloud implementation.
|
|
8
|
+
*/
|
|
9
|
+
export declare const bakeCommon = "\n#define PI 3.14159265359\n#define saturate(x) clamp(x, 0.0, 1.0)\nfloat remap(float v, float a, float b, float c, float d){\n return c + (v - a) * (d - c) / max(b - a, 1e-6);\n}\n\nvec3 hash33t(vec3 p, float f){\n p = mod(p, vec3(f));\n p = fract(p * vec3(0.1031, 0.1030, 0.0973));\n p += dot(p, p.yxz + 19.19);\n return fract((p.xxy + p.yxx) * p.zyx);\n}\nvec2 hash22t(vec2 p, float f){\n p = mod(p, vec2(f));\n vec3 q = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));\n q += dot(q, q.yzx + 19.19);\n return fract((q.xx + q.yz) * q.zy);\n}\n\nfloat perlin3(vec3 x, float f){\n vec3 p = x * f;\n vec3 i = floor(p); vec3 t = p - i;\n vec3 u = t*t*t*(t*(t*6.0-15.0)+10.0);\n float n000 = dot(hash33t(i+vec3(0,0,0),f)*2.0-1.0, t-vec3(0,0,0));\n float n100 = dot(hash33t(i+vec3(1,0,0),f)*2.0-1.0, t-vec3(1,0,0));\n float n010 = dot(hash33t(i+vec3(0,1,0),f)*2.0-1.0, t-vec3(0,1,0));\n float n110 = dot(hash33t(i+vec3(1,1,0),f)*2.0-1.0, t-vec3(1,1,0));\n float n001 = dot(hash33t(i+vec3(0,0,1),f)*2.0-1.0, t-vec3(0,0,1));\n float n101 = dot(hash33t(i+vec3(1,0,1),f)*2.0-1.0, t-vec3(1,0,1));\n float n011 = dot(hash33t(i+vec3(0,1,1),f)*2.0-1.0, t-vec3(0,1,1));\n float n111 = dot(hash33t(i+vec3(1,1,1),f)*2.0-1.0, t-vec3(1,1,1));\n float x00 = mix(n000,n100,u.x), x10 = mix(n010,n110,u.x);\n float x01 = mix(n001,n101,u.x), x11 = mix(n011,n111,u.x);\n return mix(mix(x00,x10,u.y), mix(x01,x11,u.y), u.z);\n}\n\nfloat perlin2(vec2 x, float f){\n vec2 p = x * f;\n vec2 i = floor(p); vec2 t = p - i;\n vec2 u = t*t*t*(t*(t*6.0-15.0)+10.0);\n float n00 = dot(hash22t(i+vec2(0,0),f)*2.0-1.0, t-vec2(0,0));\n float n10 = dot(hash22t(i+vec2(1,0),f)*2.0-1.0, t-vec2(1,0));\n float n01 = dot(hash22t(i+vec2(0,1),f)*2.0-1.0, t-vec2(0,1));\n float n11 = dot(hash22t(i+vec2(1,1),f)*2.0-1.0, t-vec2(1,1));\n return mix(mix(n00,n10,u.x), mix(n01,n11,u.x), u.y);\n}\n\nfloat worley3(vec3 x, float f){\n vec3 p = x * f;\n vec3 i = floor(p); vec3 t = p - i;\n float md = 1e9;\n for(int z=-1; z<=1; z++)\n for(int y=-1; y<=1; y++)\n for(int w=-1; w<=1; w++){\n vec3 o = vec3(float(w), float(y), float(z));\n vec3 h = hash33t(i + o, f);\n vec3 d = o + h - t;\n md = min(md, dot(d, d));\n }\n return saturate(sqrt(md));\n}\n";
|
|
10
|
+
export declare const bakeVertex = "\nout vec2 vUv;\nvoid main(){ vUv = uv; gl_Position = vec4(position.xy, 0.0, 1.0); }\n";
|
|
11
|
+
/**
|
|
12
|
+
* Base shape, 128³ RGBA.
|
|
13
|
+
* R = Perlin-Worley (Schneider): perlin fbm remapped by an inverted-worley fbm, which
|
|
14
|
+
* gives billowy tops without losing perlin's connectedness.
|
|
15
|
+
* G/B/A = inverted worley at 4 / 8 / 16, recombined in the march as the low-frequency
|
|
16
|
+
* fbm that erodes R.
|
|
17
|
+
*/
|
|
18
|
+
export declare const bakeBaseFrag = "\n\n#define PI 3.14159265359\n#define saturate(x) clamp(x, 0.0, 1.0)\nfloat remap(float v, float a, float b, float c, float d){\n return c + (v - a) * (d - c) / max(b - a, 1e-6);\n}\n\nvec3 hash33t(vec3 p, float f){\n p = mod(p, vec3(f));\n p = fract(p * vec3(0.1031, 0.1030, 0.0973));\n p += dot(p, p.yxz + 19.19);\n return fract((p.xxy + p.yxx) * p.zyx);\n}\nvec2 hash22t(vec2 p, float f){\n p = mod(p, vec2(f));\n vec3 q = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));\n q += dot(q, q.yzx + 19.19);\n return fract((q.xx + q.yz) * q.zy);\n}\n\nfloat perlin3(vec3 x, float f){\n vec3 p = x * f;\n vec3 i = floor(p); vec3 t = p - i;\n vec3 u = t*t*t*(t*(t*6.0-15.0)+10.0);\n float n000 = dot(hash33t(i+vec3(0,0,0),f)*2.0-1.0, t-vec3(0,0,0));\n float n100 = dot(hash33t(i+vec3(1,0,0),f)*2.0-1.0, t-vec3(1,0,0));\n float n010 = dot(hash33t(i+vec3(0,1,0),f)*2.0-1.0, t-vec3(0,1,0));\n float n110 = dot(hash33t(i+vec3(1,1,0),f)*2.0-1.0, t-vec3(1,1,0));\n float n001 = dot(hash33t(i+vec3(0,0,1),f)*2.0-1.0, t-vec3(0,0,1));\n float n101 = dot(hash33t(i+vec3(1,0,1),f)*2.0-1.0, t-vec3(1,0,1));\n float n011 = dot(hash33t(i+vec3(0,1,1),f)*2.0-1.0, t-vec3(0,1,1));\n float n111 = dot(hash33t(i+vec3(1,1,1),f)*2.0-1.0, t-vec3(1,1,1));\n float x00 = mix(n000,n100,u.x), x10 = mix(n010,n110,u.x);\n float x01 = mix(n001,n101,u.x), x11 = mix(n011,n111,u.x);\n return mix(mix(x00,x10,u.y), mix(x01,x11,u.y), u.z);\n}\n\nfloat perlin2(vec2 x, float f){\n vec2 p = x * f;\n vec2 i = floor(p); vec2 t = p - i;\n vec2 u = t*t*t*(t*(t*6.0-15.0)+10.0);\n float n00 = dot(hash22t(i+vec2(0,0),f)*2.0-1.0, t-vec2(0,0));\n float n10 = dot(hash22t(i+vec2(1,0),f)*2.0-1.0, t-vec2(1,0));\n float n01 = dot(hash22t(i+vec2(0,1),f)*2.0-1.0, t-vec2(0,1));\n float n11 = dot(hash22t(i+vec2(1,1),f)*2.0-1.0, t-vec2(1,1));\n return mix(mix(n00,n10,u.x), mix(n01,n11,u.x), u.y);\n}\n\nfloat worley3(vec3 x, float f){\n vec3 p = x * f;\n vec3 i = floor(p); vec3 t = p - i;\n float md = 1e9;\n for(int z=-1; z<=1; z++)\n for(int y=-1; y<=1; y++)\n for(int w=-1; w<=1; w++){\n vec3 o = vec3(float(w), float(y), float(z));\n vec3 h = hash33t(i + o, f);\n vec3 d = o + h - t;\n md = min(md, dot(d, d));\n }\n return saturate(sqrt(md));\n}\n\n\nin vec2 vUv;\nout vec4 outColor;\n\n\nuniform vec2 u_atlas;\nuniform float u_tiles;\nuniform float u_res;\nvec3 volCoord(){\n vec2 px = floor(vUv * u_atlas);\n vec2 tile = floor(px / u_res);\n float z = tile.y * u_tiles + tile.x;\n vec2 xy = px - tile * u_res;\n return (vec3(xy, z) + 0.5) / u_res;\n}\n\nvoid main(){\n vec3 p = volCoord();\n float pf = perlin3(p, 4.0) * 0.5 + perlin3(p, 8.0) * 0.25\n + perlin3(p, 16.0) * 0.125 + perlin3(p, 32.0) * 0.0625;\n pf = saturate(pf * 1.35 + 0.5);\n float w4 = 1.0 - worley3(p, 4.0);\n float w8 = 1.0 - worley3(p, 8.0);\n float w16 = 1.0 - worley3(p, 16.0);\n float wfbm = saturate(w4 * 0.625 + w8 * 0.25 + w16 * 0.125);\n outColor = vec4(saturate(remap(pf, wfbm - 1.0, 1.0, 0.0, 1.0)), w4, w8, w16);\n}\n";
|
|
19
|
+
/** Detail erosion, 64³ RGB inverted worley at 4 / 8 / 16. */
|
|
20
|
+
export declare const bakeDetailFrag = "\n\n#define PI 3.14159265359\n#define saturate(x) clamp(x, 0.0, 1.0)\nfloat remap(float v, float a, float b, float c, float d){\n return c + (v - a) * (d - c) / max(b - a, 1e-6);\n}\n\nvec3 hash33t(vec3 p, float f){\n p = mod(p, vec3(f));\n p = fract(p * vec3(0.1031, 0.1030, 0.0973));\n p += dot(p, p.yxz + 19.19);\n return fract((p.xxy + p.yxx) * p.zyx);\n}\nvec2 hash22t(vec2 p, float f){\n p = mod(p, vec2(f));\n vec3 q = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));\n q += dot(q, q.yzx + 19.19);\n return fract((q.xx + q.yz) * q.zy);\n}\n\nfloat perlin3(vec3 x, float f){\n vec3 p = x * f;\n vec3 i = floor(p); vec3 t = p - i;\n vec3 u = t*t*t*(t*(t*6.0-15.0)+10.0);\n float n000 = dot(hash33t(i+vec3(0,0,0),f)*2.0-1.0, t-vec3(0,0,0));\n float n100 = dot(hash33t(i+vec3(1,0,0),f)*2.0-1.0, t-vec3(1,0,0));\n float n010 = dot(hash33t(i+vec3(0,1,0),f)*2.0-1.0, t-vec3(0,1,0));\n float n110 = dot(hash33t(i+vec3(1,1,0),f)*2.0-1.0, t-vec3(1,1,0));\n float n001 = dot(hash33t(i+vec3(0,0,1),f)*2.0-1.0, t-vec3(0,0,1));\n float n101 = dot(hash33t(i+vec3(1,0,1),f)*2.0-1.0, t-vec3(1,0,1));\n float n011 = dot(hash33t(i+vec3(0,1,1),f)*2.0-1.0, t-vec3(0,1,1));\n float n111 = dot(hash33t(i+vec3(1,1,1),f)*2.0-1.0, t-vec3(1,1,1));\n float x00 = mix(n000,n100,u.x), x10 = mix(n010,n110,u.x);\n float x01 = mix(n001,n101,u.x), x11 = mix(n011,n111,u.x);\n return mix(mix(x00,x10,u.y), mix(x01,x11,u.y), u.z);\n}\n\nfloat perlin2(vec2 x, float f){\n vec2 p = x * f;\n vec2 i = floor(p); vec2 t = p - i;\n vec2 u = t*t*t*(t*(t*6.0-15.0)+10.0);\n float n00 = dot(hash22t(i+vec2(0,0),f)*2.0-1.0, t-vec2(0,0));\n float n10 = dot(hash22t(i+vec2(1,0),f)*2.0-1.0, t-vec2(1,0));\n float n01 = dot(hash22t(i+vec2(0,1),f)*2.0-1.0, t-vec2(0,1));\n float n11 = dot(hash22t(i+vec2(1,1),f)*2.0-1.0, t-vec2(1,1));\n return mix(mix(n00,n10,u.x), mix(n01,n11,u.x), u.y);\n}\n\nfloat worley3(vec3 x, float f){\n vec3 p = x * f;\n vec3 i = floor(p); vec3 t = p - i;\n float md = 1e9;\n for(int z=-1; z<=1; z++)\n for(int y=-1; y<=1; y++)\n for(int w=-1; w<=1; w++){\n vec3 o = vec3(float(w), float(y), float(z));\n vec3 h = hash33t(i + o, f);\n vec3 d = o + h - t;\n md = min(md, dot(d, d));\n }\n return saturate(sqrt(md));\n}\n\n\nin vec2 vUv;\nout vec4 outColor;\n\n\nuniform vec2 u_atlas;\nuniform float u_tiles;\nuniform float u_res;\nvec3 volCoord(){\n vec2 px = floor(vUv * u_atlas);\n vec2 tile = floor(px / u_res);\n float z = tile.y * u_tiles + tile.x;\n vec2 xy = px - tile * u_res;\n return (vec3(xy, z) + 0.5) / u_res;\n}\n\nvoid main(){\n vec3 p = volCoord();\n outColor = vec4(1.0 - worley3(p, 4.0), 1.0 - worley3(p, 8.0), 1.0 - worley3(p, 16.0), 1.0);\n}\n";
|
|
21
|
+
/**
|
|
22
|
+
* Weather map, 512² RGBA. Domain-warped so cell edges are not perlin-round.
|
|
23
|
+
* The warp offsets are themselves tileable, so the map still wraps exactly.
|
|
24
|
+
* R = coverage, low frequency B = cloud type bias
|
|
25
|
+
* G = coverage, high frequency A = precipitation
|
|
26
|
+
*/
|
|
27
|
+
export declare const bakeWeatherFrag = "\n\n#define PI 3.14159265359\n#define saturate(x) clamp(x, 0.0, 1.0)\nfloat remap(float v, float a, float b, float c, float d){\n return c + (v - a) * (d - c) / max(b - a, 1e-6);\n}\n\nvec3 hash33t(vec3 p, float f){\n p = mod(p, vec3(f));\n p = fract(p * vec3(0.1031, 0.1030, 0.0973));\n p += dot(p, p.yxz + 19.19);\n return fract((p.xxy + p.yxx) * p.zyx);\n}\nvec2 hash22t(vec2 p, float f){\n p = mod(p, vec2(f));\n vec3 q = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));\n q += dot(q, q.yzx + 19.19);\n return fract((q.xx + q.yz) * q.zy);\n}\n\nfloat perlin3(vec3 x, float f){\n vec3 p = x * f;\n vec3 i = floor(p); vec3 t = p - i;\n vec3 u = t*t*t*(t*(t*6.0-15.0)+10.0);\n float n000 = dot(hash33t(i+vec3(0,0,0),f)*2.0-1.0, t-vec3(0,0,0));\n float n100 = dot(hash33t(i+vec3(1,0,0),f)*2.0-1.0, t-vec3(1,0,0));\n float n010 = dot(hash33t(i+vec3(0,1,0),f)*2.0-1.0, t-vec3(0,1,0));\n float n110 = dot(hash33t(i+vec3(1,1,0),f)*2.0-1.0, t-vec3(1,1,0));\n float n001 = dot(hash33t(i+vec3(0,0,1),f)*2.0-1.0, t-vec3(0,0,1));\n float n101 = dot(hash33t(i+vec3(1,0,1),f)*2.0-1.0, t-vec3(1,0,1));\n float n011 = dot(hash33t(i+vec3(0,1,1),f)*2.0-1.0, t-vec3(0,1,1));\n float n111 = dot(hash33t(i+vec3(1,1,1),f)*2.0-1.0, t-vec3(1,1,1));\n float x00 = mix(n000,n100,u.x), x10 = mix(n010,n110,u.x);\n float x01 = mix(n001,n101,u.x), x11 = mix(n011,n111,u.x);\n return mix(mix(x00,x10,u.y), mix(x01,x11,u.y), u.z);\n}\n\nfloat perlin2(vec2 x, float f){\n vec2 p = x * f;\n vec2 i = floor(p); vec2 t = p - i;\n vec2 u = t*t*t*(t*(t*6.0-15.0)+10.0);\n float n00 = dot(hash22t(i+vec2(0,0),f)*2.0-1.0, t-vec2(0,0));\n float n10 = dot(hash22t(i+vec2(1,0),f)*2.0-1.0, t-vec2(1,0));\n float n01 = dot(hash22t(i+vec2(0,1),f)*2.0-1.0, t-vec2(0,1));\n float n11 = dot(hash22t(i+vec2(1,1),f)*2.0-1.0, t-vec2(1,1));\n return mix(mix(n00,n10,u.x), mix(n01,n11,u.x), u.y);\n}\n\nfloat worley3(vec3 x, float f){\n vec3 p = x * f;\n vec3 i = floor(p); vec3 t = p - i;\n float md = 1e9;\n for(int z=-1; z<=1; z++)\n for(int y=-1; y<=1; y++)\n for(int w=-1; w<=1; w++){\n vec3 o = vec3(float(w), float(y), float(z));\n vec3 h = hash33t(i + o, f);\n vec3 d = o + h - t;\n md = min(md, dot(d, d));\n }\n return saturate(sqrt(md));\n}\n\n\nin vec2 vUv;\nout vec4 outColor;\n\nvoid main(){\n vec2 q = vUv;\n vec2 w = vec2(perlin2(q, 3.0), perlin2(q + vec2(0.37, 0.11), 3.0));\n vec2 qw = q + w * 0.11;\n float c1 = perlin2(qw, 3.0) * 0.60 + perlin2(qw, 6.0) * 0.28 + perlin2(qw, 12.0) * 0.12;\n float c2 = perlin2(qw, 7.0) * 0.52 + perlin2(qw, 14.0) * 0.30 + perlin2(qw, 28.0) * 0.18;\n float ty = perlin2(q + vec2(5.1, 2.3), 2.0);\n float pr = perlin2(q + vec2(1.7, 8.2), 5.0) * 0.7 + perlin2(q + vec2(1.7, 8.2), 10.0) * 0.3;\n outColor = vec4(\n saturate(c1 * 1.55 + 0.5),\n saturate(c2 * 1.60 + 0.5),\n saturate(ty * 1.60 + 0.5),\n saturate(pr * 1.60 + 0.5)\n );\n}\n";
|
|
28
|
+
/** Curl field, 128² RG. Curl of a scalar fbm — divergence free, so it swirls rather than pushes. */
|
|
29
|
+
export declare const bakeCurlFrag = "\n\n#define PI 3.14159265359\n#define saturate(x) clamp(x, 0.0, 1.0)\nfloat remap(float v, float a, float b, float c, float d){\n return c + (v - a) * (d - c) / max(b - a, 1e-6);\n}\n\nvec3 hash33t(vec3 p, float f){\n p = mod(p, vec3(f));\n p = fract(p * vec3(0.1031, 0.1030, 0.0973));\n p += dot(p, p.yxz + 19.19);\n return fract((p.xxy + p.yxx) * p.zyx);\n}\nvec2 hash22t(vec2 p, float f){\n p = mod(p, vec2(f));\n vec3 q = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));\n q += dot(q, q.yzx + 19.19);\n return fract((q.xx + q.yz) * q.zy);\n}\n\nfloat perlin3(vec3 x, float f){\n vec3 p = x * f;\n vec3 i = floor(p); vec3 t = p - i;\n vec3 u = t*t*t*(t*(t*6.0-15.0)+10.0);\n float n000 = dot(hash33t(i+vec3(0,0,0),f)*2.0-1.0, t-vec3(0,0,0));\n float n100 = dot(hash33t(i+vec3(1,0,0),f)*2.0-1.0, t-vec3(1,0,0));\n float n010 = dot(hash33t(i+vec3(0,1,0),f)*2.0-1.0, t-vec3(0,1,0));\n float n110 = dot(hash33t(i+vec3(1,1,0),f)*2.0-1.0, t-vec3(1,1,0));\n float n001 = dot(hash33t(i+vec3(0,0,1),f)*2.0-1.0, t-vec3(0,0,1));\n float n101 = dot(hash33t(i+vec3(1,0,1),f)*2.0-1.0, t-vec3(1,0,1));\n float n011 = dot(hash33t(i+vec3(0,1,1),f)*2.0-1.0, t-vec3(0,1,1));\n float n111 = dot(hash33t(i+vec3(1,1,1),f)*2.0-1.0, t-vec3(1,1,1));\n float x00 = mix(n000,n100,u.x), x10 = mix(n010,n110,u.x);\n float x01 = mix(n001,n101,u.x), x11 = mix(n011,n111,u.x);\n return mix(mix(x00,x10,u.y), mix(x01,x11,u.y), u.z);\n}\n\nfloat perlin2(vec2 x, float f){\n vec2 p = x * f;\n vec2 i = floor(p); vec2 t = p - i;\n vec2 u = t*t*t*(t*(t*6.0-15.0)+10.0);\n float n00 = dot(hash22t(i+vec2(0,0),f)*2.0-1.0, t-vec2(0,0));\n float n10 = dot(hash22t(i+vec2(1,0),f)*2.0-1.0, t-vec2(1,0));\n float n01 = dot(hash22t(i+vec2(0,1),f)*2.0-1.0, t-vec2(0,1));\n float n11 = dot(hash22t(i+vec2(1,1),f)*2.0-1.0, t-vec2(1,1));\n return mix(mix(n00,n10,u.x), mix(n01,n11,u.x), u.y);\n}\n\nfloat worley3(vec3 x, float f){\n vec3 p = x * f;\n vec3 i = floor(p); vec3 t = p - i;\n float md = 1e9;\n for(int z=-1; z<=1; z++)\n for(int y=-1; y<=1; y++)\n for(int w=-1; w<=1; w++){\n vec3 o = vec3(float(w), float(y), float(z));\n vec3 h = hash33t(i + o, f);\n vec3 d = o + h - t;\n md = min(md, dot(d, d));\n }\n return saturate(sqrt(md));\n}\n\n\nin vec2 vUv;\nout vec4 outColor;\n\nfloat fld(vec2 q){ return perlin2(q, 6.0) * 0.6 + perlin2(q, 12.0) * 0.3 + perlin2(q, 24.0) * 0.15; }\nvoid main(){\n float e = 1.0 / 128.0;\n float dx = fld(vUv + vec2(e, 0.0)) - fld(vUv - vec2(e, 0.0));\n float dy = fld(vUv + vec2(0.0, e)) - fld(vUv - vec2(0.0, e));\n vec2 c = clamp(vec2(dy, -dx) / (2.0 * e) / 26.0, -1.0, 1.0);\n outColor = vec4(c * 0.5 + 0.5, 0.0, 1.0);\n}\n";
|
|
30
|
+
//# sourceMappingURL=noiseBake.glsl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noiseBake.glsl.d.ts","sourceRoot":"","sources":["../../../src/shaders/glsl/noiseBake.glsl.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,UAAU,mtEA8DtB,CAAA;AAED,eAAO,MAAM,UAAU,2FAGtB,CAAA;AAsBD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,w+FAexB,CAAA;AAED,6DAA6D;AAC7D,eAAO,MAAM,cAAc,6pFAQ1B,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,o2FAkB3B,CAAA;AAED,oGAAoG;AACpG,eAAO,MAAM,YAAY,8nFAWxB,CAAA"}
|