diff --git a/cocos/core/builtin/effects.ts b/cocos/core/builtin/effects.ts index f3474dec015..55f58b3f182 100644 --- a/cocos/core/builtin/effects.ts +++ b/cocos/core/builtin/effects.ts @@ -140,7 +140,7 @@ export const effects = [ "shaders": [ { "name": "particle-gpu|particle-vs-gpu:gpvs_main|tinted-fs:add", - "hash": 1813246314, + "hash": 1250077034, "builtins": { "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 63, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, @@ -148,6 +148,7 @@ export const effects = [ }, "defines": [ { "name": "CC_RENDER_MODE", "type": "number", "range": [0, 4] }, + { "name": "USE_VK_SHADER", "type": "boolean" }, { "name": "COLOR_OVER_TIME_MODULE_ENABLE", "type": "boolean" }, { "name": "ROTATION_OVER_TIME_MODULE_ENABLE", "type": "boolean" }, { "name": "SIZE_OVER_TIME_MODULE_ENABLE", "type": "boolean" }, diff --git a/cocos/core/builtin/shader-sources/glsl1.ts b/cocos/core/builtin/shader-sources/glsl1.ts index ea0e9fc9a06..0293370e408 100644 --- a/cocos/core/builtin/shader-sources/glsl1.ts +++ b/cocos/core/builtin/shader-sources/glsl1.ts @@ -26,7 +26,7 @@ export const glsl1 = [ ], [ { - "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nuniform vec4 mainTiling_Offset;\nuniform vec4 frameTile_velLenScale;\nuniform vec4 scale;\nuniform vec4 nodeRotation;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matViewInv;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\nuniform highp mat4 cc_matWorld;\nvarying mediump vec2 uv;\nvarying mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nuniform vec4 u_sampleInfo;\nuniform vec4 u_worldRot;\nuniform vec4 u_timeDelta;\nattribute vec4 a_position_starttime;\nattribute vec4 a_size_uv;\nattribute vec4 a_rotation_uv;\nattribute vec4 a_color;\nattribute vec4 a_dir_life;\nattribute float a_rndSeed;\n#if CC_RENDER_MODE == 4\nattribute vec3 a_texCoord;\nattribute vec3 a_texCoord3;\nattribute vec3 a_normal;\nattribute vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture2D(tex, coord);\nvec4 b = texture2D(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture2D(tex, coord);\nvec4 b = texture2D(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nuniform sampler2D color_over_time_tex0;\nuniform int u_color_mode;\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nuniform sampler2D rotation_over_time_tex0;\nuniform int u_rotation_mode;\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D size_over_time_tex0;\nuniform int u_size_mode;\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D force_over_time_tex0;\nuniform int u_force_mode;\nuniform int u_force_space;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nuniform sampler2D velocity_over_time_tex0;\nuniform int u_velocity_mode;\nuniform int u_velocity_space;\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nuniform sampler2D texture_animation_tex0;\nuniform vec4 u_anim_info;\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture2D(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture2D(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture2D(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", + "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nuniform vec4 mainTiling_Offset;\nuniform vec4 frameTile_velLenScale;\nuniform vec4 scale;\nuniform vec4 nodeRotation;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matViewInv;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\nuniform highp mat4 cc_matWorld;\nvarying mediump vec2 uv;\nvarying mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nuniform vec4 u_sampleInfo;\nuniform vec4 u_worldRot;\nuniform vec4 u_timeDelta;\nattribute vec4 a_position_starttime;\nattribute vec4 a_size_uv;\nattribute vec4 a_rotation_uv;\nattribute vec4 a_color;\nattribute vec4 a_dir_life;\nattribute float a_rndSeed;\n#if CC_RENDER_MODE == 4\nattribute vec3 a_texCoord;\nattribute vec3 a_texCoord3;\nattribute vec3 a_normal;\nattribute vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture2D(tex, coord);\nvec4 b = texture2D(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture2D(tex, coord);\nvec4 b = texture2D(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\n#if USE_VK_SHADER\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n#else\nfloat seed = mod(x, 233280.);\nfloat q = (seed * 9301. + 49297.) / 233280.;\nreturn fract(q);\n#endif\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nuniform sampler2D color_over_time_tex0;\nuniform int u_color_mode;\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nuniform sampler2D rotation_over_time_tex0;\nuniform int u_rotation_mode;\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D size_over_time_tex0;\nuniform int u_size_mode;\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D force_over_time_tex0;\nuniform int u_force_mode;\nuniform int u_force_space;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nuniform sampler2D velocity_over_time_tex0;\nuniform int u_velocity_mode;\nuniform int u_velocity_space;\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nuniform sampler2D texture_animation_tex0;\nuniform vec4 u_anim_info;\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture2D(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture2D(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture2D(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", "frag": "\nprecision mediump float;\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nvarying vec2 uv;\nvarying vec4 color;\nuniform sampler2D mainTexture;\nuniform vec4 tintColor;\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture2D(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nvoid main() { gl_FragColor = add(); }", } ], diff --git a/cocos/core/builtin/shader-sources/glsl3.ts b/cocos/core/builtin/shader-sources/glsl3.ts index 3304e790b78..e7a0c0aeec5 100644 --- a/cocos/core/builtin/shader-sources/glsl3.ts +++ b/cocos/core/builtin/shader-sources/glsl3.ts @@ -26,7 +26,7 @@ export const glsl3 = [ ], [ { - "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nlayout(std140) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\n};\nout mediump vec2 uv;\nout mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nlayout(std140) uniform SampleConstants {\nvec4 u_sampleInfo;\n};\nlayout(std140) uniform TickConstants {\nvec4 u_worldRot;\nvec4 u_timeDelta;\n};\nin vec4 a_position_starttime;\nin vec4 a_size_uv;\nin vec4 a_rotation_uv;\nin vec4 a_color;\nin vec4 a_dir_life;\nin float a_rndSeed;\n#if CC_RENDER_MODE == 4\nin vec3 a_texCoord;\nin vec3 a_texCoord3;\nin vec3 a_normal;\nin vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nuniform sampler2D color_over_time_tex0;\nlayout(std140) uniform ColorConstant {\nint u_color_mode;\n};\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nuniform sampler2D rotation_over_time_tex0;\nlayout(std140) uniform RotationConstant {\nint u_rotation_mode;\n};\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D size_over_time_tex0;\nlayout(std140) uniform SizeConstant {\nint u_size_mode;\n};\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D force_over_time_tex0;\nlayout(std140) uniform ForceConstant {\nint u_force_mode;\nint u_force_space;\n};\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nuniform sampler2D velocity_over_time_tex0;\nlayout(std140) uniform VelocityConstant {\nint u_velocity_mode;\nint u_velocity_space;\n};\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nuniform sampler2D texture_animation_tex0;\nlayout(std140) uniform AnimationConstant {\nvec4 u_anim_info;\n};\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", + "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nlayout(std140) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\n};\nout mediump vec2 uv;\nout mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nlayout(std140) uniform SampleConstants {\nvec4 u_sampleInfo;\n};\nlayout(std140) uniform TickConstants {\nvec4 u_worldRot;\nvec4 u_timeDelta;\n};\nin vec4 a_position_starttime;\nin vec4 a_size_uv;\nin vec4 a_rotation_uv;\nin vec4 a_color;\nin vec4 a_dir_life;\nin float a_rndSeed;\n#if CC_RENDER_MODE == 4\nin vec3 a_texCoord;\nin vec3 a_texCoord3;\nin vec3 a_normal;\nin vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\n#if USE_VK_SHADER\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n#else\nfloat seed = mod(x, 233280.);\nfloat q = (seed * 9301. + 49297.) / 233280.;\nreturn fract(q);\n#endif\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nuniform sampler2D color_over_time_tex0;\nlayout(std140) uniform ColorConstant {\nint u_color_mode;\n};\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nuniform sampler2D rotation_over_time_tex0;\nlayout(std140) uniform RotationConstant {\nint u_rotation_mode;\n};\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D size_over_time_tex0;\nlayout(std140) uniform SizeConstant {\nint u_size_mode;\n};\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D force_over_time_tex0;\nlayout(std140) uniform ForceConstant {\nint u_force_mode;\nint u_force_space;\n};\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nuniform sampler2D velocity_over_time_tex0;\nlayout(std140) uniform VelocityConstant {\nint u_velocity_mode;\nint u_velocity_space;\n};\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nuniform sampler2D texture_animation_tex0;\nlayout(std140) uniform AnimationConstant {\nvec4 u_anim_info;\n};\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", "frag": "\nprecision mediump float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nin vec2 uv;\nin vec4 color;\nuniform sampler2D mainTexture;\nlayout(std140) uniform FragConstants {\nvec4 tintColor;\n};\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = add(); }", } ], diff --git a/cocos/core/builtin/shader-sources/glsl4.ts b/cocos/core/builtin/shader-sources/glsl4.ts index 0932b9ee810..c6394ec7555 100644 --- a/cocos/core/builtin/shader-sources/glsl4.ts +++ b/cocos/core/builtin/shader-sources/glsl4.ts @@ -26,7 +26,7 @@ export const glsl4 = [ ], [ { - "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\n};\nlayout(location = 0) out mediump vec2 uv;\nlayout(location = 1) out mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nlayout(set = 1, binding = 1) uniform SampleConstants {\nvec4 u_sampleInfo;\n};\nlayout(set = 1, binding = 2) uniform TickConstants {\nvec4 u_worldRot;\nvec4 u_timeDelta;\n};\nlayout(location = 0) in vec4 a_position_starttime;\nlayout(location = 1) in vec4 a_size_uv;\nlayout(location = 2) in vec4 a_rotation_uv;\nlayout(location = 3) in vec4 a_color;\nlayout(location = 4) in vec4 a_dir_life;\nlayout(location = 5) in float a_rndSeed;\n#if CC_RENDER_MODE == 4\nlayout(location = 6) in vec3 a_texCoord;\nlayout(location = 7) in vec3 a_texCoord3;\nlayout(location = 8) in vec3 a_normal;\nlayout(location = 9) in vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 10) uniform sampler2D color_over_time_tex0;\nlayout(set = 1, binding = 3) uniform ColorConstant {\nint u_color_mode;\n};\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 11) uniform sampler2D rotation_over_time_tex0;\nlayout(set = 1, binding = 4) uniform RotationConstant {\nint u_rotation_mode;\n};\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 12) uniform sampler2D size_over_time_tex0;\nlayout(set = 1, binding = 5) uniform SizeConstant {\nint u_size_mode;\n};\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 13) uniform sampler2D force_over_time_tex0;\nlayout(set = 1, binding = 6) uniform ForceConstant {\nint u_force_mode;\nint u_force_space;\n};\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 14) uniform sampler2D velocity_over_time_tex0;\nlayout(set = 1, binding = 7) uniform VelocityConstant {\nint u_velocity_mode;\nint u_velocity_space;\n};\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nlayout(set = 1, binding = 15) uniform sampler2D texture_animation_tex0;\nlayout(set = 1, binding = 8) uniform AnimationConstant {\nvec4 u_anim_info;\n};\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", + "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\n};\nlayout(location = 0) out mediump vec2 uv;\nlayout(location = 1) out mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nlayout(set = 1, binding = 1) uniform SampleConstants {\nvec4 u_sampleInfo;\n};\nlayout(set = 1, binding = 2) uniform TickConstants {\nvec4 u_worldRot;\nvec4 u_timeDelta;\n};\nlayout(location = 0) in vec4 a_position_starttime;\nlayout(location = 1) in vec4 a_size_uv;\nlayout(location = 2) in vec4 a_rotation_uv;\nlayout(location = 3) in vec4 a_color;\nlayout(location = 4) in vec4 a_dir_life;\nlayout(location = 5) in float a_rndSeed;\n#if CC_RENDER_MODE == 4\nlayout(location = 6) in vec3 a_texCoord;\nlayout(location = 7) in vec3 a_texCoord3;\nlayout(location = 8) in vec3 a_normal;\nlayout(location = 9) in vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\n#if USE_VK_SHADER\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n#else\nfloat seed = mod(x, 233280.);\nfloat q = (seed * 9301. + 49297.) / 233280.;\nreturn fract(q);\n#endif\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 10) uniform sampler2D color_over_time_tex0;\nlayout(set = 1, binding = 3) uniform ColorConstant {\nint u_color_mode;\n};\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 11) uniform sampler2D rotation_over_time_tex0;\nlayout(set = 1, binding = 4) uniform RotationConstant {\nint u_rotation_mode;\n};\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 12) uniform sampler2D size_over_time_tex0;\nlayout(set = 1, binding = 5) uniform SizeConstant {\nint u_size_mode;\n};\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 13) uniform sampler2D force_over_time_tex0;\nlayout(set = 1, binding = 6) uniform ForceConstant {\nint u_force_mode;\nint u_force_space;\n};\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 14) uniform sampler2D velocity_over_time_tex0;\nlayout(set = 1, binding = 7) uniform VelocityConstant {\nint u_velocity_mode;\nint u_velocity_space;\n};\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nlayout(set = 1, binding = 15) uniform sampler2D texture_animation_tex0;\nlayout(set = 1, binding = 8) uniform AnimationConstant {\nvec4 u_anim_info;\n};\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", "frag": "\nprecision mediump float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nlayout(location = 0) in vec2 uv;\nlayout(location = 1) in vec4 color;\nlayout(set = 1, binding = 16) uniform sampler2D mainTexture;\nlayout(set = 1, binding = 9) uniform FragConstants {\nvec4 tintColor;\n};\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = add(); }", } ], diff --git a/cocos/particle/renderer/particle-system-renderer-gpu.ts b/cocos/particle/renderer/particle-system-renderer-gpu.ts index b3926c1388d..94ac2c46af5 100644 --- a/cocos/particle/renderer/particle-system-renderer-gpu.ts +++ b/cocos/particle/renderer/particle-system-renderer-gpu.ts @@ -28,7 +28,7 @@ import { builtinResMgr } from '../../core/builtin'; import { Material } from '../../core/assets'; import { Texture2D } from '../../core'; import { Component } from '../../core/components'; -import { AttributeName, Format, Attribute } from '../../core/gfx'; +import { AttributeName, Format, Attribute, API } from '../../core/gfx'; import { Mat4, Vec2, Vec4, Quat, Vec3 } from '../../core/math'; import { MaterialInstance, IMaterialInstanceInfo } from '../../core/renderer/core/material-instance'; import { MacroRecord } from '../../core/renderer/core/pass-utils'; @@ -39,6 +39,7 @@ import { Pass } from '../../core/renderer/core/pass'; import { packCurveRangeXYZ, packCurveRangeZ, packCurveRangeXYZW, packCurveRangeN, packCurveRangeXY } from '../animator/curve-range'; import { ParticleSystemRendererBase } from './particle-system-renderer-base'; import { Camera } from '../../core/renderer/scene/camera'; +import { legacyCC } from '../../core/global-exports'; const _tempWorldTrans = new Mat4(); const _tempVec4 = new Vec4(); @@ -64,6 +65,7 @@ const SIZE_OVER_TIME_MODULE_ENABLE = 'SIZE_OVER_TIME_MODULE_ENABLE'; const VELOCITY_OVER_TIME_MODULE_ENABLE = 'VELOCITY_OVER_TIME_MODULE_ENABLE'; const FORCE_OVER_TIME_MODULE_ENABLE = 'FORCE_OVER_TIME_MODULE_ENABLE'; const TEXTURE_ANIMATION_MODULE_ENABLE = 'TEXTURE_ANIMATION_MODULE_ENABLE'; +const USE_VK_SHADER = 'USE_VK_SHADER'; const _vert_attr_name = { POSITION_STARTTIME: 'a_position_starttime', @@ -436,6 +438,8 @@ export default class ParticleSystemRendererGPU extends ParticleSystemRendererBas _tempVec4.z = textureModule.cycleCount; pass.setUniform(infoHandle, _tempVec4); } + + this._defines[USE_VK_SHADER] = legacyCC.game._gfxDevice.gfxAPI === API.VULKAN; } public getParticleCount (): number { diff --git a/editor/assets/chunks/particle-vs-gpu.chunk b/editor/assets/chunks/particle-vs-gpu.chunk index 606b7ad0c27..6e3394b3c5e 100644 --- a/editor/assets/chunks/particle-vs-gpu.chunk +++ b/editor/assets/chunks/particle-vs-gpu.chunk @@ -78,6 +78,7 @@ vec4 scaleAndAdd (vec4 a, vec4 b, float scale) { // Vulkan compatible issue#9858, do not use large number (more than 100) in mod function float pseudoRandom(float x) { +#if USE_VK_SHADER float o = x; x = mod(x - 1.0, 2.0) - 1.0; float freqVar = 10.16640753482; //3.1415927*(sqrt(5.0)+1.0); @@ -86,6 +87,11 @@ float pseudoRandom(float x) { v *= 0.7071067812; // fix sheared 'distance' measurements - but this is 1D so unsure it's even a good thing to try v = y < 0.0 ? -v : v; return v; +#else + float seed = mod(x, 233280.); + float q = (seed * 9301. + 49297.) / 233280.; + return fract(q); +#endif } #if COLOR_OVER_TIME_MODULE_ENABLE