@absolutejs/rendering 0.4.0 → 0.5.0

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/README.md CHANGED
@@ -131,3 +131,15 @@ owned textures separately. Standard lighting, shadows and geometry stay intact.
131
131
  With color, normal and roughness present, the shader uses nine texture samples
132
132
  instead of three UV samples, with no extra draw or render pass. Hardware cost is
133
133
  scene-dependent; the qualification uses software rendering, not a hardware FPS claim.
134
+
135
+ ### Thin foliage
136
+
137
+ `createThinFoliageMaterial({ leafTransmission: 0.35 })` creates a standard
138
+ material with approximate thin-leaf backlighting. Transmission is a bounded
139
+ fraction (0–1) of direct diffuse; zero retains standard lighting. The shader
140
+ uses Three's shadowed incident light, preserving PBR specular, indirect lighting,
141
+ fog and tone mapping. Area lights retain standard lighting. This is a lightweight
142
+ leaf approximation, not volumetric subsurface scattering or a complete grass
143
+ renderer. Distribution, blade shape, wind and terrain integration remain the
144
+ caller's responsibility. Compose custom shader hooks after the factory hook;
145
+ use `cloneRenderMaterial` to preserve them when cloning.
package/dist/index.d.ts CHANGED
@@ -14,3 +14,5 @@ export declare function cloneRenderMaterial<T extends Material>(source: T): T;
14
14
  export { renderTargetScope, readTargetPixelsScoped, readFloatTargetScoped, } from "./renderTargetScope.js";
15
15
  export { createObjectTriplanarMaterial } from "./objectTriplanar.js";
16
16
  export type { ObjectTriplanarProjection, ObjectTriplanarMaterialParameters, } from "./objectTriplanar.js";
17
+ export { createThinFoliageMaterial } from './thinFoliage.js';
18
+ export type { ThinFoliageMaterialParameters } from './thinFoliage.js';
package/dist/index.js CHANGED
@@ -77,3 +77,4 @@ export function cloneRenderMaterial(source) {
77
77
  }
78
78
  export { renderTargetScope, readTargetPixelsScoped, readFloatTargetScoped, } from "./renderTargetScope.js";
79
79
  export { createObjectTriplanarMaterial } from "./objectTriplanar.js";
80
+ export { createThinFoliageMaterial } from './thinFoliage.js';
@@ -0,0 +1,11 @@
1
+ import { MeshStandardMaterial, type MeshStandardMaterialParameters } from 'three';
2
+ export type ThinFoliageMaterialParameters = MeshStandardMaterialParameters & {
3
+ /** Fraction of direct diffuse allocated to approximate leaf transmission, 0..1. */
4
+ leafTransmission?: number;
5
+ };
6
+ /** Approximate thin-leaf backlighting using Three's already shadowed direct light.
7
+ * Not volumetric transmission. No extra render pass, texture, or animation loop.
8
+ * Area-light and environment paths retain standard shading. Use
9
+ * cloneRenderMaterial to preserve shader hooks when cloning.
10
+ */
11
+ export declare function createThinFoliageMaterial(options?: ThinFoliageMaterialParameters): MeshStandardMaterial;
@@ -0,0 +1,34 @@
1
+ import { DoubleSide, MeshStandardMaterial } from 'three';
2
+ /** Approximate thin-leaf backlighting using Three's already shadowed direct light.
3
+ * Not volumetric transmission. No extra render pass, texture, or animation loop.
4
+ * Area-light and environment paths retain standard shading. Use
5
+ * cloneRenderMaterial to preserve shader hooks when cloning.
6
+ */
7
+ export function createThinFoliageMaterial(options = {}) {
8
+ const { leafTransmission = 0.35, ...parameters } = options;
9
+ if (!Number.isFinite(leafTransmission) || leafTransmission < 0 || leafTransmission > 1)
10
+ throw Error('Invalid leaf transmission');
11
+ const material = new MeshStandardMaterial({ side: DoubleSide, roughness: 0.85, ...parameters });
12
+ material.onBeforeCompile = shader => {
13
+ const anchor = '#include <lights_physical_pars_fragment>';
14
+ if (shader.fragmentShader.split(anchor).length !== 2)
15
+ throw Error('Unsupported thin-foliage shader');
16
+ shader.uniforms.absLeafTransmission = { value: leafTransmission };
17
+ shader.fragmentShader = shader.fragmentShader.replace(anchor, `${anchor}
18
+ uniform float absLeafTransmission;
19
+ void absLeafDirect(const in IncidentLight light, const in vec3 p, const in vec3 n,
20
+ const in vec3 v, const in vec3 coatN, const in PhysicalMaterial m, inout ReflectedLight result) {
21
+ vec3 previousDiffuse=result.directDiffuse;
22
+ RE_Direct_Physical(light,p,n,v,coatN,m,result);
23
+ float through=max(0.,dot(-n,light.direction));
24
+ float forward=max(0.,dot(v,-light.direction));
25
+ vec3 transmitted=light.color*BRDF_Lambert(m.diffuseColor)*through*(.5+.5*forward*forward);
26
+ result.directDiffuse=previousDiffuse+mix(result.directDiffuse-previousDiffuse,transmitted,absLeafTransmission);
27
+ }
28
+ #undef RE_Direct
29
+ #define RE_Direct absLeafDirect
30
+ `);
31
+ };
32
+ material.customProgramCacheKey = () => `absolute-thin-foliage-1:${leafTransmission}`;
33
+ return material;
34
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/rendering",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Three.js material ownership, destination coverage, rigid-object triplanar mapping and isolated React Spring hosts.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -38,7 +38,8 @@
38
38
  "check:package": "bun run build && bun run test",
39
39
  "test:browser": "bun scripts/verify-browser.cjs",
40
40
  "test:spring:browser": "bun scripts/verify-spring.cjs",
41
- "test:triplanar:browser": "bun scripts/verify-triplanar.cjs"
41
+ "test:triplanar:browser": "bun scripts/verify-triplanar.cjs",
42
+ "test:foliage:browser": "bun scripts/verify-foliage.cjs"
42
43
  },
43
44
  "peerDependencies": {
44
45
  "three": ">=0.186.0 <0.187.0",