feat(environment): vary grass density by procedural zones
This commit is contained in:
@@ -152,6 +152,16 @@ function createGrassMaterial(
|
|||||||
uClumpFrequency: { value: GRASS_CONFIG.clumpFrequency },
|
uClumpFrequency: { value: GRASS_CONFIG.clumpFrequency },
|
||||||
uClumpThreshold: { value: GRASS_CONFIG.clumpThreshold },
|
uClumpThreshold: { value: GRASS_CONFIG.clumpThreshold },
|
||||||
uClumpSoftness: { value: GRASS_CONFIG.clumpSoftness },
|
uClumpSoftness: { value: GRASS_CONFIG.clumpSoftness },
|
||||||
|
uZoneFrequency: { value: GRASS_CONFIG.zoneFrequency },
|
||||||
|
uSparseZoneThreshold: { value: GRASS_CONFIG.sparseZoneThreshold },
|
||||||
|
uTallZoneThreshold: { value: GRASS_CONFIG.tallZoneThreshold },
|
||||||
|
uZoneSoftness: { value: GRASS_CONFIG.zoneSoftness },
|
||||||
|
uSparseZoneHeight: { value: GRASS_CONFIG.sparseZoneHeight },
|
||||||
|
uLowZoneHeight: { value: GRASS_CONFIG.lowZoneHeight },
|
||||||
|
uTallZoneHeight: { value: GRASS_CONFIG.tallZoneHeight },
|
||||||
|
uSparseZoneDensity: { value: GRASS_CONFIG.sparseZoneDensity },
|
||||||
|
uLowZoneDensity: { value: GRASS_CONFIG.lowZoneDensity },
|
||||||
|
uTallZoneDensity: { value: GRASS_CONFIG.tallZoneDensity },
|
||||||
uMaxBendAngle: { value: GRASS_CONFIG.maxBendAngle },
|
uMaxBendAngle: { value: GRASS_CONFIG.maxBendAngle },
|
||||||
uMaxBladeHeight: { value: GRASS_CONFIG.maxBladeHeight },
|
uMaxBladeHeight: { value: GRASS_CONFIG.maxBladeHeight },
|
||||||
uRandomHeightAmount: { value: GRASS_CONFIG.randomHeightAmount },
|
uRandomHeightAmount: { value: GRASS_CONFIG.randomHeightAmount },
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ export const GRASS_CONFIG = {
|
|||||||
patchSize: 30,
|
patchSize: 30,
|
||||||
bladeCount: 32000,
|
bladeCount: 32000,
|
||||||
bladeWidth: 0.08,
|
bladeWidth: 0.08,
|
||||||
maxBladeHeight: 0.36,
|
maxBladeHeight: 0.56,
|
||||||
randomHeightAmount: 0.25,
|
randomHeightAmount: 0.25,
|
||||||
surfaceOffset: 0.025,
|
surfaceOffset: 0.025,
|
||||||
heightTextureSize: 128,
|
heightTextureSize: 128,
|
||||||
@@ -16,6 +16,16 @@ export const GRASS_CONFIG = {
|
|||||||
clumpFrequency: 2.6,
|
clumpFrequency: 2.6,
|
||||||
clumpThreshold: 0.18,
|
clumpThreshold: 0.18,
|
||||||
clumpSoftness: 0.45,
|
clumpSoftness: 0.45,
|
||||||
|
zoneFrequency: 0.035,
|
||||||
|
sparseZoneThreshold: 0.4,
|
||||||
|
tallZoneThreshold: 0.8,
|
||||||
|
zoneSoftness: 0.08,
|
||||||
|
sparseZoneHeight: 0.08,
|
||||||
|
lowZoneHeight: 0.45,
|
||||||
|
tallZoneHeight: 1,
|
||||||
|
sparseZoneDensity: 0.08,
|
||||||
|
lowZoneDensity: 0.72,
|
||||||
|
tallZoneDensity: 1,
|
||||||
maxBendAngle: 14,
|
maxBendAngle: 14,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,16 @@ export const grassVertexShader = /* glsl */ `
|
|||||||
uniform float uClumpFrequency;
|
uniform float uClumpFrequency;
|
||||||
uniform float uClumpThreshold;
|
uniform float uClumpThreshold;
|
||||||
uniform float uClumpSoftness;
|
uniform float uClumpSoftness;
|
||||||
|
uniform float uZoneFrequency;
|
||||||
|
uniform float uSparseZoneThreshold;
|
||||||
|
uniform float uTallZoneThreshold;
|
||||||
|
uniform float uZoneSoftness;
|
||||||
|
uniform float uSparseZoneHeight;
|
||||||
|
uniform float uLowZoneHeight;
|
||||||
|
uniform float uTallZoneHeight;
|
||||||
|
uniform float uSparseZoneDensity;
|
||||||
|
uniform float uLowZoneDensity;
|
||||||
|
uniform float uTallZoneDensity;
|
||||||
uniform float uMaxBendAngle;
|
uniform float uMaxBendAngle;
|
||||||
uniform float uMaxBladeHeight;
|
uniform float uMaxBladeHeight;
|
||||||
uniform float uRandomHeightAmount;
|
uniform float uRandomHeightAmount;
|
||||||
@@ -77,9 +87,23 @@ export const grassVertexShader = /* glsl */ `
|
|||||||
vec2 clumpUv = (worldPos.xz / uPatchSize) * uClumpFrequency;
|
vec2 clumpUv = (worldPos.xz / uPatchSize) * uClumpFrequency;
|
||||||
float clumpNoise = texture2D(uNoiseTexture, clumpUv).r;
|
float clumpNoise = texture2D(uNoiseTexture, clumpUv).r;
|
||||||
float clumpMask = smoothstep(uClumpThreshold, uClumpThreshold + uClumpSoftness, clumpNoise);
|
float clumpMask = smoothstep(uClumpThreshold, uClumpThreshold + uClumpSoftness, clumpNoise);
|
||||||
|
float zoneNoise = texture2D(uNoiseTexture, worldPos.xz * uZoneFrequency).r;
|
||||||
|
float sparseZone = 1.0 - smoothstep(uSparseZoneThreshold, uSparseZoneThreshold + uZoneSoftness, zoneNoise);
|
||||||
|
float tallZone = smoothstep(uTallZoneThreshold, uTallZoneThreshold + uZoneSoftness, zoneNoise);
|
||||||
|
float midZone = clamp(1.0 - sparseZone - tallZone, 0.0, 1.0);
|
||||||
|
float zoneHeight =
|
||||||
|
sparseZone * uSparseZoneHeight +
|
||||||
|
midZone * uLowZoneHeight +
|
||||||
|
tallZone * uTallZoneHeight;
|
||||||
|
float zoneDensity =
|
||||||
|
sparseZone * uSparseZoneDensity +
|
||||||
|
midZone * uLowZoneDensity +
|
||||||
|
tallZone * uTallZoneDensity;
|
||||||
|
float bladeVisibility = step(random(worldPos.xz), zoneDensity);
|
||||||
float heightModifier = uMaxBladeHeight * mix(0.35, 1.0, heightNoiseAverage) * uHeightNoiseAmplitude;
|
float heightModifier = uMaxBladeHeight * mix(0.35, 1.0, heightNoiseAverage) * uHeightNoiseAmplitude;
|
||||||
heightModifier += random(terrainUv) * (uRandomHeightAmount * 0.1);
|
heightModifier += random(terrainUv) * (uRandomHeightAmount * 0.1);
|
||||||
heightModifier = clamp(heightModifier, 0.0, uMaxBladeHeight);
|
heightModifier = clamp(heightModifier, 0.0, uMaxBladeHeight);
|
||||||
|
heightModifier *= zoneHeight * bladeVisibility;
|
||||||
|
|
||||||
float edgeDistanceX = abs(origin.x) / halfPatchSize;
|
float edgeDistanceX = abs(origin.x) / halfPatchSize;
|
||||||
float edgeDistanceZ = abs(origin.z) / halfPatchSize;
|
float edgeDistanceZ = abs(origin.z) / halfPatchSize;
|
||||||
@@ -99,7 +123,7 @@ export const grassVertexShader = /* glsl */ `
|
|||||||
|
|
||||||
float sideFactor = (color.r == 0.1) ? 1.0 : (color.b == 0.1) ? -1.0 : 0.0;
|
float sideFactor = (color.r == 0.1) ? 1.0 : (color.b == 0.1) ? -1.0 : 0.0;
|
||||||
float tipFactor = color.g;
|
float tipFactor = color.g;
|
||||||
float width = smoothstep(0.02, uMaxBladeHeight * 0.85, heightModifier) * uBladeWidth;
|
float width = smoothstep(0.02, uMaxBladeHeight * 0.85, heightModifier) * uBladeWidth * bladeVisibility;
|
||||||
transformed += aYaw * (width / 2.0) * sideFactor;
|
transformed += aYaw * (width / 2.0) * sideFactor;
|
||||||
|
|
||||||
vec3 textureColor = texture2D(uDiffuseMap, terrainUv * 10.0).rgb;
|
vec3 textureColor = texture2D(uDiffuseMap, terrainUv * 10.0).rgb;
|
||||||
|
|||||||
Reference in New Issue
Block a user