lecodes-cli 2.4.10 → 2.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/dist/index.js +2510 -1035
- package/package.json +10 -10
- package/runtime/materials/decal-relief.mat +21 -46
- package/runtime/materials/decal.mat +41 -61
- package/runtime/materials/foliage-cards.mat +28 -140
- package/runtime/materials/foliage-impostor.mat +485 -0
- package/runtime/materials/foliage.mat +232 -0
- package/runtime/materials/grass.mat +244 -0
- package/runtime/materials/particles-quad.mat +5 -3
- package/runtime/materials/particles.mat +5 -3
- package/runtime/sdk-types.json +1 -1
- package/runtime/web/VERSION.json +3 -3
- package/runtime/web/assets/materials-Cs_z1zLi.bin +0 -0
- package/runtime/web/assets/materials-world-BtoAfznA.bin +0 -0
- package/runtime/web/player.js +3 -3
- package/runtime/web-lite/assets/{canvas-WxiusXCB.js → canvas-wFjS40IX.js} +1 -1
- package/runtime/web-lite/assets/creator2d-1pSkYRCn.js +1 -0
- package/runtime/web-lite/assets/creator2d-Ci5-pZGr.wasm +0 -0
- package/runtime/web-lite/assets/{pager-DpGa2uaE.js → pager-BZAO9gMC.js} +1 -1
- package/runtime/web-lite/assets/{plugins-CuEPHbHL.js → plugins-B7TuO_p4.js} +1 -1
- package/runtime/web-lite/assets/scene2d-F6T1Io7I.js +1 -0
- package/runtime/web-lite/assets/{tween-BnWYhJ7P.js → tween-DbrQTld4.js} +1 -1
- package/runtime/web-lite/assets/{video-BLj61nDx.js → video-bzR_t2i6.js} +1 -1
- package/runtime/web-lite/assets/{vlist-CwSYpLz-.js → vlist-Ap-F4H5J.js} +1 -1
- package/runtime/web-lite/features.json +18 -6
- package/runtime/web-lite/lite.js +6 -6
- package/src/commands/compile.ts +2 -1
- package/src/commands/hub/create.ts +100 -0
- package/src/commands/hub/credential.ts +32 -0
- package/src/commands/hub/index.ts +21 -0
- package/src/commands/hub/login.ts +89 -0
- package/src/commands/hub/status.ts +109 -0
- package/src/commands/index.ts +5 -1
- package/src/commands/level.ts +123 -0
- package/src/commands/lightmap.ts +41 -79
- package/src/commands/navmesh.ts +84 -67
- package/src/commands/secrets.ts +147 -0
- package/src/commands/update/index.ts +154 -64
- package/src/compile/designCompile.ts +2 -0
- package/src/compile/headlessBundle.ts +2 -0
- package/src/compile/projectCompile.ts +12 -1
- package/src/compile/sceneCompile.ts +2 -1
- package/src/dev/backendWorker.ts +6 -1
- package/src/dev/devServer.ts +2 -1
- package/src/dev/localBackend.ts +21 -14
- package/src/dev/projectBackend.ts +7 -3
- package/src/dev/watchProject.ts +2 -0
- package/src/hosts/desktopRenderer.ts +10 -2
- package/src/hosts/peerInstall.ts +7 -3
- package/src/hub/api.ts +220 -0
- package/src/hub/config.ts +53 -0
- package/src/hub/git.ts +148 -0
- package/src/platform/api.ts +21 -0
- package/src/project/env.ts +29 -0
- package/src/web/build.ts +149 -88
- package/runtime/web/assets/materials-CJzxzdUK.bin +0 -0
- package/runtime/web/assets/materials-world-BNQb0Z1l.bin +0 -0
package/package.json
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lecodes-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@letary/chisel": "^0.15.0",
|
|
6
6
|
"jimp": "^1.6.1",
|
|
7
|
-
"lecodes-sdk": "2.
|
|
7
|
+
"lecodes-sdk": "2.5.0",
|
|
8
8
|
"selfsigned": "^2.4.1"
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"lecodes-design": "https://storage.yandexcloud.net/le-codes/releases/packages/lecodes-design/lecodes-design-0.11.0.tgz",
|
|
12
|
-
"lecodes-headless": "2.
|
|
12
|
+
"lecodes-headless": "2.5.0",
|
|
13
13
|
"qrcode-terminal": "^0.12.0",
|
|
14
14
|
"lecodes-3d-editor": "https://storage.yandexcloud.net/le-codes/releases/packages/lecodes-3d-editor/lecodes-3d-editor-0.9.0.tgz",
|
|
15
|
-
"lecodes-assets": "2.
|
|
15
|
+
"lecodes-assets": "2.5.0",
|
|
16
16
|
"lecodes-creator-nav": "0.19.0",
|
|
17
|
-
"lecodes-gl-lite": "2.
|
|
18
|
-
"lecodes-web-frame": "2.
|
|
19
|
-
"lecodes-web-player": "2.
|
|
20
|
-
"lecodes-web-shared": "2.
|
|
17
|
+
"lecodes-gl-lite": "2.5.0",
|
|
18
|
+
"lecodes-web-frame": "2.5.0",
|
|
19
|
+
"lecodes-web-player": "2.5.0",
|
|
20
|
+
"lecodes-web-shared": "2.5.0",
|
|
21
21
|
"lecodes-web-lite": "2.0.7",
|
|
22
22
|
"heic-decode": "^2.1.0",
|
|
23
23
|
"marcidb-embedded": "^0.15.0",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"lecodes-design": "^0.11.0",
|
|
28
|
-
"lecodes-headless": "^2.
|
|
28
|
+
"lecodes-headless": "^2.5.0",
|
|
29
29
|
"lecodes-3d-editor": "^0.9.0",
|
|
30
|
-
"lecodes-assets": "^2.
|
|
30
|
+
"lecodes-assets": "^2.5.0",
|
|
31
31
|
"heic-decode": "^2.1.0",
|
|
32
32
|
"marcidb-embedded": "^0.15.0",
|
|
33
33
|
"sharp": "^0.35.2",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Relief decal material (SDK: Material.decal({ normalMap }) — a DecalSet with a `normalMap`). The
|
|
2
|
-
// projection is decal.mat's: the box, the depth
|
|
3
|
-
// test, the atlas rect, the life fade. What differs is WHAT it paints: not a colour but a change
|
|
2
|
+
// projection is decal.mat's: the box, the scene-depth read (the colour pass's own depth, fork
|
|
3
|
+
// patch 0017), the unit-space test, the atlas rect, the life fade. What differs is WHAT it paints: not a colour but a change
|
|
4
4
|
// of the surface's own lighting. A forward renderer has already shaded the wall when the decal is
|
|
5
5
|
// drawn, so the normal map cannot bend the wall's normal; instead this shader shades the surface
|
|
6
6
|
// point twice — with the normal reconstructed from the depth buffer, and with that normal bent by
|
|
@@ -86,32 +86,11 @@ fragment {
|
|
|
86
86
|
vec3 value = vec3(1.0);
|
|
87
87
|
float alpha = 0.0;
|
|
88
88
|
#if !defined(VARIANT_DEPTH)
|
|
89
|
-
|
|
90
|
-
highp vec4 clip = getClipFromWorldMatrix() * vec4(wp, 1.0);
|
|
91
|
-
highp vec2 suv = clip.xy * (0.5 / clip.w) + 0.5;
|
|
92
|
-
highp mat4 p = getViewFromClipMatrix();
|
|
93
|
-
// depth-aware bilinear structure read — see decal.mat
|
|
89
|
+
// the pixel centre's ray and the scene depth under this very pixel — see decal.mat
|
|
94
90
|
highp vec2 ssz = vec2(textureSize(sampler0_structure, 0));
|
|
95
|
-
highp vec2
|
|
96
|
-
highp
|
|
97
|
-
highp
|
|
98
|
-
highp vec2 fr = fract(pix);
|
|
99
|
-
highp float d00 = textureLod(sampler0_structure, uvToRenderTargetUV(base), 0.0).r;
|
|
100
|
-
highp float d10 = textureLod(sampler0_structure, uvToRenderTargetUV(base + vec2(ts.x, 0.0)), 0.0).r;
|
|
101
|
-
highp float d01 = textureLod(sampler0_structure, uvToRenderTargetUV(base + vec2(0.0, ts.y)), 0.0).r;
|
|
102
|
-
highp float d11 = textureLod(sampler0_structure, uvToRenderTargetUV(base + ts), 0.0).r;
|
|
103
|
-
highp float z00 = (d00 * p[2].z + p[3].z) / max(d00 * p[2].w + p[3].w, 1.0 / 16777216.0);
|
|
104
|
-
highp float z10 = (d10 * p[2].z + p[3].z) / max(d10 * p[2].w + p[3].w, 1.0 / 16777216.0);
|
|
105
|
-
highp float z01 = (d01 * p[2].z + p[3].z) / max(d01 * p[2].w + p[3].w, 1.0 / 16777216.0);
|
|
106
|
-
highp float z11 = (d11 * p[2].z + p[3].z) / max(d11 * p[2].w + p[3].w, 1.0 / 16777216.0);
|
|
107
|
-
highp float zRef = fr.x < 0.5 ? (fr.y < 0.5 ? z00 : z01) : (fr.y < 0.5 ? z10 : z11);
|
|
108
|
-
highp float tol = max(0.05 * abs(zRef), 0.03);
|
|
109
|
-
highp float w00 = (1.0 - fr.x) * (1.0 - fr.y) * step(abs(z00 - zRef), tol);
|
|
110
|
-
highp float w10 = fr.x * (1.0 - fr.y) * step(abs(z10 - zRef), tol);
|
|
111
|
-
highp float w01 = (1.0 - fr.x) * fr.y * step(abs(z01 - zRef), tol);
|
|
112
|
-
highp float w11 = fr.x * fr.y * step(abs(z11 - zRef), tol);
|
|
113
|
-
highp float wsum = max(w00 + w10 + w01 + w11, 1e-6);
|
|
114
|
-
highp float sceneDepth = (d00 * w00 + d10 * w10 + d01 * w01 + d11 * w11) / wsum;
|
|
91
|
+
highp vec2 suv = getFragCoord(ssz) / ssz;
|
|
92
|
+
highp mat4 p = getViewFromClipMatrix();
|
|
93
|
+
highp float sceneDepth = texelFetch(sampler0_structure, ivec2(gl_FragCoord.xy), 0).r;
|
|
115
94
|
highp vec4 vc = p * vec4(suv * 2.0 - 1.0, sceneDepth, 1.0);
|
|
116
95
|
highp vec3 sv = vc.xyz / vc.w;
|
|
117
96
|
highp vec3 sw = (getWorldFromViewMatrix() * vec4(sv, 1.0)).xyz;
|
|
@@ -131,24 +110,20 @@ fragment {
|
|
|
131
110
|
float4 tint = getColor();
|
|
132
111
|
alpha = tint.a;
|
|
133
112
|
|
|
134
|
-
// The surface normal from
|
|
113
|
+
// The surface normal from the depth texels around this pixel (see decal.mat) — needed
|
|
135
114
|
// here always: it is the normal the relief bends.
|
|
136
|
-
highp vec2
|
|
137
|
-
highp
|
|
138
|
-
highp float
|
|
139
|
-
highp float
|
|
140
|
-
highp float
|
|
141
|
-
highp
|
|
142
|
-
highp float du = textureLod(sampler0_structure, uvToRenderTargetUV(cuv + vec2(0.0, ts.y)), 0.0).r;
|
|
143
|
-
highp vec2 ndc = cuv * 2.0 - 1.0;
|
|
144
|
-
highp vec4 vcc = p * vec4(ndc, dc, 1.0);
|
|
115
|
+
highp vec2 ts = 1.0 / vec2(textureSize(sampler0_structure, 0));
|
|
116
|
+
highp float dl = textureLod(sampler0_structure, uvToRenderTargetUV(suv - vec2(ts.x, 0.0)), 0.0).r;
|
|
117
|
+
highp float dr = textureLod(sampler0_structure, uvToRenderTargetUV(suv + vec2(ts.x, 0.0)), 0.0).r;
|
|
118
|
+
highp float dd = textureLod(sampler0_structure, uvToRenderTargetUV(suv - vec2(0.0, ts.y)), 0.0).r;
|
|
119
|
+
highp float du = textureLod(sampler0_structure, uvToRenderTargetUV(suv + vec2(0.0, ts.y)), 0.0).r;
|
|
120
|
+
highp vec2 ndc = suv * 2.0 - 1.0;
|
|
145
121
|
highp vec4 vl = p * vec4(ndc - vec2(2.0 * ts.x, 0.0), dl, 1.0);
|
|
146
122
|
highp vec4 vr = p * vec4(ndc + vec2(2.0 * ts.x, 0.0), dr, 1.0);
|
|
147
123
|
highp vec4 vd = p * vec4(ndc - vec2(0.0, 2.0 * ts.y), dd, 1.0);
|
|
148
124
|
highp vec4 vu = p * vec4(ndc + vec2(0.0, 2.0 * ts.y), du, 1.0);
|
|
149
|
-
highp vec3
|
|
150
|
-
highp vec3
|
|
151
|
-
highp vec3 ey = abs(du - dc) < abs(dd - dc) ? vu.xyz / vu.w - sc : sc - vd.xyz / vd.w;
|
|
125
|
+
highp vec3 ex = abs(dr - sceneDepth) < abs(dl - sceneDepth) ? vr.xyz / vr.w - sv : sv - vl.xyz / vl.w;
|
|
126
|
+
highp vec3 ey = abs(du - sceneDepth) < abs(dd - sceneDepth) ? vu.xyz / vu.w - sv : sv - vd.xyz / vd.w;
|
|
152
127
|
highp vec3 nv = cross(ex, ey);
|
|
153
128
|
highp float nl = length(nv);
|
|
154
129
|
highp vec3 axis = normalize(variable_inv2.xyz);
|
|
@@ -162,12 +137,12 @@ fragment {
|
|
|
162
137
|
if (edge > 0.0) alpha *= saturate((0.5 - abs(local.z)) / (0.5 * edge));
|
|
163
138
|
|
|
164
139
|
highp vec2 uv = vec2(local.x + 0.5, 0.5 - local.y);
|
|
165
|
-
// The atlas
|
|
166
|
-
highp float
|
|
167
|
-
highp float
|
|
168
|
-
highp
|
|
169
|
-
highp vec2
|
|
170
|
-
highp vec2 tuv =
|
|
140
|
+
// The atlas cell as small integers — see decal.mat
|
|
141
|
+
highp float pc = floor(variable_rect.x + 0.5), ps = floor(variable_rect.y + 0.5);
|
|
142
|
+
highp float col = floor(pc / 256.0), row = pc - col * 256.0;
|
|
143
|
+
highp float cols = floor(ps / 256.0), rows = ps - cols * 256.0;
|
|
144
|
+
highp vec2 cell = 1.0 / vec2(cols, rows);
|
|
145
|
+
highp vec2 tuv = (vec2(col, row) + uv) * cell;
|
|
171
146
|
|
|
172
147
|
// The bent normal: the map's xy along the decal's right / up, z along the surface normal.
|
|
173
148
|
vec3 T = normalize(variable_inv0.xyz);
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
// Projected decal material (SDK: Material.decal({ map }); native DecalSet in creator-gl
|
|
2
2
|
// src/decals.cpp). One DecalSet is ONE renderable of unit boxes. The fragment stage does not shade
|
|
3
|
-
// the box: it reads the scene depth behind the fragment (
|
|
4
|
-
//
|
|
3
|
+
// the box: it reads the scene depth behind the fragment (the colour pass's own depth after the
|
|
4
|
+
// opaque objects — Filament fork patch 0017 splits the pass and binds it to the blended half as
|
|
5
|
+
// sampler0_structure while creator-gl's scene_depth.cpp asks for it), reconstructs the scene point
|
|
5
6
|
// on the fragment's eye ray, maps it into the decal's unit space with the inverse frame the vertex
|
|
6
7
|
// carries, discards outside the box and samples the atlas cell there. So a decal lands on whatever
|
|
7
8
|
// opaque surface sits inside its box — floor, wall, corner, stairs, a curved rock — with no
|
|
8
9
|
// geometry access at all. It never lands on blended things (particles, glass, other decals): they
|
|
9
|
-
//
|
|
10
|
+
// draw after the capture.
|
|
10
11
|
//
|
|
11
12
|
// Per-vertex inputs (DECAL_VERTEX_FLOATS in decals.h, one interleaved buffer, 8 corners per decal):
|
|
12
13
|
// POSITION — the box corner in the SET's space (the renderable's model space)
|
|
13
14
|
// CUSTOM0..2 — rows of the 3x4 inverse frame: unit box ← set space
|
|
14
|
-
// CUSTOM3 —
|
|
15
|
-
//
|
|
16
|
-
//
|
|
15
|
+
// CUSTOM3 — col·256 + row, cols·256 + rows (the atlas cell on its sheet grid, as small
|
|
16
|
+
// integers — see decals.h for why not packed uv; row 0 = the top, image top =
|
|
17
|
+
// +Y of the box), capStart, capEnd (tilt of the bottom / top edge in unit
|
|
18
|
+
// space — a trail segment's mitred joints, 0 = square)
|
|
17
19
|
// COLOR — tint rgba (a = opacity, already × the gradient end at each corner: −Y corners
|
|
18
20
|
// carry alphaStart, +Y ones alphaEnd, so a trail darkens along its length)
|
|
19
21
|
// CUSTOM4 — born, life, fadeIn, fadeOut (seconds on the `time` clock; life 0 = forever)
|
|
@@ -82,40 +84,21 @@ fragment {
|
|
|
82
84
|
float alpha = 0.0;
|
|
83
85
|
float3 rgb = float3(0.0);
|
|
84
86
|
#if !defined(VARIANT_DEPTH)
|
|
85
|
-
// The scene point behind this fragment: the
|
|
87
|
+
// The scene point behind this fragment: the scene depth on the eye ray through the
|
|
88
|
+
// PIXEL CENTRE. The sampler holds the colour pass's own depth (full resolution, one texel
|
|
89
|
+
// per pixel — fork patch 0017), fetched at gl_FragCoord: the texel the opaque surface
|
|
90
|
+
// wrote under this very pixel, no reconstruction filter. The ray comes from the same
|
|
91
|
+
// pixel centre (getFragCoord = gl_FragCoord in the GL convention on every backend) — NOT
|
|
92
|
+
// from the interpolated world position: under MSAA, GL may interpolate a varying anywhere
|
|
93
|
+
// inside a partly covered pixel (NVIDIA: not at the centre), and a ray through that spot
|
|
94
|
+
// with the centre's depth lands off the surface — a comb of dropped pixels along the
|
|
95
|
+
// box's silhouette at a grazing view; Vulkan, which interpolates at the centre, was clean.
|
|
86
96
|
// Depth goes through Filament's SSR linearizeDepth formula (reversed-Z, far at infinity);
|
|
87
97
|
// clip z is the stored depth itself, so viewFromClip * (ndc.xy, depth, 1) is a view point.
|
|
88
|
-
highp vec3 wp = getWorldPosition();
|
|
89
|
-
highp vec4 clip = getClipFromWorldMatrix() * vec4(wp, 1.0);
|
|
90
|
-
highp vec2 suv = clip.xy * (0.5 / clip.w) + 0.5;
|
|
91
|
-
highp mat4 p = getViewFromClipMatrix();
|
|
92
|
-
// Depth-aware BILINEAR read of the structure buffer. Filament binds it NEAREST and at half
|
|
93
|
-
// resolution, so a plain read quantises the projection to 2x2-pixel blocks (stair-stepped
|
|
94
|
-
// edges, blocky uv at oblique views). Hardware depth is affine in screen space on a plane,
|
|
95
|
-
// so interpolating the RAW depth between the four texel centres is exact there. Across a
|
|
96
|
-
// silhouette a mix would float in the air: taps whose linear depth strays from the nearest
|
|
97
|
-
// texel by more than a few percent are dropped (weights renormalised).
|
|
98
98
|
highp vec2 ssz = vec2(textureSize(sampler0_structure, 0));
|
|
99
|
-
highp vec2
|
|
100
|
-
highp
|
|
101
|
-
highp
|
|
102
|
-
highp vec2 fr = fract(pix);
|
|
103
|
-
highp float d00 = textureLod(sampler0_structure, uvToRenderTargetUV(base), 0.0).r;
|
|
104
|
-
highp float d10 = textureLod(sampler0_structure, uvToRenderTargetUV(base + vec2(ts.x, 0.0)), 0.0).r;
|
|
105
|
-
highp float d01 = textureLod(sampler0_structure, uvToRenderTargetUV(base + vec2(0.0, ts.y)), 0.0).r;
|
|
106
|
-
highp float d11 = textureLod(sampler0_structure, uvToRenderTargetUV(base + ts), 0.0).r;
|
|
107
|
-
highp float z00 = (d00 * p[2].z + p[3].z) / max(d00 * p[2].w + p[3].w, 1.0 / 16777216.0);
|
|
108
|
-
highp float z10 = (d10 * p[2].z + p[3].z) / max(d10 * p[2].w + p[3].w, 1.0 / 16777216.0);
|
|
109
|
-
highp float z01 = (d01 * p[2].z + p[3].z) / max(d01 * p[2].w + p[3].w, 1.0 / 16777216.0);
|
|
110
|
-
highp float z11 = (d11 * p[2].z + p[3].z) / max(d11 * p[2].w + p[3].w, 1.0 / 16777216.0);
|
|
111
|
-
highp float zRef = fr.x < 0.5 ? (fr.y < 0.5 ? z00 : z01) : (fr.y < 0.5 ? z10 : z11);
|
|
112
|
-
highp float tol = max(0.05 * abs(zRef), 0.03);
|
|
113
|
-
highp float w00 = (1.0 - fr.x) * (1.0 - fr.y) * step(abs(z00 - zRef), tol);
|
|
114
|
-
highp float w10 = fr.x * (1.0 - fr.y) * step(abs(z10 - zRef), tol);
|
|
115
|
-
highp float w01 = (1.0 - fr.x) * fr.y * step(abs(z01 - zRef), tol);
|
|
116
|
-
highp float w11 = fr.x * fr.y * step(abs(z11 - zRef), tol);
|
|
117
|
-
highp float wsum = max(w00 + w10 + w01 + w11, 1e-6);
|
|
118
|
-
highp float sceneDepth = (d00 * w00 + d10 * w10 + d01 * w01 + d11 * w11) / wsum;
|
|
99
|
+
highp vec2 suv = getFragCoord(ssz) / ssz;
|
|
100
|
+
highp mat4 p = getViewFromClipMatrix();
|
|
101
|
+
highp float sceneDepth = texelFetch(sampler0_structure, ivec2(gl_FragCoord.xy), 0).r;
|
|
119
102
|
highp vec4 vc = p * vec4(suv * 2.0 - 1.0, sceneDepth, 1.0);
|
|
120
103
|
highp vec3 sv = vc.xyz / vc.w;
|
|
121
104
|
highp vec3 sw = (getWorldFromViewMatrix() * vec4(sv, 1.0)).xyz;
|
|
@@ -136,29 +119,22 @@ fragment {
|
|
|
136
119
|
alpha = tint.a;
|
|
137
120
|
|
|
138
121
|
// Surface facing for the angle fade (a floor decal reaching a wall). The normal comes from
|
|
139
|
-
// the
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
// mixing the bilinear centre with nearest neighbours makes the differences wobble at texel
|
|
143
|
-
// frequency, which reads as hatching on a wall. Per axis the neighbour closer in depth wins
|
|
144
|
-
// (a silhouette is crossed on one side only).
|
|
122
|
+
// the depth texels around this pixel, not screen derivatives: at a silhouette a derivative
|
|
123
|
+
// straddles two surfaces, while here per axis the neighbour closer in depth wins (a
|
|
124
|
+
// silhouette is crossed on one side only). Every point is a texel centre = a pixel centre.
|
|
145
125
|
if (materialParams.angleFade > 0.0) {
|
|
146
|
-
highp vec2
|
|
147
|
-
highp
|
|
148
|
-
highp float
|
|
149
|
-
highp float
|
|
150
|
-
highp float
|
|
151
|
-
highp
|
|
152
|
-
highp float du = textureLod(sampler0_structure, uvToRenderTargetUV(cuv + vec2(0.0, ts.y)), 0.0).r;
|
|
153
|
-
highp vec2 ndc = cuv * 2.0 - 1.0;
|
|
154
|
-
highp vec4 vcc = p * vec4(ndc, dc, 1.0);
|
|
126
|
+
highp vec2 ts = 1.0 / vec2(textureSize(sampler0_structure, 0));
|
|
127
|
+
highp float dl = textureLod(sampler0_structure, uvToRenderTargetUV(suv - vec2(ts.x, 0.0)), 0.0).r;
|
|
128
|
+
highp float dr = textureLod(sampler0_structure, uvToRenderTargetUV(suv + vec2(ts.x, 0.0)), 0.0).r;
|
|
129
|
+
highp float dd = textureLod(sampler0_structure, uvToRenderTargetUV(suv - vec2(0.0, ts.y)), 0.0).r;
|
|
130
|
+
highp float du = textureLod(sampler0_structure, uvToRenderTargetUV(suv + vec2(0.0, ts.y)), 0.0).r;
|
|
131
|
+
highp vec2 ndc = suv * 2.0 - 1.0;
|
|
155
132
|
highp vec4 vl = p * vec4(ndc - vec2(2.0 * ts.x, 0.0), dl, 1.0);
|
|
156
133
|
highp vec4 vr = p * vec4(ndc + vec2(2.0 * ts.x, 0.0), dr, 1.0);
|
|
157
134
|
highp vec4 vd = p * vec4(ndc - vec2(0.0, 2.0 * ts.y), dd, 1.0);
|
|
158
135
|
highp vec4 vu = p * vec4(ndc + vec2(0.0, 2.0 * ts.y), du, 1.0);
|
|
159
|
-
highp vec3
|
|
160
|
-
highp vec3
|
|
161
|
-
highp vec3 ey = abs(du - dc) < abs(dd - dc) ? vu.xyz / vu.w - sc : sc - vd.xyz / vd.w;
|
|
136
|
+
highp vec3 ex = abs(dr - sceneDepth) < abs(dl - sceneDepth) ? vr.xyz / vr.w - sv : sv - vl.xyz / vl.w;
|
|
137
|
+
highp vec3 ey = abs(du - sceneDepth) < abs(dd - sceneDepth) ? vu.xyz / vu.w - sv : sv - vd.xyz / vd.w;
|
|
162
138
|
highp vec3 nv = cross(ex, ey);
|
|
163
139
|
highp float nl = length(nv);
|
|
164
140
|
highp vec3 axisView = mat3(getViewFromWorldMatrix()) * normalize(variable_inv2.xyz);
|
|
@@ -170,12 +146,16 @@ fragment {
|
|
|
170
146
|
if (edge > 0.0) alpha *= saturate((0.5 - abs(local.z)) / (0.5 * edge));
|
|
171
147
|
|
|
172
148
|
highp vec2 uv = vec2(local.x + 0.5, 0.5 - local.y);
|
|
173
|
-
// The atlas
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
highp
|
|
178
|
-
highp
|
|
149
|
+
// The atlas cell: col·256 + row and cols·256 + rows (decals.h) — small integers, so the
|
|
150
|
+
// varying's interpolation rounding (relative, ~1e-7) cannot move them across a half
|
|
151
|
+
// (the packed 0..1 values this replaced sat near 2^22, where it did, and the cell's v
|
|
152
|
+
// range collapsed on scattered pixels — a comb along every decal of the last atlas row).
|
|
153
|
+
highp float pc = floor(variable_rect.x + 0.5), ps = floor(variable_rect.y + 0.5);
|
|
154
|
+
highp float col = floor(pc / 256.0), row = pc - col * 256.0;
|
|
155
|
+
highp float cols = floor(ps / 256.0), rows = ps - cols * 256.0;
|
|
156
|
+
highp vec2 cell = 1.0 / vec2(cols, rows);
|
|
157
|
+
highp vec2 rect0 = vec2(col, row) * cell; // v0 = the cell's top (rows count downward)
|
|
158
|
+
highp vec2 tuv = rect0 + uv * cell;
|
|
179
159
|
float4 tex = texture(materialParams_baseColorMap, tuv);
|
|
180
160
|
alpha *= tex.a;
|
|
181
161
|
if (alpha <= 0.002) discard;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
// foliage-cards: the LEAN material of
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// foliage-cards: the LEAN material of a CROWN's cards (leaves, needles) — the same wind (foliage-wind.vs) and the same
|
|
2
|
+
// parameters as foliage.mat, with the fragment cut to what a card seen past a few metres needs (2026-10-18, the Forest
|
|
3
|
+
// testbed: foliage.mat's masked fragment was ~15 ms of a 49 ms frame on the Radeon — a third of the forest).
|
|
4
|
+
// A CROWN IS A VOLUME IN THE AIR (2026-11-03, the split from grass.mat — the owner: a crown and a blade of grass are two
|
|
5
|
+
// different things and had one shader): its ambient is the sky's SH on the crown's hull normal, darkened by the baked
|
|
6
|
+
// per-vertex sky visibility (the crown's own depth), its sun the real-time light through the shadow map. It reads
|
|
7
|
+
// NOTHING from the ground — the terrain's baked light is the GROUND's (its own cosine, the crown's shadow on it), and
|
|
8
|
+
// read under a tree it was the tree's own shadow: a pine in full sun drew black, trunk and all (the owner's A/B,
|
|
9
|
+
// CREATOR_FOLIAGE_GROUND=0 lit it right). Ground cover — the plant that IS the ground's surface — is grass.mat.
|
|
10
|
+
// What moved or went, against foliage.mat:
|
|
5
11
|
// • the LIGHTING is PER VERTEX: the sky's SH on the crown's hull normal (the ambient) and the sun's wrapped
|
|
6
12
|
// Lambert + back-lit translucency (one scalar), interpolated over the card. Only the sun's SHADOW stays per
|
|
7
13
|
// pixel — Filament's lights loop hands it to surfaceShading() with every light (the material is `lit` with
|
|
@@ -11,11 +17,8 @@
|
|
|
11
17
|
// • no derivatives: the shading normal is the hull's (foliage.mat blends the card's own plane in), the mip
|
|
12
18
|
// coverage is estimated from the DISTANCE in the vertex shader (log2 of the distance over ~8 m), there is no
|
|
13
19
|
// edge fade
|
|
14
|
-
// • THE GROUND'S BAKED LIGHT is read per vertex too (groundLightV, 2026-10-18): the ambient under the vertex and the
|
|
15
|
-
// sun's baked share where the vertex's own sun ray meets the ground, so trees past the shadow map's reach stand in
|
|
16
|
-
// their neighbours' baked shadow; without a bound terrain the scene's sky lights every card
|
|
17
20
|
// The engine treats it as foliage (it declares `benders`) and writes the same blocks; `Material.foliageCards`
|
|
18
|
-
// in the SDK picks it for a
|
|
21
|
+
// in the SDK picks it for a crown's MASK materials in place of foliage-masked.
|
|
19
22
|
|
|
20
23
|
material {
|
|
21
24
|
name : foliage_cards,
|
|
@@ -27,7 +30,7 @@ material {
|
|
|
27
30
|
alphaToCoverage : true,
|
|
28
31
|
flipUV : false,
|
|
29
32
|
requires : [ uv0, color ],
|
|
30
|
-
variables : [ variation, radial, lightv,
|
|
33
|
+
variables : [ variation, radial, lightv, leafv ],
|
|
31
34
|
parameters : [
|
|
32
35
|
{ type : float4, name : baseColorFactor },
|
|
33
36
|
{ type : sampler2d, name : baseColorMap },
|
|
@@ -52,65 +55,12 @@ material {
|
|
|
52
55
|
{ type : sampler2d, name : windNoise },
|
|
53
56
|
{ type : float4, name : plant },
|
|
54
57
|
{ type : float4[8], name : benders },
|
|
55
|
-
{ type : float4[8], name : benderMotion }
|
|
56
|
-
// ---- THE GROUND'S LIGHT (foliage.mat's block, read PER VERTEX here; 2026-10-18, the Forest's baked ground) ----
|
|
57
|
-
// level-wide, written by creator-gl once a terrain's rect is bound (glb.cpp bindGround / bindOptions)
|
|
58
|
-
{ type : float4, name : ground, precision : high },
|
|
59
|
-
{ type : float4, name : groundInv, precision : high },
|
|
60
|
-
{ type : float4, name : groundST, precision : high },
|
|
61
|
-
{ type : sampler2d, name : lightmapLight, precision : high },
|
|
62
|
-
{ type : sampler2d, name : lightmapAux },
|
|
63
|
-
{ type : float, name : lightScale },
|
|
64
|
-
{ type : float4, name : sunDir },
|
|
65
|
-
{ type : float4, name : sunLight, precision : high },
|
|
66
|
-
// ---- THE GROUND'S COLOUR (2026-10-18, glb.cpp foliageSetGroundTint): the terrain's control map (its four layers'
|
|
67
|
-
// weights) and each layer's mean colour; a card's base takes the colour of the soil under it, its top its own
|
|
68
|
-
{ type : sampler2d, name : groundControl },
|
|
69
|
-
{ type : float4[4], name : groundTint },
|
|
70
|
-
{ type : float4, name : groundTintOrigin, precision : high }, // xy = the terrain's world xz origin, z = bound
|
|
71
|
-
{ type : float4, name : groundTintInv, precision : high } // the inverse of its world xz axes
|
|
58
|
+
{ type : float4[8], name : benderMotion }
|
|
72
59
|
]
|
|
73
60
|
}
|
|
74
61
|
|
|
75
62
|
vertex {
|
|
76
63
|
#include "foliage-wind.vs"
|
|
77
|
-
#include "lightmap-sunmap.fs"
|
|
78
|
-
|
|
79
|
-
// THE GROUND'S LIGHT AT A VERTEX (foliage.mat reads it per pixel, under the pixel): true when the plant stands over
|
|
80
|
-
// the bound terrain. `ambient` = the terrain texel's irradiance under the vertex without the sun's part (lux, on the
|
|
81
|
-
// up normal) — the sky through the canopy, the bounce. `sunShare` = the baked share of the sun's disc at the point
|
|
82
|
-
// where THIS VERTEX'S OWN SUN RAY meets the ground (the plant's base height): what shades that point shades the
|
|
83
|
-
// vertex too — a neighbour's crown, or the crown above a card deep in it — so a tree past the shadow map's reach
|
|
84
|
-
// still stands in its neighbour's shadow, and the grass under a pine in the pine's. `lod` picks the pages' level
|
|
85
|
-
// (a far vertex over one texel of 25 cm would flicker between texels as it sways).
|
|
86
|
-
// the crowns' level over the ground: a vertex this high takes the open sky's ambient and its own crown's softened shadow
|
|
87
|
-
#define CANOPY 12.0
|
|
88
|
-
|
|
89
|
-
bool groundLightV(highp vec3 uwp, highp float baseY, float lod, out highp vec3 ambient, out float sunShare) {
|
|
90
|
-
ambient = vec3(0.0); sunShare = 1.0;
|
|
91
|
-
if (materialParams.ground.z < 0.5) return false;
|
|
92
|
-
highp vec2 d = uwp.xz - materialParams.ground.xy;
|
|
93
|
-
highp vec2 g = vec2(dot(materialParams.groundInv.xy, d), dot(materialParams.groundInv.zw, d));
|
|
94
|
-
if (g.x < 0.0 || g.y < 0.0 || g.x > 1.0 || g.y > 1.0) return false; // off the terrain
|
|
95
|
-
highp vec2 luv = g * materialParams.groundST.xy + materialParams.groundST.zw;
|
|
96
|
-
highp vec3 E = textureLod(materialParams_lightmapLight, luv, lod).rgb * materialParams.lightScale;
|
|
97
|
-
ambient = E;
|
|
98
|
-
if (materialParams.sunDir.w > 0.5) {
|
|
99
|
-
highp ivec2 auxSize = textureSize(materialParams_lightmapAux, 0);
|
|
100
|
-
highp int level = clamp(int(lod + 0.5), 0, max(sunMapLevels(), 1) - 1);
|
|
101
|
-
// the sun's part out of the ground's E under the vertex: its illuminance x the share there x the cosine on the
|
|
102
|
-
// ground, taken as flat
|
|
103
|
-
float shareHere = sunMapAt(luv, auxSize, level);
|
|
104
|
-
ambient = max(E - materialParams.sunLight.rgb * (shareHere * max(materialParams.sunDir.y, 0.0)), vec3(0.0));
|
|
105
|
-
// the sun ray through the vertex, followed down to the plant's base height
|
|
106
|
-
vec3 s = materialParams.sunDir.xyz; // TO the sun
|
|
107
|
-
highp vec3 foot = uwp - s * ((uwp.y - baseY) / max(s.y, 0.05));
|
|
108
|
-
d = foot.xz - materialParams.ground.xy;
|
|
109
|
-
g = clamp(vec2(dot(materialParams.groundInv.xy, d), dot(materialParams.groundInv.zw, d)), 0.0, 1.0);
|
|
110
|
-
sunShare = sunMapAt(g * materialParams.groundST.xy + materialParams.groundST.zw, auxSize, level);
|
|
111
|
-
}
|
|
112
|
-
return true;
|
|
113
|
-
}
|
|
114
64
|
|
|
115
65
|
vec3 shIrradianceV(const vec3 n) {
|
|
116
66
|
return max(
|
|
@@ -129,31 +79,13 @@ vertex {
|
|
|
129
79
|
float lodEst = max(log2(max(f.dist, 1.0) / 8.0), 0.0);
|
|
130
80
|
material.radial = vec4(f.hull, lodEst);
|
|
131
81
|
// THE LIGHT, per vertex. Ambient = the sky's SH on the hull normal, as radiance under the camera's exposure
|
|
132
|
-
// (frameUniforms.iblLuminance holds it), darkened by the baked sky visibility by `leaf.w
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
82
|
+
// (frameUniforms.iblLuminance holds it), darkened by the baked sky visibility by `leaf.w` — the crown's own
|
|
83
|
+
// depth: a vertex deep in it took less sky in the bake than one on the outside. The sun = a wrapped Lambert on
|
|
84
|
+
// the hull (thin leaves let light past the terminator, `sway.w`) plus the translucency of a card lit from behind
|
|
85
|
+
// (`leaf.z`, narrowed toward the view line into the light; less deep in the crown), one scalar the fragment
|
|
86
|
+
// multiplies by the light's colour, intensity and SHADOW
|
|
136
87
|
float ao = mix(1.0, f.vao, clamp(materialParams.leaf.w, 0.0, 1.0));
|
|
137
|
-
vec3
|
|
138
|
-
vec3 ambient = skyAmbient;
|
|
139
|
-
float sunShare = 1.0;
|
|
140
|
-
float up = 1.0; // the vertex's height over the ground as a share of the canopy's (1 without a ground)
|
|
141
|
-
highp vec3 gAmb;
|
|
142
|
-
if (groundLightV(f.uwp, f.uOrigin.y, lodEst, gAmb, sunShare)) {
|
|
143
|
-
// THE BAKED GROUND'S LIGHT (the function above): its ambient on the hull normal by the hemisphere formula
|
|
144
|
-
// lightmapShade uses for a tilted normal (the light comes from above), as radiance E / pi under the camera's
|
|
145
|
-
// exposure. The crown's base takes the ground's ambient (the sky through the canopy), its top the open sky's
|
|
146
|
-
// SH - blended by the vertex's height over the plant; a grass blade is all ground
|
|
147
|
-
// the hemisphere formula alone gave a down-facing hull nothing (black needles under a young pine, the owner
|
|
148
|
-
// 2026-10-18): what a card sees below is the ground, lit by that same E and reflecting a quarter of it
|
|
149
|
-
vec3 groundAmbient = gAmb * mix(0.25, 1.0, (1.0 + f.hull.y) * 0.5) / PI * frameUniforms.exposure;
|
|
150
|
-
// by the height OVER THE GROUND, not within the plant: a bush's top is under the same crowns as the ground
|
|
151
|
-
// beside it (a 1.5 m bush with the open sky's SH on its top was a lamp in the shade - the owner, 2026-10-18);
|
|
152
|
-
// the open sky is reached at the crowns' level, CANOPY metres up
|
|
153
|
-
up = clamp((f.uwp.y - f.uOrigin.y) / CANOPY, 0.0, 1.0);
|
|
154
|
-
ambient = mix(groundAmbient, skyAmbient, up);
|
|
155
|
-
}
|
|
156
|
-
ambient *= ao;
|
|
88
|
+
vec3 ambient = shIrradianceV(f.hull) * frameUniforms.iblLuminance * ao;
|
|
157
89
|
vec3 l = frameUniforms.lightDirection;
|
|
158
90
|
vec3 v = normalize(getWorldCameraPosition() - f.wp);
|
|
159
91
|
float wrap = clamp(materialParams.sway.w, 0.0, 1.0);
|
|
@@ -162,36 +94,11 @@ vertex {
|
|
|
162
94
|
float vl = pow(max(dot(-v, l), 0.0), 4.0);
|
|
163
95
|
float through = clamp(materialParams.leaf.z, 0.0, 1.0) * back * (0.5 + 0.5 * vl) * mix(1.0, f.vao, 0.5);
|
|
164
96
|
material.lightv = vec4(ambient, NoL);
|
|
165
|
-
|
|
166
|
-
//
|
|
167
|
-
// the shadow map ALONE: the bake's 64-ray share through the crown put out the glow of a back-lit crown (the
|
|
168
|
-
// multiple scattering a real crown has and this model lacks; the owner, 2026-10-18 "лес довольно тёмный")
|
|
169
|
-
// .z = the height share: near the ground a shadow is a NEIGHBOUR's and lands in full, at the crowns' level it is the
|
|
170
|
-
// crown's own and is softened by leaf.y (the scattering a real crown has); the fragment weighs the shadow by it.
|
|
97
|
+
material.variation = vec4(f.hash, f.alive, f.tintN, 0.0);
|
|
98
|
+
// .x = the translucency scalar (the fragment multiplies it by the light and its shadow, like NoL)
|
|
171
99
|
// (The plants' SHADOW LOD is the LOD pass's, per renderable - lod.cpp gFoliageCast - not this shader's: a card-level
|
|
172
100
|
// discard in the depth variant saved 0.6 ms of the pass's 6.8, the renderables' vertices and draws are the cost)
|
|
173
|
-
|
|
174
|
-
// that differs per vertex could not carry a packed value) times their mean colours; the fragment blends the card's
|
|
175
|
-
// colour toward it by `baked.w` - all of it at the ground, none from ~70 % of the plant's height up (a grass
|
|
176
|
-
// blade's base is its soil, a bush's crown its own leaves; a tree's cards never reach it). The colour rides
|
|
177
|
-
// `variation.w` packed 7 bits a channel (matc allows four variables with the colour attribute; vao was unused there)
|
|
178
|
-
float gtPacked = 0.0, gtBlend = 0.0;
|
|
179
|
-
if (materialParams.groundTintOrigin.z > 0.5) {
|
|
180
|
-
highp vec2 td = f.uOrigin.xz - materialParams.groundTintOrigin.xy;
|
|
181
|
-
highp vec2 tg = vec2(dot(materialParams.groundTintInv.xy, td), dot(materialParams.groundTintInv.zw, td));
|
|
182
|
-
if (tg.x >= 0.0 && tg.y >= 0.0 && tg.x <= 1.0 && tg.y <= 1.0) {
|
|
183
|
-
vec4 w = textureLod(materialParams_groundControl, tg, 0.0);
|
|
184
|
-
float ws = max(w.x + w.y + w.z + w.w, 1e-3);
|
|
185
|
-
vec3 soil = (materialParams.groundTint[0].rgb * w.x + materialParams.groundTint[1].rgb * w.y
|
|
186
|
-
+ materialParams.groundTint[2].rgb * w.z + materialParams.groundTint[3].rgb * w.w) / ws;
|
|
187
|
-
float base = 1.0 - clamp((f.uwp.y - f.uOrigin.y) / max(0.7 * f.plantH, 0.05), 0.0, 1.0);
|
|
188
|
-
vec3 q = floor(clamp(soil, 0.0, 1.0) * 127.0 + 0.5);
|
|
189
|
-
gtPacked = q.r * 16384.0 + q.g * 128.0 + q.b;
|
|
190
|
-
gtBlend = base * 0.85;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
material.variation = vec4(f.hash, f.alive, f.tintN, gtPacked);
|
|
194
|
-
material.baked = vec4(sunShare, through, up, gtBlend);
|
|
101
|
+
material.leafv = vec4(through, 0.0, 0.0, 0.0);
|
|
195
102
|
}
|
|
196
103
|
}
|
|
197
104
|
|
|
@@ -203,12 +110,6 @@ fragment {
|
|
|
203
110
|
float hash = variable_variation.x;
|
|
204
111
|
vec3 tint = mix(vec3(0.86, 0.94, 0.72), vec3(1.06, 1.02, 1.12), hash);
|
|
205
112
|
base.rgb *= mix(vec3(1.0), tint, materialParams.sway.z) * (1.0 - 0.18 * variable_variation.z);
|
|
206
|
-
// the ground's colour at the base (the vertex shader's note): the soil's mean colour in place of the card's
|
|
207
|
-
if (variable_baked.w > 0.0) {
|
|
208
|
-
highp float pk = variable_variation.w;
|
|
209
|
-
vec3 soil = vec3(floor(pk / 16384.0), mod(floor(pk / 128.0), 128.0), mod(pk, 128.0)) / 127.0;
|
|
210
|
-
base.rgb = mix(base.rgb, soil, variable_baked.w);
|
|
211
|
-
}
|
|
212
113
|
// the distance fade thins the card; the coverage holds a far crown's share over the cutoff (colour pass only:
|
|
213
114
|
// the shadow map's caster is fattened below already)
|
|
214
115
|
base.a *= variable_variation.y;
|
|
@@ -227,25 +128,12 @@ fragment {
|
|
|
227
128
|
}
|
|
228
129
|
|
|
229
130
|
// PER LIGHT (the sun first): the vertex shader's wrapped Lambert + translucency scalar, times the light and its
|
|
230
|
-
// SHADOW
|
|
231
|
-
//
|
|
232
|
-
//
|
|
233
|
-
// too — the lean tier is for cards seen from a distance, where a lamp's own angle on a leaf is not read
|
|
131
|
+
// SHADOW. A card takes the shadow map by leaf.y only (foliage.mat's rule): the map cannot tell a neighbour's shadow
|
|
132
|
+
// from the crown's own card-on-card one, and a young pine at full strength went black (2026-10-18). A lamp gets the
|
|
133
|
+
// sun's scalar too — the lean tier is for cards seen from a distance, where a lamp's own angle on a leaf is not read
|
|
234
134
|
vec3 surfaceShading(const MaterialInputs materialInputs, const ShadingData shadingData, const LightData lightData) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
float ky = clamp(materialParams.leaf.y, 0.0, 1.0);
|
|
239
|
-
float kB = mix(1.0, ky, variable_baked.z);
|
|
240
|
-
// the baked share is the SUN's: a lamp takes its own shadow map alone (foliage.mat's test for the sun)
|
|
241
|
-
bool sun = dot(lightData.l, frameUniforms.lightDirection) > 0.999;
|
|
242
|
-
float baked = sun ? mix(1.0, variable_baked.x, kB) : 1.0;
|
|
243
|
-
float lit = min(mix(1.0, lightData.visibility, ky), baked); // the direct light
|
|
244
|
-
// the translucency takes the same two shadows at the HEIGHT weight (kB): a blade at the ground in a tree's baked shade
|
|
245
|
-
// gets none of the sun through it (the map alone leaked 30-40 % of the sun into every shaded clump, and all of it past
|
|
246
|
-
// castDistance - the owner, 2026-10-18 "трава светлая в тени"); a card at the crowns' level keeps leaf.y of it
|
|
247
|
-
float litT = sun ? mix(1.0, min(lightData.visibility, variable_baked.x), kB) : mix(1.0, lightData.visibility, ky);
|
|
248
|
-
float reach = lightData.colorIntensity.w * lightData.attenuation;
|
|
249
|
-
return shadingData.diffuseColor * lightData.colorIntensity.rgb * (reach * (lit * variable_lightv.w + litT * variable_baked.y) / PI);
|
|
135
|
+
float lit = mix(1.0, lightData.visibility, clamp(materialParams.leaf.y, 0.0, 1.0));
|
|
136
|
+
float reach = lightData.colorIntensity.w * lightData.attenuation * lit;
|
|
137
|
+
return shadingData.diffuseColor * lightData.colorIntensity.rgb * (reach * (variable_lightv.w + variable_leafv.x) / PI);
|
|
250
138
|
}
|
|
251
139
|
}
|