action-engine-js 1.0.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/LICENSE +45 -0
- package/README.md +348 -0
- package/actionengine/3rdparty/goblin/goblin.js +9609 -0
- package/actionengine/3rdparty/goblin/goblin.min.js +5 -0
- package/actionengine/camera/actioncamera.js +90 -0
- package/actionengine/camera/cameracollisionhandler.js +69 -0
- package/actionengine/character/actioncharacter.js +360 -0
- package/actionengine/character/actioncharacter3D.js +61 -0
- package/actionengine/core/app.js +430 -0
- package/actionengine/debug/basedebugpanel.js +858 -0
- package/actionengine/display/canvasmanager.js +75 -0
- package/actionengine/display/gl/programmanager.js +570 -0
- package/actionengine/display/gl/shaders/lineshader.js +118 -0
- package/actionengine/display/gl/shaders/objectshader.js +1756 -0
- package/actionengine/display/gl/shaders/particleshader.js +43 -0
- package/actionengine/display/gl/shaders/shadowshader.js +319 -0
- package/actionengine/display/gl/shaders/spriteshader.js +100 -0
- package/actionengine/display/gl/shaders/watershader.js +67 -0
- package/actionengine/display/graphics/actionmodel3D.js +191 -0
- package/actionengine/display/graphics/actionsprite3D.js +230 -0
- package/actionengine/display/graphics/lighting/actiondirectionalshadowlight.js +864 -0
- package/actionengine/display/graphics/lighting/actionlight.js +211 -0
- package/actionengine/display/graphics/lighting/actionomnidirectionalshadowlight.js +862 -0
- package/actionengine/display/graphics/lighting/lightingconstants.js +263 -0
- package/actionengine/display/graphics/lighting/lightmanager.js +789 -0
- package/actionengine/display/graphics/renderableobject.js +44 -0
- package/actionengine/display/graphics/renderers/actionrenderer2D.js +341 -0
- package/actionengine/display/graphics/renderers/actionrenderer3D/actionrenderer3D.js +655 -0
- package/actionengine/display/graphics/renderers/actionrenderer3D/canvasmanager3D.js +82 -0
- package/actionengine/display/graphics/renderers/actionrenderer3D/debugrenderer3D.js +493 -0
- package/actionengine/display/graphics/renderers/actionrenderer3D/objectrenderer3D.js +790 -0
- package/actionengine/display/graphics/renderers/actionrenderer3D/spriteRenderer3D.js +266 -0
- package/actionengine/display/graphics/renderers/actionrenderer3D/sunrenderer3D.js +140 -0
- package/actionengine/display/graphics/renderers/actionrenderer3D/waterrenderer3D.js +173 -0
- package/actionengine/display/graphics/renderers/actionrenderer3D/weatherrenderer3D.js +87 -0
- package/actionengine/display/graphics/texture/proceduraltexture.js +192 -0
- package/actionengine/display/graphics/texture/texturemanager.js +242 -0
- package/actionengine/display/graphics/texture/textureregistry.js +177 -0
- package/actionengine/input/actionscrollablearea.js +1405 -0
- package/actionengine/input/inputhandler.js +1647 -0
- package/actionengine/math/geometry/geometrybuilder.js +161 -0
- package/actionengine/math/geometry/glbexporter.js +364 -0
- package/actionengine/math/geometry/glbloader.js +722 -0
- package/actionengine/math/geometry/modelcodegenerator.js +97 -0
- package/actionengine/math/geometry/triangle.js +33 -0
- package/actionengine/math/geometry/triangleutils.js +34 -0
- package/actionengine/math/mathutils.js +25 -0
- package/actionengine/math/matrix4.js +785 -0
- package/actionengine/math/physics/actionphysics.js +108 -0
- package/actionengine/math/physics/actionphysicsobject3D.js +164 -0
- package/actionengine/math/physics/actionphysicsworld3D.js +238 -0
- package/actionengine/math/physics/actionraycast.js +129 -0
- package/actionengine/math/physics/shapes/actionphysicsbox3D.js +158 -0
- package/actionengine/math/physics/shapes/actionphysicscapsule3D.js +200 -0
- package/actionengine/math/physics/shapes/actionphysicscompoundshape3D.js +147 -0
- package/actionengine/math/physics/shapes/actionphysicscone3D.js +126 -0
- package/actionengine/math/physics/shapes/actionphysicsconvexshape3D.js +72 -0
- package/actionengine/math/physics/shapes/actionphysicscylinder3D.js +117 -0
- package/actionengine/math/physics/shapes/actionphysicsmesh3D.js +74 -0
- package/actionengine/math/physics/shapes/actionphysicsplane3D.js +100 -0
- package/actionengine/math/physics/shapes/actionphysicssphere3D.js +95 -0
- package/actionengine/math/quaternion.js +61 -0
- package/actionengine/math/vector2.js +277 -0
- package/actionengine/math/vector3.js +318 -0
- package/actionengine/math/viewfrustum.js +136 -0
- package/actionengine/network/ACTIONNETREADME.md +810 -0
- package/actionengine/network/client/ActionNetManager.js +802 -0
- package/actionengine/network/client/ActionNetManagerGUI.js +1709 -0
- package/actionengine/network/client/ActionNetManagerP2P.js +1537 -0
- package/actionengine/network/client/SyncSystem.js +422 -0
- package/actionengine/network/p2p/ActionNetPeer.js +142 -0
- package/actionengine/network/p2p/ActionNetTrackerClient.js +623 -0
- package/actionengine/network/p2p/DataConnection.js +282 -0
- package/actionengine/network/p2p/README.md +510 -0
- package/actionengine/network/p2p/example.html +502 -0
- package/actionengine/network/server/ActionNetServer.js +577 -0
- package/actionengine/network/server/ActionNetServerSSL.js +579 -0
- package/actionengine/network/server/ActionNetServerUtils.js +458 -0
- package/actionengine/network/server/SERVERREADME.md +314 -0
- package/actionengine/network/server/package-lock.json +35 -0
- package/actionengine/network/server/package.json +13 -0
- package/actionengine/network/server/start.bat +27 -0
- package/actionengine/network/server/start.sh +25 -0
- package/actionengine/network/server/startwss.bat +27 -0
- package/actionengine/sound/audiomanager.js +1589 -0
- package/actionengine/sound/soundfont/ACTIONSOUNDFONT_README.md +205 -0
- package/actionengine/sound/soundfont/actionparser.js +718 -0
- package/actionengine/sound/soundfont/actionreverb.js +252 -0
- package/actionengine/sound/soundfont/actionsoundfont.js +543 -0
- package/actionengine/sound/soundfont/sf2playerlicence.txt +29 -0
- package/actionengine/sound/soundfont/soundfont.js +2 -0
- package/dist/action-engine.min.js +328 -0
- package/package.json +35 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// game/display/gl/shaders/particleshader.js
|
|
2
|
+
class ParticleShader {
|
|
3
|
+
getParticleVertexShader(isWebGL2) {
|
|
4
|
+
return `${isWebGL2 ? "#version 300 es\n" : ""}
|
|
5
|
+
${isWebGL2 ? "in" : "attribute"} vec3 aPosition;
|
|
6
|
+
${isWebGL2 ? "in" : "attribute"} float aSize;
|
|
7
|
+
${isWebGL2 ? "in" : "attribute"} vec4 aColor;
|
|
8
|
+
|
|
9
|
+
uniform mat4 uProjectionMatrix;
|
|
10
|
+
uniform mat4 uViewMatrix;
|
|
11
|
+
|
|
12
|
+
${isWebGL2 ? "out" : "varying"} vec4 vColor;
|
|
13
|
+
|
|
14
|
+
void main() {
|
|
15
|
+
gl_Position = uProjectionMatrix * uViewMatrix * vec4(aPosition, 1.0);
|
|
16
|
+
gl_PointSize = aSize;
|
|
17
|
+
vColor = aColor;
|
|
18
|
+
}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
getParticleFragmentShader(isWebGL2) {
|
|
22
|
+
return `${isWebGL2 ? "#version 300 es\n" : ""}
|
|
23
|
+
precision mediump float;
|
|
24
|
+
${isWebGL2 ? "in" : "varying"} vec4 vColor;
|
|
25
|
+
${isWebGL2 ? "out vec4 fragColor;\n" : ""}
|
|
26
|
+
uniform int uParticleType;
|
|
27
|
+
void main() {
|
|
28
|
+
vec2 coord = gl_PointCoord * 2.0 - 1.0;
|
|
29
|
+
if (uParticleType == 1 || uParticleType == 2) { // Rain types
|
|
30
|
+
coord.y *= 12.0; // Longer streaks
|
|
31
|
+
float r = dot(coord, coord);
|
|
32
|
+
float streak = smoothstep(1.0, 0.0, r);
|
|
33
|
+
float trail = smoothstep(1.0, 0.0, coord.y);
|
|
34
|
+
float droplet = streak * trail;
|
|
35
|
+
${isWebGL2 ? "fragColor" : "gl_FragColor"} = vec4(0.8, 0.85, 1.0, 1.0); // Blueish tint, more transparent
|
|
36
|
+
} else {
|
|
37
|
+
float r = dot(coord, coord);
|
|
38
|
+
if (r > 1.0) discard;
|
|
39
|
+
${isWebGL2 ? "fragColor" : "gl_FragColor"} = vColor;
|
|
40
|
+
}
|
|
41
|
+
}`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
// actionengine/display/gl/shaders/shadowshader.js
|
|
2
|
+
class ShadowShader {
|
|
3
|
+
/**
|
|
4
|
+
* Dedicated vertex shader for directional shadow mapping
|
|
5
|
+
* This is the clean version that only handles directional shadows
|
|
6
|
+
*/
|
|
7
|
+
getDirectionalShadowVertexShader(isWebGL2) {
|
|
8
|
+
return `${isWebGL2 ? "#version 300 es\n" : ""}
|
|
9
|
+
${isWebGL2 ? "in" : "attribute"} vec3 aPosition;
|
|
10
|
+
|
|
11
|
+
uniform mat4 uLightSpaceMatrix;
|
|
12
|
+
uniform mat4 uModelMatrix;
|
|
13
|
+
|
|
14
|
+
void main() {
|
|
15
|
+
gl_Position = uLightSpaceMatrix * uModelMatrix * vec4(aPosition, 1.0);
|
|
16
|
+
}`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Vertex shader for the shadow mapping pass
|
|
21
|
+
* This shader simply transforms vertices to light space
|
|
22
|
+
*/
|
|
23
|
+
getShadowVertexShader(isWebGL2) {
|
|
24
|
+
return `${isWebGL2 ? "#version 300 es\n" : ""}
|
|
25
|
+
${isWebGL2 ? "in" : "attribute"} vec3 aPosition;
|
|
26
|
+
|
|
27
|
+
uniform mat4 uLightSpaceMatrix;
|
|
28
|
+
uniform mat4 uModelMatrix;
|
|
29
|
+
${isWebGL2 ? "out" : "varying"} vec4 vWorldPos; // For omnidirectional shadows
|
|
30
|
+
uniform vec3 uLightPos; // For omnidirectional shadows
|
|
31
|
+
|
|
32
|
+
void main() {
|
|
33
|
+
vec4 worldPos = uModelMatrix * vec4(aPosition, 1.0);
|
|
34
|
+
vWorldPos = worldPos;
|
|
35
|
+
gl_Position = uLightSpaceMatrix * worldPos;
|
|
36
|
+
}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get the vertex shader for omnidirectional shadow mapping
|
|
41
|
+
* This variant is optimized for point lights with cubemap shadows
|
|
42
|
+
*/
|
|
43
|
+
getOmniShadowVertexShader(isWebGL2) {
|
|
44
|
+
return `${isWebGL2 ? "#version 300 es\n" : ""}
|
|
45
|
+
${isWebGL2 ? "in" : "attribute"} vec3 aPosition;
|
|
46
|
+
|
|
47
|
+
uniform mat4 uLightSpaceMatrix;
|
|
48
|
+
uniform mat4 uModelMatrix;
|
|
49
|
+
uniform vec3 uLightPos;
|
|
50
|
+
|
|
51
|
+
${isWebGL2 ? "out" : "varying"} vec3 vFragPos;
|
|
52
|
+
|
|
53
|
+
void main() {
|
|
54
|
+
vec4 worldPos = uModelMatrix * vec4(aPosition, 1.0);
|
|
55
|
+
vFragPos = worldPos.xyz;
|
|
56
|
+
gl_Position = uLightSpaceMatrix * worldPos;
|
|
57
|
+
}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Fragment shader for the shadow mapping pass
|
|
62
|
+
* This shader outputs depth values to the shadow map
|
|
63
|
+
*/
|
|
64
|
+
getDirectionalShadowFragmentShader(isWebGL2) {
|
|
65
|
+
if (isWebGL2) {
|
|
66
|
+
return `#version 300 es
|
|
67
|
+
precision mediump float;
|
|
68
|
+
|
|
69
|
+
// Debug uniforms
|
|
70
|
+
uniform bool uDebugShadowMap;
|
|
71
|
+
uniform bool uForceShadowMapTest;
|
|
72
|
+
uniform float uShadowMapSize;
|
|
73
|
+
|
|
74
|
+
out vec4 fragColor;
|
|
75
|
+
|
|
76
|
+
void main() {
|
|
77
|
+
// DIRECTIONAL ONLY: Direct depth from gl_FragCoord.z
|
|
78
|
+
float depth = gl_FragCoord.z;
|
|
79
|
+
|
|
80
|
+
// Apply forcing if in test mode
|
|
81
|
+
if (uForceShadowMapTest) {
|
|
82
|
+
vec2 center = vec2(0.5, 0.5);
|
|
83
|
+
vec2 normalizedCoord = gl_FragCoord.xy / uShadowMapSize;
|
|
84
|
+
|
|
85
|
+
float testSize = 256.0 / uShadowMapSize;
|
|
86
|
+
if (abs(normalizedCoord.x - center.x) < testSize &&
|
|
87
|
+
abs(normalizedCoord.y - center.y) < testSize) {
|
|
88
|
+
depth = 0.5; // Force a mid-range depth value in test area
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Pack depth into RGBA (manual encoding for better precision)
|
|
93
|
+
const vec4 bitShift = vec4(1.0, 256.0, 256.0*256.0, 256.0*256.0*256.0);
|
|
94
|
+
const vec4 bitMask = vec4(1.0/256.0, 1.0/256.0, 1.0/256.0, 0.0);
|
|
95
|
+
vec4 encodedDepth = fract(depth * bitShift);
|
|
96
|
+
encodedDepth -= encodedDepth.gbaa * bitMask;
|
|
97
|
+
|
|
98
|
+
fragColor = encodedDepth;
|
|
99
|
+
}`;
|
|
100
|
+
} else {
|
|
101
|
+
// WebGL1 version
|
|
102
|
+
return `precision highp float;
|
|
103
|
+
|
|
104
|
+
// Debug uniforms
|
|
105
|
+
uniform bool uDebugShadowMap;
|
|
106
|
+
uniform bool uForceShadowMapTest;
|
|
107
|
+
uniform float uShadowMapSize;
|
|
108
|
+
|
|
109
|
+
void main() {
|
|
110
|
+
// DIRECTIONAL ONLY: Direct depth from gl_FragCoord.z
|
|
111
|
+
float depth = gl_FragCoord.z;
|
|
112
|
+
|
|
113
|
+
// Create test pattern if enabled
|
|
114
|
+
if (uForceShadowMapTest) {
|
|
115
|
+
vec2 center = vec2(0.5, 0.5);
|
|
116
|
+
vec2 normalizedCoord = gl_FragCoord.xy / uShadowMapSize;
|
|
117
|
+
|
|
118
|
+
float testSize = 256.0 / uShadowMapSize;
|
|
119
|
+
if (abs(normalizedCoord.x - center.x) < testSize &&
|
|
120
|
+
abs(normalizedCoord.y - center.y) < testSize) {
|
|
121
|
+
// For WebGL1, we need to encode depth as RGBA
|
|
122
|
+
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); // White = 1.0 depth
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (uDebugShadowMap) {
|
|
128
|
+
// For debug visualization
|
|
129
|
+
gl_FragColor = vec4(depth, depth * 0.5, depth * 0.2, 1.0);
|
|
130
|
+
|
|
131
|
+
// Show test area if enabled
|
|
132
|
+
if (uForceShadowMapTest) {
|
|
133
|
+
vec2 center = vec2(0.5, 0.5);
|
|
134
|
+
vec2 normalizedCoord = gl_FragCoord.xy / uShadowMapSize;
|
|
135
|
+
|
|
136
|
+
float testSize = 256.0 / uShadowMapSize;
|
|
137
|
+
if (abs(normalizedCoord.x - center.x) < testSize &&
|
|
138
|
+
abs(normalizedCoord.y - center.y) < testSize) {
|
|
139
|
+
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red for test area
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
// Pack depth into RGBA (bit-wise encoding) for normal operation
|
|
144
|
+
const vec4 bitShift = vec4(1.0, 256.0, 256.0*256.0, 256.0*256.0*256.0);
|
|
145
|
+
const vec4 bitMask = vec4(1.0/256.0, 1.0/256.0, 1.0/256.0, 0.0);
|
|
146
|
+
vec4 color = fract(depth * bitShift);
|
|
147
|
+
color -= color.gbaa * bitMask;
|
|
148
|
+
|
|
149
|
+
gl_FragColor = color;
|
|
150
|
+
}
|
|
151
|
+
}`;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
getShadowFragmentShader(isWebGL2) {
|
|
156
|
+
if (isWebGL2) {
|
|
157
|
+
return `#version 300 es
|
|
158
|
+
precision mediump float;
|
|
159
|
+
|
|
160
|
+
// Debug uniforms
|
|
161
|
+
uniform bool uDebugShadowMap;
|
|
162
|
+
uniform bool uForceShadowMapTest;
|
|
163
|
+
uniform float uShadowMapSize; // New uniform for shadow map size
|
|
164
|
+
|
|
165
|
+
// For omnidirectional shadows
|
|
166
|
+
in vec4 vWorldPos;
|
|
167
|
+
uniform vec3 uLightPos;
|
|
168
|
+
uniform float uFarPlane;
|
|
169
|
+
|
|
170
|
+
out vec4 fragColor;
|
|
171
|
+
|
|
172
|
+
void main() {
|
|
173
|
+
// For omnidirectional shadows, compute distance from light to fragment
|
|
174
|
+
vec3 fragToLight = vWorldPos.xyz - uLightPos;
|
|
175
|
+
float lightDistance = length(fragToLight);
|
|
176
|
+
|
|
177
|
+
// Normalize to [0,1] range based on far plane
|
|
178
|
+
float depth = lightDistance / uFarPlane;
|
|
179
|
+
|
|
180
|
+
// Apply forcing if in test mode
|
|
181
|
+
if (uForceShadowMapTest) {
|
|
182
|
+
vec2 center = vec2(0.5, 0.5);
|
|
183
|
+
vec2 normalizedCoord = gl_FragCoord.xy / uShadowMapSize;
|
|
184
|
+
|
|
185
|
+
float testSize = 256.0 / uShadowMapSize;
|
|
186
|
+
if (abs(normalizedCoord.x - center.x) < testSize &&
|
|
187
|
+
abs(normalizedCoord.y - center.y) < testSize) {
|
|
188
|
+
depth = 0.5; // Force a mid-range depth value in test area
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Pack depth into RGBA (manual encoding for better precision)
|
|
193
|
+
const vec4 bitShift = vec4(1.0, 256.0, 256.0*256.0, 256.0*256.0*256.0);
|
|
194
|
+
const vec4 bitMask = vec4(1.0/256.0, 1.0/256.0, 1.0/256.0, 0.0);
|
|
195
|
+
vec4 encodedDepth = fract(depth * bitShift);
|
|
196
|
+
encodedDepth -= encodedDepth.gbaa * bitMask;
|
|
197
|
+
|
|
198
|
+
fragColor = encodedDepth;
|
|
199
|
+
}`;
|
|
200
|
+
} else {
|
|
201
|
+
// WebGL1 version
|
|
202
|
+
return `precision highp float;
|
|
203
|
+
|
|
204
|
+
// Debug uniforms
|
|
205
|
+
uniform bool uDebugShadowMap;
|
|
206
|
+
uniform bool uForceShadowMapTest;
|
|
207
|
+
uniform float uShadowMapSize; // New uniform for shadow map size
|
|
208
|
+
|
|
209
|
+
// For omnidirectional shadows
|
|
210
|
+
varying vec4 vWorldPos;
|
|
211
|
+
uniform vec3 uLightPos;
|
|
212
|
+
uniform float uFarPlane;
|
|
213
|
+
|
|
214
|
+
void main() {
|
|
215
|
+
// For omnidirectional shadows, compute distance from light to fragment
|
|
216
|
+
vec3 fragToLight = vWorldPos.xyz - uLightPos;
|
|
217
|
+
float lightDistance = length(fragToLight);
|
|
218
|
+
|
|
219
|
+
// Normalize to [0,1] range based on far plane
|
|
220
|
+
float depth = lightDistance / uFarPlane;
|
|
221
|
+
|
|
222
|
+
// Create test pattern if enabled
|
|
223
|
+
if (uForceShadowMapTest) {
|
|
224
|
+
vec2 center = vec2(0.5, 0.5);
|
|
225
|
+
vec2 normalizedCoord = gl_FragCoord.xy / uShadowMapSize;
|
|
226
|
+
|
|
227
|
+
float testSize = 256.0 / uShadowMapSize;
|
|
228
|
+
if (abs(normalizedCoord.x - center.x) < testSize &&
|
|
229
|
+
abs(normalizedCoord.y - center.y) < testSize) {
|
|
230
|
+
// For WebGL1, we need to encode depth as RGBA
|
|
231
|
+
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); // White = 1.0 depth
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (uDebugShadowMap) {
|
|
237
|
+
// For debug visualization
|
|
238
|
+
gl_FragColor = vec4(depth, depth * 0.5, depth * 0.2, 1.0);
|
|
239
|
+
|
|
240
|
+
// Show test area if enabled
|
|
241
|
+
if (uForceShadowMapTest) {
|
|
242
|
+
vec2 center = vec2(0.5, 0.5);
|
|
243
|
+
vec2 normalizedCoord = gl_FragCoord.xy / uShadowMapSize;
|
|
244
|
+
|
|
245
|
+
float testSize = 256.0 / uShadowMapSize;
|
|
246
|
+
if (abs(normalizedCoord.x - center.x) < testSize &&
|
|
247
|
+
abs(normalizedCoord.y - center.y) < testSize) {
|
|
248
|
+
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red for test area
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} else {
|
|
252
|
+
// Pack depth into RGBA (bit-wise encoding) for normal operation
|
|
253
|
+
const vec4 bitShift = vec4(1.0, 256.0, 256.0*256.0, 256.0*256.0*256.0);
|
|
254
|
+
const vec4 bitMask = vec4(1.0/256.0, 1.0/256.0, 1.0/256.0, 0.0);
|
|
255
|
+
vec4 color = fract(depth * bitShift);
|
|
256
|
+
color -= color.gbaa * bitMask;
|
|
257
|
+
|
|
258
|
+
gl_FragColor = color;
|
|
259
|
+
}
|
|
260
|
+
}`;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Fragment shader specifically for omnidirectional shadow mapping
|
|
266
|
+
* Optimized for point lights with cubemap shadows
|
|
267
|
+
*/
|
|
268
|
+
getOmniShadowFragmentShader(isWebGL2) {
|
|
269
|
+
if (isWebGL2) {
|
|
270
|
+
return `#version 300 es
|
|
271
|
+
precision mediump float;
|
|
272
|
+
|
|
273
|
+
in vec3 vFragPos;
|
|
274
|
+
uniform vec3 uLightPos;
|
|
275
|
+
uniform float uFarPlane;
|
|
276
|
+
|
|
277
|
+
out vec4 fragColor;
|
|
278
|
+
|
|
279
|
+
void main() {
|
|
280
|
+
// Get distance between fragment and light source
|
|
281
|
+
float lightDistance = length(vFragPos - uLightPos);
|
|
282
|
+
|
|
283
|
+
// Map to [0,1] range by dividing by far plane
|
|
284
|
+
lightDistance = lightDistance / uFarPlane;
|
|
285
|
+
|
|
286
|
+
// Write this as depth value
|
|
287
|
+
const vec4 bitShift = vec4(1.0, 256.0, 256.0*256.0, 256.0*256.0*256.0);
|
|
288
|
+
const vec4 bitMask = vec4(1.0/256.0, 1.0/256.0, 1.0/256.0, 0.0);
|
|
289
|
+
vec4 encodedDepth = fract(lightDistance * bitShift);
|
|
290
|
+
encodedDepth -= encodedDepth.gbaa * bitMask;
|
|
291
|
+
|
|
292
|
+
fragColor = encodedDepth;
|
|
293
|
+
}`;
|
|
294
|
+
} else {
|
|
295
|
+
// WebGL1 version
|
|
296
|
+
return `precision highp float;
|
|
297
|
+
|
|
298
|
+
varying vec3 vFragPos;
|
|
299
|
+
uniform vec3 uLightPos;
|
|
300
|
+
uniform float uFarPlane;
|
|
301
|
+
|
|
302
|
+
void main() {
|
|
303
|
+
// Get distance between fragment and light source
|
|
304
|
+
float lightDistance = length(vFragPos - uLightPos);
|
|
305
|
+
|
|
306
|
+
// Map to [0,1] range by dividing by far plane
|
|
307
|
+
lightDistance = lightDistance / uFarPlane;
|
|
308
|
+
|
|
309
|
+
// Write this as depth value
|
|
310
|
+
const vec4 bitShift = vec4(1.0, 256.0, 256.0*256.0, 256.0*256.0*256.0);
|
|
311
|
+
const vec4 bitMask = vec4(1.0/256.0, 1.0/256.0, 1.0/256.0, 0.0);
|
|
312
|
+
vec4 color = fract(lightDistance * bitShift);
|
|
313
|
+
color -= color.gbaa * bitMask;
|
|
314
|
+
|
|
315
|
+
gl_FragColor = color;
|
|
316
|
+
}`;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// actionengine/display/gl/shaders/spriteshader.js
|
|
2
|
+
|
|
3
|
+
class SpriteShader {
|
|
4
|
+
constructor() {
|
|
5
|
+
// No variants needed for sprites - keep it simple
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Get sprite vertex shader
|
|
10
|
+
* @param {boolean} isWebGL2 - Whether WebGL2 is being used
|
|
11
|
+
* @returns {string} - Vertex shader source code
|
|
12
|
+
*/
|
|
13
|
+
getVertexShader(isWebGL2) {
|
|
14
|
+
return `${isWebGL2 ? "#version 300 es\n" : ""}
|
|
15
|
+
precision mediump float;
|
|
16
|
+
|
|
17
|
+
${isWebGL2 ? "in" : "attribute"} vec3 aPosition;
|
|
18
|
+
${isWebGL2 ? "in" : "attribute"} vec2 aTexCoord;
|
|
19
|
+
|
|
20
|
+
uniform mat4 uProjectionMatrix;
|
|
21
|
+
uniform mat4 uViewMatrix;
|
|
22
|
+
uniform vec3 uSpritePosition; // World position of the sprite
|
|
23
|
+
uniform vec2 uSpriteSize; // Width and height of the sprite
|
|
24
|
+
uniform vec3 uCameraPosition;
|
|
25
|
+
uniform vec3 uCameraRight;
|
|
26
|
+
uniform vec3 uCameraUp;
|
|
27
|
+
uniform bool uIsBillboard; // Whether to use billboard mode
|
|
28
|
+
uniform vec3 uSpriteForward; // Sprite forward direction (for non-billboard)
|
|
29
|
+
uniform vec3 uSpriteUp; // Sprite up direction (for non-billboard)
|
|
30
|
+
|
|
31
|
+
${isWebGL2 ? "out" : "varying"} vec2 vTexCoord;
|
|
32
|
+
|
|
33
|
+
void main() {
|
|
34
|
+
vec3 worldPos;
|
|
35
|
+
|
|
36
|
+
if (uIsBillboard) {
|
|
37
|
+
// Calculate billboard position in world space
|
|
38
|
+
// aPosition.xy contains the quad vertices (-0.5 to 0.5)
|
|
39
|
+
worldPos = uSpritePosition
|
|
40
|
+
+ uCameraRight * aPosition.x * uSpriteSize.x
|
|
41
|
+
+ uCameraUp * aPosition.y * uSpriteSize.y;
|
|
42
|
+
} else {
|
|
43
|
+
// Non-billboard mode: Use sprite's own orientation
|
|
44
|
+
// Create a basis using sprite's forward and up vectors
|
|
45
|
+
vec3 forward = normalize(uSpriteForward);
|
|
46
|
+
vec3 up = normalize(uSpriteUp);
|
|
47
|
+
|
|
48
|
+
// Calculate right vector (perpendicular to forward and up)
|
|
49
|
+
vec3 right = normalize(cross(forward, up));
|
|
50
|
+
|
|
51
|
+
// Recalculate up to ensure orthogonality (in case forward/up weren't perfectly perpendicular)
|
|
52
|
+
vec3 correctedUp = normalize(cross(right, forward));
|
|
53
|
+
|
|
54
|
+
// Calculate world position using sprite's local coordinate system
|
|
55
|
+
worldPos = uSpritePosition
|
|
56
|
+
+ right * aPosition.x * uSpriteSize.x
|
|
57
|
+
+ correctedUp * aPosition.y * uSpriteSize.y;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Transform to screen space
|
|
61
|
+
vec4 viewPos = uViewMatrix * vec4(worldPos, 1.0);
|
|
62
|
+
gl_Position = uProjectionMatrix * viewPos;
|
|
63
|
+
|
|
64
|
+
// Pass through texture coordinates
|
|
65
|
+
vTexCoord = aTexCoord;
|
|
66
|
+
}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get billboard fragment shader
|
|
71
|
+
* @param {boolean} isWebGL2 - Whether WebGL2 is being used
|
|
72
|
+
* @returns {string} - Fragment shader source code
|
|
73
|
+
*/
|
|
74
|
+
getFragmentShader(isWebGL2) {
|
|
75
|
+
return `${isWebGL2 ? "#version 300 es\n" : ""}
|
|
76
|
+
precision mediump float;
|
|
77
|
+
|
|
78
|
+
${isWebGL2 ? "in" : "varying"} vec2 vTexCoord;
|
|
79
|
+
|
|
80
|
+
uniform sampler2D uTexture;
|
|
81
|
+
uniform vec3 uColor; // Color tint
|
|
82
|
+
uniform float uAlpha; // Alpha value
|
|
83
|
+
|
|
84
|
+
${isWebGL2 ? "out vec4 fragColor;" : ""}
|
|
85
|
+
|
|
86
|
+
void main() {
|
|
87
|
+
vec4 texColor = texture${isWebGL2 ? "" : "2D"}(uTexture, vTexCoord);
|
|
88
|
+
|
|
89
|
+
// Apply color tint and alpha
|
|
90
|
+
vec4 finalColor = vec4(texColor.rgb * uColor, texColor.a * uAlpha);
|
|
91
|
+
|
|
92
|
+
// Discard transparent pixels
|
|
93
|
+
if (finalColor.a < 0.01) {
|
|
94
|
+
discard;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
${isWebGL2 ? "fragColor = finalColor;" : "gl_FragColor = finalColor;"}
|
|
98
|
+
}`;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
class WaterShader {
|
|
2
|
+
getWaterVertexShader(isWebGL2) {
|
|
3
|
+
return `${isWebGL2 ? "#version 300 es\n" : ""}
|
|
4
|
+
${isWebGL2 ? "in" : "attribute"} vec3 aPosition;
|
|
5
|
+
${isWebGL2 ? "in" : "attribute"} vec3 aNormal;
|
|
6
|
+
${isWebGL2 ? "in" : "attribute"} vec2 aTexCoord;
|
|
7
|
+
|
|
8
|
+
uniform mat4 uProjectionMatrix;
|
|
9
|
+
uniform mat4 uViewMatrix;
|
|
10
|
+
uniform mat4 uModelMatrix;
|
|
11
|
+
uniform float uTime;
|
|
12
|
+
|
|
13
|
+
${isWebGL2 ? "out" : "varying"} vec3 vPosition;
|
|
14
|
+
${isWebGL2 ? "out" : "varying"} vec3 vNormal;
|
|
15
|
+
${isWebGL2 ? "out" : "varying"} vec2 vTexCoord;
|
|
16
|
+
|
|
17
|
+
void main() {
|
|
18
|
+
vec3 pos = aPosition;
|
|
19
|
+
|
|
20
|
+
float wave = sin(pos.x * 2.0 + uTime) * 2.0 +
|
|
21
|
+
sin(pos.z * 1.5 + uTime * 0.8) * 1.8;
|
|
22
|
+
pos.y += wave;
|
|
23
|
+
|
|
24
|
+
vec3 normal = aNormal;
|
|
25
|
+
normal.xz += cos(pos.xz * 2.0 + uTime) * 0.2;
|
|
26
|
+
normal = normalize(normal);
|
|
27
|
+
|
|
28
|
+
vPosition = (uModelMatrix * vec4(pos, 1.0)).xyz;
|
|
29
|
+
vNormal = normal;
|
|
30
|
+
vTexCoord = aTexCoord;
|
|
31
|
+
|
|
32
|
+
gl_Position = uProjectionMatrix * uViewMatrix * vec4(vPosition, 1.0);
|
|
33
|
+
}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getWaterFragmentShader(isWebGL2) {
|
|
37
|
+
return `${isWebGL2 ? "#version 300 es\n" : ""}
|
|
38
|
+
precision highp float;
|
|
39
|
+
|
|
40
|
+
${isWebGL2 ? "in" : "varying"} vec3 vPosition;
|
|
41
|
+
${isWebGL2 ? "in" : "varying"} vec3 vNormal;
|
|
42
|
+
${isWebGL2 ? "in" : "varying"} vec2 vTexCoord;
|
|
43
|
+
|
|
44
|
+
uniform vec3 uCameraPos;
|
|
45
|
+
uniform vec3 uLightDir;
|
|
46
|
+
uniform float uTime;
|
|
47
|
+
|
|
48
|
+
${isWebGL2 ? "out vec4 fragColor;\n" : ""}
|
|
49
|
+
|
|
50
|
+
void main() {
|
|
51
|
+
vec3 viewDir = normalize(uCameraPos - vPosition);
|
|
52
|
+
|
|
53
|
+
vec3 waterColor = vec3(0.0, 0.4, 0.6);
|
|
54
|
+
|
|
55
|
+
float fresnel = pow(1.0 - max(dot(viewDir, vNormal), 0.0), 3.0);
|
|
56
|
+
|
|
57
|
+
vec3 reflectDir = reflect(-uLightDir, vNormal);
|
|
58
|
+
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);
|
|
59
|
+
|
|
60
|
+
vec3 finalColor = waterColor + fresnel * 0.5 + spec;
|
|
61
|
+
|
|
62
|
+
float alpha = mix(0.6, 0.9, fresnel);
|
|
63
|
+
|
|
64
|
+
${isWebGL2 ? "fragColor" : "gl_FragColor"} = vec4(finalColor, alpha);
|
|
65
|
+
}`;
|
|
66
|
+
}
|
|
67
|
+
}
|