@zephyr3d/scene 0.1.0 → 0.1.2
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 +46 -0
- package/dist/animation/animation.js +28 -28
- package/dist/animation/skeleton.js +14 -14
- package/dist/animation/usertrack.js +9 -9
- package/dist/app.js +31 -31
- package/dist/asset/assetmanager.js +50 -50
- package/dist/asset/builtin.js +157 -157
- package/dist/asset/loaders/dds/dds_loader.js +11 -11
- package/dist/asset/loaders/gltf/gltf_loader.js +10 -10
- package/dist/asset/loaders/hdr/hdr.js +5 -5
- package/dist/asset/loaders/image/tga_Loader.js +3 -3
- package/dist/asset/loaders/image/webimage_loader.js +3 -3
- package/dist/asset/loaders/loader.js +19 -19
- package/dist/asset/model.js +57 -57
- package/dist/blitter/blitter.js +35 -35
- package/dist/blitter/box.js +24 -24
- package/dist/blitter/depthlimitedgaussion.js +3 -3
- package/dist/blitter/gaussianblur.js +21 -21
- package/dist/camera/camera.js +68 -68
- package/dist/index.d.ts +2 -0
- package/dist/material/grassmaterial.js +17 -17
- package/dist/material/lambert.js +3 -3
- package/dist/material/lightmodel.js +362 -362
- package/dist/material/material.js +50 -50
- package/dist/material/meshmaterial.js +48 -48
- package/dist/material/unlit.js +3 -3
- package/dist/posteffect/bloom.js +5 -5
- package/dist/posteffect/compositor.js +16 -16
- package/dist/posteffect/fxaa.js +5 -5
- package/dist/posteffect/grayscale.js +5 -5
- package/dist/posteffect/posteffect.js +42 -42
- package/dist/posteffect/sao.js +5 -5
- package/dist/posteffect/tonemap.js +5 -5
- package/dist/posteffect/water.js +6 -6
- package/dist/render/cull_visitor.js +12 -12
- package/dist/render/depth_pass.js +8 -8
- package/dist/render/envlight.js +104 -104
- package/dist/render/render_queue.js +33 -33
- package/dist/render/renderpass.js +18 -18
- package/dist/render/renderscheme.js +14 -14
- package/dist/render/scatteringlut.js +3 -3
- package/dist/render/sky.js +38 -38
- package/dist/render/temporalcache.js +4 -4
- package/dist/render/watermesh.js +5 -5
- package/dist/scene/graph_node.js +25 -25
- package/dist/scene/octree.js +191 -191
- package/dist/scene/scene.js +37 -37
- package/dist/scene/terrain/grass.js +27 -27
- package/dist/scene/terrain/quadtree.js +45 -45
- package/dist/shaders/framework.js +161 -161
- package/dist/shaders/lighting.js +7 -7
- package/dist/shaders/noise.js +43 -43
- package/dist/shadow/shadowmapper.js +76 -76
- package/dist/shadow/ssm.js +34 -34
- package/dist/utility/bounding_volume.js +30 -27
- package/dist/utility/bounding_volume.js.map +1 -1
- package/dist/utility/shprojection.js +14 -14
- package/package.json +70 -70
- package/dist/material/mixins/texture.js +0 -110
- package/dist/material/mixins/texture.js.map +0 -1
package/dist/asset/builtin.js
CHANGED
|
@@ -2,13 +2,13 @@ import { Vector4, Vector3, Vector2 } from '@zephyr3d/base';
|
|
|
2
2
|
import { BUILTIN_ASSET_TEXTURE_SHEEN_LUT } from '../values.js';
|
|
3
3
|
import { Application } from '../app.js';
|
|
4
4
|
|
|
5
|
-
/*
|
|
6
|
-
interface MicrofacetDistributionSample {
|
|
7
|
-
pdf?: number;
|
|
8
|
-
cosTheta?: number;
|
|
9
|
-
sinTheta?: number;
|
|
10
|
-
phi?: number;
|
|
11
|
-
}
|
|
5
|
+
/*
|
|
6
|
+
interface MicrofacetDistributionSample {
|
|
7
|
+
pdf?: number;
|
|
8
|
+
cosTheta?: number;
|
|
9
|
+
sinTheta?: number;
|
|
10
|
+
phi?: number;
|
|
11
|
+
}
|
|
12
12
|
*/ /** @internal */ function getTestCubemapLoader() {
|
|
13
13
|
return async function(assetManager) {
|
|
14
14
|
const tex = Application.instance.device.createCubeTexture('rgba8unorm', 32, {
|
|
@@ -53,57 +53,57 @@ interface MicrofacetDistributionSample {
|
|
|
53
53
|
function hammersley(i, iN, out) {
|
|
54
54
|
out.setXY(i * iN, radicalInverse_VdC(i));
|
|
55
55
|
}
|
|
56
|
-
/*
|
|
57
|
-
function hammersley(i: number, iN: number, out: Vector2) {
|
|
58
|
-
const tof = 0.5 / 0x80000000;
|
|
59
|
-
let bits = i;
|
|
60
|
-
bits = (bits << 16) | (bits >>> 16);
|
|
61
|
-
bits = ((bits & 0x55555555) << 1) | ((bits & 0xAAAAAAAA) >>> 1);
|
|
62
|
-
bits = ((bits & 0x33333333) << 2) | ((bits & 0xCCCCCCCC) >>> 2);
|
|
63
|
-
bits = ((bits & 0x0F0F0F0F) << 4) | ((bits & 0xF0F0F0F0) >>> 4);
|
|
64
|
-
bits = ((bits & 0x00FF00FF) << 8) | ((bits & 0xFF00FF00) >>> 8);
|
|
65
|
-
out.setXY(i * iN, (bits >>> 0) * tof);
|
|
66
|
-
}
|
|
67
|
-
*/ /*
|
|
68
|
-
function generateTBN(normal: Vector3, out: Matrix3x3) {
|
|
69
|
-
bitangent.setXYZ(0.0, 1.0, 0.0);
|
|
70
|
-
const NdotUp = Vector3.dot(normal, up);
|
|
71
|
-
const epsilon = 0.0000001;
|
|
72
|
-
if (1.0 - Math.abs(NdotUp) <= epsilon) {
|
|
73
|
-
// Sampling +Y or -Y, so we need a more robust bitangent.
|
|
74
|
-
if (NdotUp > 0.0) {
|
|
75
|
-
bitangent.setXYZ(0.0, 0.0, 1.0);
|
|
76
|
-
} else {
|
|
77
|
-
bitangent.setXYZ(0.0, 0.0, -1.0);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
Vector3.cross(bitangent, normal, tangent).inplaceNormalize();
|
|
81
|
-
Vector3.cross(normal, tangent, bitangent);
|
|
82
|
-
out.setCol(0, tangent);
|
|
83
|
-
out.setCol(1, bitangent);
|
|
84
|
-
out.setCol(2, normal);
|
|
85
|
-
}
|
|
86
|
-
function mix(x: number, y: number, a: number): number {
|
|
87
|
-
return x * (1 - a) + y * a;
|
|
88
|
-
}
|
|
89
|
-
function l(x: number, alphaG: number): number {
|
|
90
|
-
const oneMinusAlphaSq = (1 - alphaG) * (1 - alphaG);
|
|
91
|
-
const a = mix(21.5473, 25.3245, oneMinusAlphaSq);
|
|
92
|
-
const b = mix(3.82987, 3.32435, oneMinusAlphaSq);
|
|
93
|
-
const c = mix(0.19823, 0.16801, oneMinusAlphaSq);
|
|
94
|
-
const d = mix(-1.9776, -1.27393, oneMinusAlphaSq);
|
|
95
|
-
const e = mix(-4.32054, -4.85967, oneMinusAlphaSq);
|
|
96
|
-
return a / (1 + b * Math.pow(x, c)) + d * x + e;
|
|
97
|
-
}
|
|
98
|
-
function lambdaSheen(cosTheta: number, alphaG: number): number {
|
|
99
|
-
return Math.abs(cosTheta) < 0.5
|
|
100
|
-
? Math.exp(l(Math.abs(cosTheta), alphaG))
|
|
101
|
-
: Math.exp(2 * l(0.5, alphaG) - l(1 - Math.abs(cosTheta), alphaG));
|
|
102
|
-
}
|
|
103
|
-
function visibilityCharlie(NdotV: number, NdotL: number, a: number): number {
|
|
104
|
-
const alphaG = a;
|
|
105
|
-
return 1 / ((1 + lambdaSheen(NdotV, alphaG) + lambdaSheen(NdotL, alphaG)) * (4 * NdotV * NdotL));
|
|
106
|
-
}
|
|
56
|
+
/*
|
|
57
|
+
function hammersley(i: number, iN: number, out: Vector2) {
|
|
58
|
+
const tof = 0.5 / 0x80000000;
|
|
59
|
+
let bits = i;
|
|
60
|
+
bits = (bits << 16) | (bits >>> 16);
|
|
61
|
+
bits = ((bits & 0x55555555) << 1) | ((bits & 0xAAAAAAAA) >>> 1);
|
|
62
|
+
bits = ((bits & 0x33333333) << 2) | ((bits & 0xCCCCCCCC) >>> 2);
|
|
63
|
+
bits = ((bits & 0x0F0F0F0F) << 4) | ((bits & 0xF0F0F0F0) >>> 4);
|
|
64
|
+
bits = ((bits & 0x00FF00FF) << 8) | ((bits & 0xFF00FF00) >>> 8);
|
|
65
|
+
out.setXY(i * iN, (bits >>> 0) * tof);
|
|
66
|
+
}
|
|
67
|
+
*/ /*
|
|
68
|
+
function generateTBN(normal: Vector3, out: Matrix3x3) {
|
|
69
|
+
bitangent.setXYZ(0.0, 1.0, 0.0);
|
|
70
|
+
const NdotUp = Vector3.dot(normal, up);
|
|
71
|
+
const epsilon = 0.0000001;
|
|
72
|
+
if (1.0 - Math.abs(NdotUp) <= epsilon) {
|
|
73
|
+
// Sampling +Y or -Y, so we need a more robust bitangent.
|
|
74
|
+
if (NdotUp > 0.0) {
|
|
75
|
+
bitangent.setXYZ(0.0, 0.0, 1.0);
|
|
76
|
+
} else {
|
|
77
|
+
bitangent.setXYZ(0.0, 0.0, -1.0);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
Vector3.cross(bitangent, normal, tangent).inplaceNormalize();
|
|
81
|
+
Vector3.cross(normal, tangent, bitangent);
|
|
82
|
+
out.setCol(0, tangent);
|
|
83
|
+
out.setCol(1, bitangent);
|
|
84
|
+
out.setCol(2, normal);
|
|
85
|
+
}
|
|
86
|
+
function mix(x: number, y: number, a: number): number {
|
|
87
|
+
return x * (1 - a) + y * a;
|
|
88
|
+
}
|
|
89
|
+
function l(x: number, alphaG: number): number {
|
|
90
|
+
const oneMinusAlphaSq = (1 - alphaG) * (1 - alphaG);
|
|
91
|
+
const a = mix(21.5473, 25.3245, oneMinusAlphaSq);
|
|
92
|
+
const b = mix(3.82987, 3.32435, oneMinusAlphaSq);
|
|
93
|
+
const c = mix(0.19823, 0.16801, oneMinusAlphaSq);
|
|
94
|
+
const d = mix(-1.9776, -1.27393, oneMinusAlphaSq);
|
|
95
|
+
const e = mix(-4.32054, -4.85967, oneMinusAlphaSq);
|
|
96
|
+
return a / (1 + b * Math.pow(x, c)) + d * x + e;
|
|
97
|
+
}
|
|
98
|
+
function lambdaSheen(cosTheta: number, alphaG: number): number {
|
|
99
|
+
return Math.abs(cosTheta) < 0.5
|
|
100
|
+
? Math.exp(l(Math.abs(cosTheta), alphaG))
|
|
101
|
+
: Math.exp(2 * l(0.5, alphaG) - l(1 - Math.abs(cosTheta), alphaG));
|
|
102
|
+
}
|
|
103
|
+
function visibilityCharlie(NdotV: number, NdotL: number, a: number): number {
|
|
104
|
+
const alphaG = a;
|
|
105
|
+
return 1 / ((1 + lambdaSheen(NdotV, alphaG) + lambdaSheen(NdotL, alphaG)) * (4 * NdotV * NdotL));
|
|
106
|
+
}
|
|
107
107
|
*/ function distributionCharlie(NdotH, roughness) {
|
|
108
108
|
// roughness = Math.max(roughness, 0.000001);
|
|
109
109
|
const invAlpha = 1 / roughness;
|
|
@@ -111,90 +111,90 @@ interface MicrofacetDistributionSample {
|
|
|
111
111
|
const sin2h = 1 - cos2h;
|
|
112
112
|
return (2 + invAlpha) * Math.pow(sin2h, invAlpha * 0.5) / (2 * Math.PI);
|
|
113
113
|
}
|
|
114
|
-
/*
|
|
115
|
-
function charlie(xi: Vector2, roughness: number, sample: MicrofacetDistributionSample) {
|
|
116
|
-
const alpha = roughness * roughness;
|
|
117
|
-
sample.sinTheta = Math.pow(xi.y, alpha / (2 * alpha + 1));
|
|
118
|
-
sample.cosTheta = Math.sqrt(1 - sample.sinTheta * sample.sinTheta);
|
|
119
|
-
sample.phi = 2 * Math.PI * xi.x;
|
|
120
|
-
sample.pdf = distributionCharlie(sample.cosTheta, Math.max(alpha, 0.000001)) / 4;
|
|
121
|
-
}
|
|
122
|
-
function getImportanceSample(
|
|
123
|
-
sampleIndex: number,
|
|
124
|
-
sampleCount: number,
|
|
125
|
-
N: Vector3,
|
|
126
|
-
roughness: number,
|
|
127
|
-
out: Vector4
|
|
128
|
-
) {
|
|
129
|
-
// generate a quasi monte carlo point in the unit square [0.1)^2
|
|
130
|
-
hammersley(sampleIndex, 1 / sampleCount, xi);
|
|
131
|
-
// generate the points on the hemisphere with a fitting mapping for
|
|
132
|
-
// the distribution (e.g. lambertian uses a cosine importance)
|
|
133
|
-
charlie(xi, roughness, importanceSample);
|
|
134
|
-
|
|
135
|
-
// transform the hemisphere sample to the normal coordinate frame
|
|
136
|
-
// i.e. rotate the hemisphere to the normal direction
|
|
137
|
-
localSpaceDirection
|
|
138
|
-
.setXYZ(
|
|
139
|
-
importanceSample.sinTheta * Math.cos(importanceSample.phi),
|
|
140
|
-
importanceSample.sinTheta * Math.sin(importanceSample.phi),
|
|
141
|
-
importanceSample.cosTheta
|
|
142
|
-
)
|
|
143
|
-
.inplaceNormalize();
|
|
144
|
-
generateTBN(N, TBN);
|
|
145
|
-
TBN.transform(localSpaceDirection, direction);
|
|
146
|
-
out.setXYZW(direction.x, direction.y, direction.z, importanceSample.pdf);
|
|
147
|
-
}
|
|
148
|
-
function lut(NdotV: number, roughness: number, numSamples: number, out: Vector4) {
|
|
149
|
-
V.setXYZ(Math.sqrt(1 - NdotV * NdotV), 0, NdotV);
|
|
150
|
-
N.setXYZ(0, 0, 1);
|
|
151
|
-
const A = 0;
|
|
152
|
-
const B = 0;
|
|
153
|
-
let C = 0;
|
|
154
|
-
const importanceSample = new Vector4();
|
|
155
|
-
for (let i = 0; i < numSamples; i++) {
|
|
156
|
-
getImportanceSample(i, numSamples, N, roughness, importanceSample);
|
|
157
|
-
H.setXYZ(importanceSample.x, importanceSample.y, importanceSample.z);
|
|
158
|
-
// do reflect L = normalize(reflect(-V, H)) = normalize(-V - 2.0 * dot(H, -V) * H) = normalize(2 * dot(H, V) * H - V)
|
|
159
|
-
Vector3.scale(H, Vector3.dot(V, H) * 2, L)
|
|
160
|
-
.subBy(V)
|
|
161
|
-
.inplaceNormalize();
|
|
162
|
-
const NdotL = Math.min(Math.max(L.z, 0), 1);
|
|
163
|
-
const NdotH = Math.min(Math.max(H.z, 0), 1);
|
|
164
|
-
const VdotH = Math.min(Math.max(Vector3.dot(V, H), 0), 1);
|
|
165
|
-
if (NdotL > 0) {
|
|
166
|
-
const sheenDistribution = distributionCharlie(NdotH, roughness);
|
|
167
|
-
// const sheenVisibility = visibilityAshikhmin(NdotV, NdotL);
|
|
168
|
-
const sheenVisibility = visibilityCharlie(NdotV, NdotL, roughness);
|
|
169
|
-
C += sheenVisibility * sheenDistribution * NdotL * VdotH;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
out.setXYZW(4 * A, 4 * B, 4 * 2 * Math.PI * C, 0).scaleBy(1 / numSamples);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
async function createSheenLUT(): Promise<Texture2D> {
|
|
176
|
-
const tex = Application.instance.device.createTexture2D('rgba8unorm', textureSize, textureSize);
|
|
177
|
-
const image = new Uint8Array(textureSize * textureSize * 4);
|
|
178
|
-
let p = 0;
|
|
179
|
-
const c = new Vector4();
|
|
180
|
-
for (let y = 0; y < textureSize; y++) {
|
|
181
|
-
const coord = Math.min(Math.max((y + 0.5) / textureSize, 0), 1);
|
|
182
|
-
const roughness = coord;
|
|
183
|
-
for (let x = 0; x < textureSize; x++) {
|
|
184
|
-
const NdotV = Math.min(Math.max((x + 0.5) / textureSize, 0), 1);
|
|
185
|
-
// const c = dfvCharlieUniform(NdotV, roughness, 1024);
|
|
186
|
-
// const c = Math.min(Math.max(Math.round(t * 255), 0), 255);
|
|
187
|
-
lut(NdotV, roughness, 1024, c);
|
|
188
|
-
image[p++] = Math.min(Math.max(Math.round(c.x * 255), 0), 255);
|
|
189
|
-
image[p++] = Math.min(Math.max(Math.round(c.y * 255), 0), 255);
|
|
190
|
-
image[p++] = Math.min(Math.max(Math.round(c.z * 255), 0), 255);
|
|
191
|
-
image[p++] = 255;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
tex.update(image, 0, 0, textureSize, textureSize);
|
|
195
|
-
tex.name = `builtin:${BUILTIN_ASSET_TEXTURE_SHEEN_LUT}`;
|
|
196
|
-
return tex;
|
|
197
|
-
}
|
|
114
|
+
/*
|
|
115
|
+
function charlie(xi: Vector2, roughness: number, sample: MicrofacetDistributionSample) {
|
|
116
|
+
const alpha = roughness * roughness;
|
|
117
|
+
sample.sinTheta = Math.pow(xi.y, alpha / (2 * alpha + 1));
|
|
118
|
+
sample.cosTheta = Math.sqrt(1 - sample.sinTheta * sample.sinTheta);
|
|
119
|
+
sample.phi = 2 * Math.PI * xi.x;
|
|
120
|
+
sample.pdf = distributionCharlie(sample.cosTheta, Math.max(alpha, 0.000001)) / 4;
|
|
121
|
+
}
|
|
122
|
+
function getImportanceSample(
|
|
123
|
+
sampleIndex: number,
|
|
124
|
+
sampleCount: number,
|
|
125
|
+
N: Vector3,
|
|
126
|
+
roughness: number,
|
|
127
|
+
out: Vector4
|
|
128
|
+
) {
|
|
129
|
+
// generate a quasi monte carlo point in the unit square [0.1)^2
|
|
130
|
+
hammersley(sampleIndex, 1 / sampleCount, xi);
|
|
131
|
+
// generate the points on the hemisphere with a fitting mapping for
|
|
132
|
+
// the distribution (e.g. lambertian uses a cosine importance)
|
|
133
|
+
charlie(xi, roughness, importanceSample);
|
|
134
|
+
|
|
135
|
+
// transform the hemisphere sample to the normal coordinate frame
|
|
136
|
+
// i.e. rotate the hemisphere to the normal direction
|
|
137
|
+
localSpaceDirection
|
|
138
|
+
.setXYZ(
|
|
139
|
+
importanceSample.sinTheta * Math.cos(importanceSample.phi),
|
|
140
|
+
importanceSample.sinTheta * Math.sin(importanceSample.phi),
|
|
141
|
+
importanceSample.cosTheta
|
|
142
|
+
)
|
|
143
|
+
.inplaceNormalize();
|
|
144
|
+
generateTBN(N, TBN);
|
|
145
|
+
TBN.transform(localSpaceDirection, direction);
|
|
146
|
+
out.setXYZW(direction.x, direction.y, direction.z, importanceSample.pdf);
|
|
147
|
+
}
|
|
148
|
+
function lut(NdotV: number, roughness: number, numSamples: number, out: Vector4) {
|
|
149
|
+
V.setXYZ(Math.sqrt(1 - NdotV * NdotV), 0, NdotV);
|
|
150
|
+
N.setXYZ(0, 0, 1);
|
|
151
|
+
const A = 0;
|
|
152
|
+
const B = 0;
|
|
153
|
+
let C = 0;
|
|
154
|
+
const importanceSample = new Vector4();
|
|
155
|
+
for (let i = 0; i < numSamples; i++) {
|
|
156
|
+
getImportanceSample(i, numSamples, N, roughness, importanceSample);
|
|
157
|
+
H.setXYZ(importanceSample.x, importanceSample.y, importanceSample.z);
|
|
158
|
+
// do reflect L = normalize(reflect(-V, H)) = normalize(-V - 2.0 * dot(H, -V) * H) = normalize(2 * dot(H, V) * H - V)
|
|
159
|
+
Vector3.scale(H, Vector3.dot(V, H) * 2, L)
|
|
160
|
+
.subBy(V)
|
|
161
|
+
.inplaceNormalize();
|
|
162
|
+
const NdotL = Math.min(Math.max(L.z, 0), 1);
|
|
163
|
+
const NdotH = Math.min(Math.max(H.z, 0), 1);
|
|
164
|
+
const VdotH = Math.min(Math.max(Vector3.dot(V, H), 0), 1);
|
|
165
|
+
if (NdotL > 0) {
|
|
166
|
+
const sheenDistribution = distributionCharlie(NdotH, roughness);
|
|
167
|
+
// const sheenVisibility = visibilityAshikhmin(NdotV, NdotL);
|
|
168
|
+
const sheenVisibility = visibilityCharlie(NdotV, NdotL, roughness);
|
|
169
|
+
C += sheenVisibility * sheenDistribution * NdotL * VdotH;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
out.setXYZW(4 * A, 4 * B, 4 * 2 * Math.PI * C, 0).scaleBy(1 / numSamples);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function createSheenLUT(): Promise<Texture2D> {
|
|
176
|
+
const tex = Application.instance.device.createTexture2D('rgba8unorm', textureSize, textureSize);
|
|
177
|
+
const image = new Uint8Array(textureSize * textureSize * 4);
|
|
178
|
+
let p = 0;
|
|
179
|
+
const c = new Vector4();
|
|
180
|
+
for (let y = 0; y < textureSize; y++) {
|
|
181
|
+
const coord = Math.min(Math.max((y + 0.5) / textureSize, 0), 1);
|
|
182
|
+
const roughness = coord;
|
|
183
|
+
for (let x = 0; x < textureSize; x++) {
|
|
184
|
+
const NdotV = Math.min(Math.max((x + 0.5) / textureSize, 0), 1);
|
|
185
|
+
// const c = dfvCharlieUniform(NdotV, roughness, 1024);
|
|
186
|
+
// const c = Math.min(Math.max(Math.round(t * 255), 0), 255);
|
|
187
|
+
lut(NdotV, roughness, 1024, c);
|
|
188
|
+
image[p++] = Math.min(Math.max(Math.round(c.x * 255), 0), 255);
|
|
189
|
+
image[p++] = Math.min(Math.max(Math.round(c.y * 255), 0), 255);
|
|
190
|
+
image[p++] = Math.min(Math.max(Math.round(c.z * 255), 0), 255);
|
|
191
|
+
image[p++] = 255;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
tex.update(image, 0, 0, textureSize, textureSize);
|
|
195
|
+
tex.name = `builtin:${BUILTIN_ASSET_TEXTURE_SHEEN_LUT}`;
|
|
196
|
+
return tex;
|
|
197
|
+
}
|
|
198
198
|
*/ //////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
199
199
|
function visibilityAshikhmin(NdotV, NdotL) {
|
|
200
200
|
return Math.min(Math.max(1 / (4 * (NdotL + NdotV - NdotL * NdotV)), 0), 1);
|
|
@@ -318,21 +318,21 @@ interface MicrofacetDistributionSample {
|
|
|
318
318
|
const e = f >> 23 & 0x1ff;
|
|
319
319
|
return _tables.baseTable[e] + ((f & 0x007fffff) >> _tables.shiftTable[e]);
|
|
320
320
|
}
|
|
321
|
-
/*
|
|
322
|
-
function decodeF16(val: number) {
|
|
323
|
-
const exponent = (val & 0x7c00) >> 10;
|
|
324
|
-
const fraction = val & 0x03ff;
|
|
325
|
-
return (
|
|
326
|
-
(val >> 15 ? -1 : 1) *
|
|
327
|
-
(exponent
|
|
328
|
-
? exponent === 0x1f
|
|
329
|
-
? fraction
|
|
330
|
-
? NaN
|
|
331
|
-
: Infinity
|
|
332
|
-
: Math.pow(2, exponent - 15) * (1 + fraction / 0x400)
|
|
333
|
-
: 6.103515625e-5 * (fraction / 0x400))
|
|
334
|
-
);
|
|
335
|
-
}
|
|
321
|
+
/*
|
|
322
|
+
function decodeF16(val: number) {
|
|
323
|
+
const exponent = (val & 0x7c00) >> 10;
|
|
324
|
+
const fraction = val & 0x03ff;
|
|
325
|
+
return (
|
|
326
|
+
(val >> 15 ? -1 : 1) *
|
|
327
|
+
(exponent
|
|
328
|
+
? exponent === 0x1f
|
|
329
|
+
? fraction
|
|
330
|
+
? NaN
|
|
331
|
+
: Infinity
|
|
332
|
+
: Math.pow(2, exponent - 15) * (1 + fraction / 0x400)
|
|
333
|
+
: 6.103515625e-5 * (fraction / 0x400))
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
336
|
*/ async function createSheenLUTFilament(assetManager, texture) {
|
|
337
337
|
if (texture) {
|
|
338
338
|
if (!texture.isTexture2D()) {
|
|
@@ -2,9 +2,9 @@ import { getDDSMipLevelsInfo } from './dds.js';
|
|
|
2
2
|
import { AbstractTextureLoader } from '../loader.js';
|
|
3
3
|
import { Application } from '../../../app.js';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* The DDS texture loader
|
|
7
|
-
* @internal
|
|
5
|
+
/**
|
|
6
|
+
* The DDS texture loader
|
|
7
|
+
* @internal
|
|
8
8
|
*/ class DDSLoader extends AbstractTextureLoader {
|
|
9
9
|
supportExtension(ext) {
|
|
10
10
|
return ext === '.dds';
|
|
@@ -23,14 +23,14 @@ import { Application } from '../../../app.js';
|
|
|
23
23
|
samplerOptions
|
|
24
24
|
};
|
|
25
25
|
return Application.instance.device.createTextureFromMipmapData(mipmapLevelData, srgb, options);
|
|
26
|
-
/*
|
|
27
|
-
if (mipmapLevelData.isCubemap) {
|
|
28
|
-
return Application.instance.device.createCubeTextureFromMipmapData(mipmapLevelData, options);
|
|
29
|
-
} else if (mipmapLevelData.isVolume) {
|
|
30
|
-
throw new Error(`load DDS volume texture is not supported`);
|
|
31
|
-
} else {
|
|
32
|
-
return Application.instance.device.createTexture2DFromMipmapData(mipmapLevelData, options);
|
|
33
|
-
}
|
|
26
|
+
/*
|
|
27
|
+
if (mipmapLevelData.isCubemap) {
|
|
28
|
+
return Application.instance.device.createCubeTextureFromMipmapData(mipmapLevelData, options);
|
|
29
|
+
} else if (mipmapLevelData.isVolume) {
|
|
30
|
+
throw new Error(`load DDS volume texture is not supported`);
|
|
31
|
+
} else {
|
|
32
|
+
return Application.instance.device.createTexture2DFromMipmapData(mipmapLevelData, options);
|
|
33
|
+
}
|
|
34
34
|
*/ }
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -15,9 +15,9 @@ import '../../../material/lightmodel.js';
|
|
|
15
15
|
import { GLTFAccessor, ComponentType } from './helpers.js';
|
|
16
16
|
import { AbstractModelLoader } from '../loader.js';
|
|
17
17
|
|
|
18
|
-
/**
|
|
19
|
-
* The GLTF/GLB model loader
|
|
20
|
-
* @internal
|
|
18
|
+
/**
|
|
19
|
+
* The GLTF/GLB model loader
|
|
20
|
+
* @internal
|
|
21
21
|
*/ class GLTFLoader extends AbstractModelLoader {
|
|
22
22
|
supportExtension(ext) {
|
|
23
23
|
return ext === '.gltf' || ext === '.glb';
|
|
@@ -477,10 +477,10 @@ import { AbstractModelLoader } from '../loader.js';
|
|
|
477
477
|
pbrMaterial.lightModel.useSheen = true;
|
|
478
478
|
pbrMaterial.lightModel.sheenColorFactor = sheen.sheenColorFactor;
|
|
479
479
|
pbrMaterial.lightModel.sheenRoughnessFactor = sheen.sheenRoughnessFactor;
|
|
480
|
-
/*
|
|
481
|
-
pbrMaterial.lightModel.setSheenLut(
|
|
482
|
-
await assetManager.fetchBuiltinTexture(BUILTIN_ASSET_TEXTURE_SHEEN_LUT)
|
|
483
|
-
);
|
|
480
|
+
/*
|
|
481
|
+
pbrMaterial.lightModel.setSheenLut(
|
|
482
|
+
await assetManager.fetchBuiltinTexture(BUILTIN_ASSET_TEXTURE_SHEEN_LUT)
|
|
483
|
+
);
|
|
484
484
|
*/ if (sheen.sheenColorMap) {
|
|
485
485
|
pbrMaterial.lightModel.setSheenColorMap(sheen.sheenColorMap.texture, sheen.sheenColorMap.sampler, sheen.sheenColorMap.texCoord, sheen.sheenColorMap.transform);
|
|
486
486
|
}
|
|
@@ -802,9 +802,9 @@ import { AbstractModelLoader } from '../loader.js';
|
|
|
802
802
|
return 'point-list';
|
|
803
803
|
case 1:
|
|
804
804
|
return 'line-list';
|
|
805
|
-
/* FIXME:
|
|
806
|
-
case 2: // GL_LINE_LOOP
|
|
807
|
-
return PrimitiveType.LineLoop;
|
|
805
|
+
/* FIXME:
|
|
806
|
+
case 2: // GL_LINE_LOOP
|
|
807
|
+
return PrimitiveType.LineLoop;
|
|
808
808
|
*/ case 3:
|
|
809
809
|
return 'line-strip';
|
|
810
810
|
case 4:
|
|
@@ -3,9 +3,9 @@ import { floatToHalf, packFloat3 } from '@zephyr3d/base';
|
|
|
3
3
|
import { Application } from '../../../app.js';
|
|
4
4
|
|
|
5
5
|
const _f16one = floatToHalf(1);
|
|
6
|
-
/**
|
|
7
|
-
* The HDR texture loader
|
|
8
|
-
* @internal
|
|
6
|
+
/**
|
|
7
|
+
* The HDR texture loader
|
|
8
|
+
* @internal
|
|
9
9
|
*/ class HDRLoader extends AbstractTextureLoader {
|
|
10
10
|
supportExtension(ext) {
|
|
11
11
|
return ext === '.hdr';
|
|
@@ -72,8 +72,8 @@ const _f16one = floatToHalf(1);
|
|
|
72
72
|
}
|
|
73
73
|
return result;
|
|
74
74
|
}
|
|
75
|
-
/*
|
|
76
|
-
Decode: rgb = pow(6 * rgbm.rgb * rgbm.a, 2.2);
|
|
75
|
+
/*
|
|
76
|
+
Decode: rgb = pow(6 * rgbm.rgb * rgbm.a, 2.2);
|
|
77
77
|
*/ _rgbeToRGBM(buffer) {
|
|
78
78
|
const length = buffer.byteLength >> 2;
|
|
79
79
|
const result = new Uint8Array(length * 4);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AbstractTextureLoader } from '../loader.js';
|
|
2
2
|
import { Application } from '../../../app.js';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* TGA image loader
|
|
6
|
-
* @internal
|
|
4
|
+
/**
|
|
5
|
+
* TGA image loader
|
|
6
|
+
* @internal
|
|
7
7
|
*/ class TGALoader extends AbstractTextureLoader {
|
|
8
8
|
supportExtension(ext) {
|
|
9
9
|
return ext === '.tga';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AbstractTextureLoader } from '../loader.js';
|
|
2
2
|
import { Application } from '../../../app.js';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Web image loader
|
|
6
|
-
* @internal
|
|
4
|
+
/**
|
|
5
|
+
* Web image loader
|
|
6
|
+
* @internal
|
|
7
7
|
*/ class WebImageLoader extends AbstractTextureLoader {
|
|
8
8
|
supportExtension(ext) {
|
|
9
9
|
return ext === '.jpg' || ext === '.jpeg' || ext === '.png';
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Base interface for any kind loaders
|
|
3
|
-
* @public
|
|
1
|
+
/**
|
|
2
|
+
* Base interface for any kind loaders
|
|
3
|
+
* @public
|
|
4
4
|
*/ class LoaderBase {
|
|
5
5
|
/** @internal */ _urlResolver;
|
|
6
|
-
/**
|
|
7
|
-
* Creates an instance of LoaderBase
|
|
6
|
+
/**
|
|
7
|
+
* Creates an instance of LoaderBase
|
|
8
8
|
*/ constructor(){
|
|
9
9
|
this._urlResolver = null;
|
|
10
10
|
}
|
|
11
|
-
/**
|
|
12
|
-
* URL resolver for the loader
|
|
11
|
+
/**
|
|
12
|
+
* URL resolver for the loader
|
|
13
13
|
*/ get urlResolver() {
|
|
14
14
|
return this._urlResolver;
|
|
15
15
|
}
|
|
16
16
|
set urlResolver(resolver) {
|
|
17
17
|
this._urlResolver = resolver;
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Sends a GET request
|
|
21
|
-
* @param url - The URL to get
|
|
22
|
-
* @param headers - The headers for the request
|
|
23
|
-
* @param crossOrigin - crossOrigin property for the request
|
|
24
|
-
* @returns Response of the request
|
|
19
|
+
/**
|
|
20
|
+
* Sends a GET request
|
|
21
|
+
* @param url - The URL to get
|
|
22
|
+
* @param headers - The headers for the request
|
|
23
|
+
* @param crossOrigin - crossOrigin property for the request
|
|
24
|
+
* @returns Response of the request
|
|
25
25
|
*/ async request(url, headers = {}, crossOrigin = 'anonymous') {
|
|
26
26
|
url = this._urlResolver ? this._urlResolver(url) : null;
|
|
27
27
|
return url ? fetch(url, {
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
}) : null;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Base class for any kind of texture loaders
|
|
35
|
-
* @public
|
|
33
|
+
/**
|
|
34
|
+
* Base class for any kind of texture loaders
|
|
35
|
+
* @public
|
|
36
36
|
*/ class AbstractTextureLoader extends LoaderBase {
|
|
37
37
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Base class for any kind of model loaders
|
|
40
|
-
* @public
|
|
38
|
+
/**
|
|
39
|
+
* Base class for any kind of model loaders
|
|
40
|
+
* @public
|
|
41
41
|
*/ class AbstractModelLoader extends LoaderBase {
|
|
42
42
|
}
|
|
43
43
|
|