sparcoon 0.4.2 → 0.4.3
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.
|
@@ -40,6 +40,7 @@ function wrapShadowCalls(source, uniformName) {
|
|
|
40
40
|
function buildFXDiffuseMaterial(varyings, blending, useAlphaHashing, alphaTest, premultipliedAlpha, albedoNodes, normalNodes, emissionNodes, scatterUniforms, shadowSensitivity) {
|
|
41
41
|
const useScatter = scatterUniforms !== undefined;
|
|
42
42
|
const useShadowSensitivity = shadowSensitivity !== undefined;
|
|
43
|
+
const useNormals = normalNodes.length > 0;
|
|
43
44
|
const attributeDeclarations = [];
|
|
44
45
|
const varyingDeclarations = [];
|
|
45
46
|
const vertexAssignments = [];
|
|
@@ -67,7 +68,7 @@ function buildFXDiffuseMaterial(varyings, blending, useAlphaHashing, alphaTest,
|
|
|
67
68
|
PARTICLE_DEFINES,
|
|
68
69
|
attributeDeclarations.join("\n"),
|
|
69
70
|
"varying vec2 p_uv;",
|
|
70
|
-
"varying
|
|
71
|
+
useNormals ? "varying vec2 p_billboardSinCos;" : "",
|
|
71
72
|
useScatter ? "varying vec3 v_viewPosition;" : "",
|
|
72
73
|
varyingDeclarations.join("\n"),
|
|
73
74
|
].join("\n");
|
|
@@ -79,7 +80,6 @@ function buildFXDiffuseMaterial(varyings, blending, useAlphaHashing, alphaTest,
|
|
|
79
80
|
.replace("#include <defaultnormal_vertex>", "vec3 transformedNormal = vec3(0.0, 0.0, 1.0);")
|
|
80
81
|
.replace("#include <begin_vertex>", [
|
|
81
82
|
"p_uv = uv;",
|
|
82
|
-
"p_rotation = PARTICLE_ROTATION;",
|
|
83
83
|
vertexAssignments.join("\n"),
|
|
84
84
|
"vec3 transformed = position;",
|
|
85
85
|
"#ifdef USE_ALPHAHASH",
|
|
@@ -98,6 +98,9 @@ function buildFXDiffuseMaterial(varyings, blending, useAlphaHashing, alphaTest,
|
|
|
98
98
|
" billboardOffset.x * sinRotation + billboardOffset.y * cosRotation",
|
|
99
99
|
");",
|
|
100
100
|
"",
|
|
101
|
+
// Pass the exact sin/cos that rotated the billboard to the fragment shader.
|
|
102
|
+
useNormals ? "p_billboardSinCos = vec2(sinRotation, cosRotation);" : "",
|
|
103
|
+
"",
|
|
101
104
|
"vec3 particleCenter = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z);",
|
|
102
105
|
"vec4 mvPosition = modelViewMatrix * vec4(particleCenter, 1.0);",
|
|
103
106
|
"mvPosition.xy += billboardOffset;",
|
|
@@ -155,7 +158,7 @@ function buildFXDiffuseMaterial(varyings, blending, useAlphaHashing, alphaTest,
|
|
|
155
158
|
const fragmentPreamble = [
|
|
156
159
|
PARTICLE_DEFINES,
|
|
157
160
|
"varying vec2 p_uv;",
|
|
158
|
-
"varying
|
|
161
|
+
useNormals ? "varying vec2 p_billboardSinCos;" : "",
|
|
159
162
|
varyingDeclarations.join("\n"),
|
|
160
163
|
albedoNodes.flatMap((n) => n.uniformDeclarations).join("\n"),
|
|
161
164
|
uniqueHelpers(albedoNodes),
|
|
@@ -186,7 +189,7 @@ function buildFXDiffuseMaterial(varyings, blending, useAlphaHashing, alphaTest,
|
|
|
186
189
|
Object.assign(shader.uniforms, node.uniforms);
|
|
187
190
|
}
|
|
188
191
|
let fragmentShader = shader.fragmentShader;
|
|
189
|
-
if (
|
|
192
|
+
if (useNormals) {
|
|
190
193
|
const normalExpressions = normalNodes.map((node) => {
|
|
191
194
|
if (node instanceof FXTextureNode) {
|
|
192
195
|
return `normalize(${node.colorExpression}.rgb * 2.0 - 1.0)`;
|
|
@@ -200,10 +203,17 @@ function buildFXDiffuseMaterial(varyings, blending, useAlphaHashing, alphaTest,
|
|
|
200
203
|
"float faceDirection = gl_FrontFacing ? 1.0 : -1.0;",
|
|
201
204
|
`vec3 normal = ${normalExpressions[0]};`,
|
|
202
205
|
...blendLines,
|
|
203
|
-
"
|
|
204
|
-
"
|
|
205
|
-
"
|
|
206
|
-
"
|
|
206
|
+
"",
|
|
207
|
+
"// Rotate tangent-space normal XY into view space to match billboard rotation.",
|
|
208
|
+
"// p_billboardSinCos carries the exact sin/cos that rotated the quad vertices.",
|
|
209
|
+
"float sinR = p_billboardSinCos.x;",
|
|
210
|
+
"float cosR = p_billboardSinCos.y;",
|
|
211
|
+
"normal = vec3(",
|
|
212
|
+
" normal.x * cosR - normal.y * sinR,",
|
|
213
|
+
" normal.x * sinR + normal.y * cosR,",
|
|
214
|
+
" normal.z",
|
|
215
|
+
");",
|
|
216
|
+
"",
|
|
207
217
|
"normal *= faceDirection;",
|
|
208
218
|
].join("\n");
|
|
209
219
|
fragmentShader = fragmentShader.replace("#include <normal_fragment_begin>", normalCode);
|
|
@@ -252,13 +262,6 @@ function buildFXDiffuseMaterial(varyings, blending, useAlphaHashing, alphaTest,
|
|
|
252
262
|
}
|
|
253
263
|
#endif
|
|
254
264
|
|
|
255
|
-
// calculateScatter() includes a "* alpha" density factor. Compositing
|
|
256
|
-
// will apply another "* alpha" (via blend equation in straight mode,
|
|
257
|
-
// or via premultiplied_alpha_fragment + One/OneMinusSrcAlpha blend).
|
|
258
|
-
// Without correction, scatter would get alpha² while diffuse lighting
|
|
259
|
-
// only gets alpha¹. Dividing diffuseColor.rgb by alpha cancels the
|
|
260
|
-
// extra factor, so scatter composites at the same alpha power as
|
|
261
|
-
// the rest of outgoingLight.
|
|
262
265
|
vec3 albedo = diffuseColor.a > 0.001
|
|
263
266
|
? diffuseColor.rgb / diffuseColor.a
|
|
264
267
|
: vec3(0.0);
|